<NME> Makefile
<BEF> # Copyright 2010-2022 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

.PHONY: help all
all: build

PROJECT := ortools
#UID := $(shell id -u)
#GID := $(shell id -g)
#DOCKER_DEVEL_CMD := docker run --rm -it -v ${PWD}:/project -w /project --user ${UID}:${GID}
BOLD=\e[1m
RESET=\e[0m

help:
	@echo -e "${BOLD}SYNOPSIS${RESET}"
	@echo -e "\tmake <target> [NOCACHE=1]"
	@echo
	@echo -e "${BOLD}DESCRIPTION${RESET}"
	@echo -e "\ttest build inside docker container to have a reproductible build."
	@echo
	@echo -e "${BOLD}MAKE TARGETS${RESET}"
docker_ubuntu: cache/ubuntu/docker_devel.tar
cache/%/docker_devel.tar: cmake/docker/%/Dockerfile cmake/docker/%/setup.sh
	mkdir -p cache/$*
	@docker image rm -f ${PROJECT}_$*:devel 2>/dev/null
	docker build --no-cache -t ${PROJECT}_$*:devel -f $< cmake/docker/$*
	docker save ${PROJECT}_$*:devel -o $@

# DOCKER BASH
.PHONY: bash_alpine bash_ubuntu
bash_alpine: cache/alpine/docker_devel.tar
	${DOCKER_DEVEL_CMD} ${PROJECT}_alpine:devel /bin/sh
bash_ubuntu: cache/ubuntu/docker_devel.tar
	${DOCKER_DEVEL_CMD} ${PROJECT}_ubuntu:devel /bin/bash

# CONFIGURE
.PHONY: configure configure_alpine configure_ubuntu
	@echo -e "\t${BOLD}save_<distro>_<lang>_<stage>${RESET}: Save the <stage> docker image for a specific distro for a specific language."
	@echo -e "\t${BOLD}sh_<distro>_<lang>_<stage>${RESET}: run a container using the <stage> docker image specified (debug purpose)."
	@echo -e "\t${BOLD}clean_<distro>_<lang>_<prestage>${RESET}: Remove the <stage> docker image (and the save archive if any) for a specific distro."
	@echo
	CMakeLists.txt cmake/external/CMakeLists.txt ortools/*/CMakeLists.txt \
	cmake/*.cmake cmake/*Config.cmake.in patches
	@docker load -i $<
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"cmake -H. -Bcache/$*"
	@date > $@

	@echo -e "\t\t${BOLD}ubuntu${RESET} (rolling)"
	@echo -e "\t\t${BOLD}system_deps${RESET} (archlinux with all deps from pacman)"
	@echo
build_alpine: cache/alpine/build.log
build_ubuntu: cache/ubuntu/build.log
cache/%/build.log: cache/%/configure.log ortools examples
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"cmake --build cache/$* --target all"
	@date > $@

# TEST
.PHONY: test test_alpine test_ubuntu
test: test_ubuntu
test_alpine: cache/alpine/test.log
test_ubuntu: cache/ubuntu/test.log
cache/%/test.log: cache/%/build.log
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"cmake --build cache/$* --target test -- CTEST_OUTPUT_ON_FAILURE=1"
	@date > $@

# INSTALL
.PHONY: install install_alpine install_ubuntu
install: install_ubuntu
install_alpine: cache/alpine/install.log
install_ubuntu: cache/ubuntu/install.log
cache/%/install.log: cmake/docker/%/InstallDockerfile cache/%/build.log
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"cmake --build cache/$* --target install -- DESTDIR=install"
	@docker image rm -f ${PROJECT}_$*:install 2>/dev/null
	docker build --no-cache -t ${PROJECT}_$*:install -f $< .
	docker save ${PROJECT}_$*:install -o cache/$*/docker_install.tar
	@date > $@

# DOCKER BASH INSTALL
.PHONY: bash_install_alpine bash_install_ubuntu
bash_install_alpine: cache/alpine/install.log
	@docker load -i cache/alpine/docker_install.tar
	${DOCKER_INSTALL_CMD} ${PROJECT}_alpine:install /bin/sh
bash_install_ubuntu: cache/ubuntu/install.log
	@docker load -i cache/ubuntu/docker_install.tar
	${DOCKER_INSTALL_CMD} ${PROJECT}_ubuntu:install /bin/bash

# TEST INSTALL of ProjectConfigs.cmake
.PHONY: test_install test_install_alpine bash_isntall_ubuntu
	@echo -e "\t\t${BOLD}glop${RESET} Build libglop"
	@echo -e "\t\t${BOLD}or-tools${RESET} Build libortools"
test_install_ubuntu: cache/ubuntu/test_install.log
cache/%/test_install.log: cache/%/install.log cmake/sample
	@docker load -i cache/$*/docker_install.tar
	${DOCKER_INSTALL_CMD} ${PROJECT}_$*:install /bin/sh -c \
		"cmake -H. -B/cache; \
		cmake --build /cache; \
		cmake --build /cache --target test; \
	@echo -e "\t${BOLD}clean${RESET}: Remove cache and docker image."
	@echo -e "\t${BOLD}clean_<distro>${RESET}: Remove cache and docker image for the specified distro."
	@echo -e "\t${BOLD}clean_<vm>${RESET}: Remove virtual machine for the specified vm."
	@echo
	@echo -e "\t${BOLD}NOCACHE=1${RESET}: use 'docker build --no-cache' when building container (default use cache)."
	@echo
	@echo -e "branch: $(BRANCH)"
clean_ubuntu: clean-ubuntu
clean-%:: cache/%/docker_devel.tar
	@docker load -i $<
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"cmake --build cache/$* --target clean"
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"rm -rf cache/$*/install"
	@rm -f cache/$*/test.log
	@rm -f cache/$*/build.log
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
# Keep all intermediate files
# ToDo: try to remove it later
.SECONDARY:

# Docker image name prefix.
IMAGE := ${PROJECT}/${BUILD_SYSTEM}
distclean_alpine: distclean-alpine
distclean_ubuntu: distclean-ubuntu
distclean-%::
	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
		"rm -rf cache/$*"
	docker image rm -f ${PROJECT}_$*:devel 2>/dev/null
	docker image rm -f ${PROJECT}_$*:install 2>/dev/null
DOCKER_RUN_CMD := docker run --rm --init --net=host

# Currently supported distro
DISTROS = alpine archlinux centos debian fedora opensuse system_deps ubuntu
LANGUAGES = cpp python java dotnet

# $* stem
# $< first prerequist
# $@ target name

###############
## PRESTAGES ##
###############
PRESTAGES = base swig
define make-prestage-target =
#$$(info STAGE: $1)
#$$(info Create targets: $1 $(addsuffix _$1, $(DISTROS)).)
targets_$1 = $(addsuffix _$1, $(DISTROS))
.PHONY: $1 $$(targets_$1)
$1: $$(targets_$1)
$$(targets_$1): %_$1: docker/%/Dockerfile
	#@docker image rm -f ${IMAGE}:$$*_$1 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_$1 -f $$< ..

#$$(info Create targets: save_$1 $(addprefix save_, $(addsuffix _$1, $(DISTROS))) (debug).)
save_targets_$1 = $(addprefix save_, $(addsuffix _$1, $(DISTROS)))
.PHONY: save_$1 $$(save_targets_$1)
save_$1: $$(save_targets_$1)
$$(save_targets_$1): save_%_$1: cache/%/docker_$1.tar
cache/%/docker_$1.tar: %_$1
	@rm -f $$@
	mkdir -p cache/$$*
	docker save ${IMAGE}:$$*_$1 -o $$@

#$$(info Create targets: $(addprefix sh_, $(addsuffix _$1, $(DISTROS))) (debug).)
sh_targets_$1 = $(addprefix sh_, $(addsuffix _$1, $(DISTROS)))
.PHONY: $$(sh_targets_$1)
$$(sh_targets_$1): sh_%_$1: %_$1
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$*_$1 ${IMAGE}:$$*_$1

#$$(info Create targets: $(addprefix clean_, $(addsuffix _$1, $(DISTROS))).)
clean_targets_$1 = $(addprefix clean_, $(addsuffix _$1, $(DISTROS)))
.PHONY: clean_$1 $$(clean_targets_$1)
clean_$1: $$(clean_targets_$1)
$$(clean_targets_$1): clean_%_$1:
	docker image rm -f ${IMAGE}:$$*_$1 2>/dev/null
	rm -f cache/$$*/docker_$1.tar
endef

$(foreach stage,$(PRESTAGES),$(eval $(call make-prestage-target,$(stage))))

############
## STAGES ##
############
STAGES = env devel build test install_env install_devel install_build install_test
define make-stage-target =
#$$(info STAGE: $1)
#$$(info Create targets: $1 $(addsuffix _$1, $(DISTROS)).)
targets_$1 = $(addsuffix _$1, $(DISTROS))
.PHONY: $1 $$(targets_$1)
$1: $$(targets_$1)
$$(targets_$1): %_$1: $(addprefix %_, $(addsuffix _$1, $(LANGUAGES)))

#$$(info Create targets: $(addsuffix _$1, $(LANGUAGES)).)
targets_$1 = $(addsuffix _$1, $(LANGUAGES))
.PHONY: $$(targets_$1)
$$(targets_$1): %_$1: $(addsuffix _$1, $(addsuffix _%, $(DISTROS)))

#$$(info Create targets: $(addsuffix _cpp_$1, $(DISTROS)))
cpp_targets_$1 = $(addsuffix _cpp_$1, $(DISTROS))
#$$(info Create targets: $(addsuffix _dotnet_$1, $(DISTROS)))
dotnet_targets_$1 = $(addsuffix _dotnet_$1, $(DISTROS))
#$$(info Create targets: $(addsuffix _java_$1, $(DISTROS)))
java_targets_$1 = $(addsuffix _java_$1, $(DISTROS))
#$$(info Create targets: $(addsuffix _python_$1, $(DISTROS)))
python_targets_$1 = $(addsuffix _python_$1, $(DISTROS))
.PHONY: $$(cpp_targets_$1) $$(dotnet_targets_$1) $$(java_targets_$1) $$(python_targets_$1)

$$(cpp_targets_$1): %_cpp_$1: docker/%/cpp.Dockerfile %_base
	#@docker image rm -f ${IMAGE}:$$*_cpp_$1 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_cpp_$1 -f $$< ..
$$(dotnet_targets_$1): %_dotnet_$1: docker/%/dotnet.Dockerfile %_swig
	#@docker image rm -f ${IMAGE}:$$*_dotnet_$1 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_dotnet_$1 -f $$< ..
$$(java_targets_$1): %_java_$1: docker/%/java.Dockerfile %_swig
	#@docker image rm -f ${IMAGE}:$$*_java_$1 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_java_$1 -f $$< ..
$$(python_targets_$1): %_python_$1: docker/%/python.Dockerfile %_swig
	#@docker image rm -f ${IMAGE}:$$*_python_$1 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_python_$1 -f $$< ..

# Save $1 docker images (debug).
#$$(info Create targets: save_$1 $(addprefix save_, $(addsuffix _$1, $(DISTROS))).)
targets_$1 = $(addprefix save_, $(addsuffix _$1, $(DISTROS)))
.PHONY: save_$1 $$(targets_$1)
save_$1: $$(targets_$1)
$$(targets_$1): save_%_$1: $(addprefix save_%_, $(addsuffix _$1, $(LANGUAGES)))

#$$(info Create targets: $(addprefix save_, $(addsuffix _$1, $(LANGUAGES))).)
targets_$1 = $(addprefix save_, $(addsuffix _$1, $(LANGUAGES)))
.PHONY: $$(targets_$1)
$$(targets_$1): save_%_$1: $(addprefix save_, $(addsuffix _%_$1, $(DISTROS)))

#$$(info Create targets: $(addprefix save_, $(addsuffix _cpp_$1, $(DISTROS))))
cpp_targets_$1 = $(addprefix save_, $(addsuffix _cpp_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix save_, $(addsuffix _dotnet_$1, $(DISTROS))))
dotnet_targets_$1 = $(addprefix save_, $(addsuffix _dotnet_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix save_, $(addsuffix _java_$1, $(DISTROS))))
java_targets_$1 = $(addprefix save_, $(addsuffix _java_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix save_, $(addsuffix _python_$1, $(DISTROS))))
python_targets_$1 = $(addprefix save_, $(addsuffix _python_$1, $(DISTROS)))
.PHONY: $$(cpp_targets_$1) $$(dotnet_targets_$1) $$(java_targets_$1) $$(python_targets_$1)

$$(cpp_targets_$1): save_%_cpp_$1: cache/%/docker_cpp_$1.tar
cache/%/docker_cpp_$1.tar: %_cpp_$1
	@rm -f $$@
	mkdir -p cache/$$*
	docker save ${IMAGE}:$$*_cpp_$1 -o $$@
$$(dotnet_targets_$1): save_%_dotnet_$1: cache/%/docker_dotnet_$1.tar
cache/%/docker_dotnet_$1.tar: %_dotnet_$1
	@rm -f $$@
	mkdir -p cache/$$*
	docker save ${IMAGE}:$$*_dotnet_$1 -o $$@
$$(java_targets_$1): save_%_java_$1: cache/%/docker_java_$1.tar
cache/%/docker_java_$1.tar: %_java_$1
	@rm -f $$@
	mkdir -p cache/$$*
	docker save ${IMAGE}:$$*_java_$1 -o $$@
$$(python_targets_$1): save_%_python_$1: cache/%/docker_python_$1.tar
cache/%/docker_python_$1.tar: %_python_$1
	@rm -f $$@
	mkdir -p cache/$$*
	docker save ${IMAGE}:$$*_python_$1 -o $$@

# Run a container using the <distro>_<lang>_$1 image (debug).
#$$(info Create targets: $(addprefix sh_, $(addsuffix _cpp_$1, $(DISTROS))))
cpp_targets_$1 = $(addprefix sh_, $(addsuffix _cpp_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix sh_, $(addsuffix _dotnet_$1, $(DISTROS))))
dotnet_targets_$1 = $(addprefix sh_, $(addsuffix _dotnet_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix sh_, $(addsuffix _java_$1, $(DISTROS))))
java_targets_$1 = $(addprefix sh_, $(addsuffix _java_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix sh_, $(addsuffix _python_$1, $(DISTROS))))
python_targets_$1 = $(addprefix sh_, $(addsuffix _python_$1, $(DISTROS)))
.PHONY: $$(cpp_targets_$1) $$(dotnet_targets_$1) $$(java_targets_$1) $$(python_targets_$1)

$$(cpp_targets_$1): sh_%_cpp_$1: %_cpp_$1
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$*_cpp_$1 ${IMAGE}:$$*_cpp_$1
$$(dotnet_targets_$1): sh_%_dotnet_$1: %_dotnet_$1
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$*_dotnet_$1 ${IMAGE}:$$*_dotnet_$1
$$(java_targets_$1): sh_%_java_$1: %_java_$1
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$*_java_$1 ${IMAGE}:$$*_java_$1
$$(python_targets_$1): sh_%_python_$1: %_python_$1
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$*_python_$1 ${IMAGE}:$$*_python_$1

# Clean $1 docker images.
#$$(info Create targets: clean_$1 $(addprefix clean_, $(addsuffix _$1, $(DISTROS))).)
targets_$1 = $(addprefix clean_, $(addsuffix _$1, $(DISTROS)))
.PHONY: clean_$1 $(targets_$1)
clean_$1: $$(targets_$1)
$$(targets_$1): clean_%_$1: $(addprefix clean_%_, $(addsuffix _$1, $(LANGUAGES)))

#$$(info Create targets: $(addprefix clean_, $(addsuffix _$1, $(LANGUAGES))).)
targets_$1 = $(addprefix clean_, $(addsuffix _$1, $(LANGUAGES)))
.PHONY: $$(targets_$1)
$$(targets_$1): clean_%_$1: $(addprefix clean_, $(addsuffix _%_$1, $(DISTROS)))

#$$(info Create targets: $(addprefix clean_, $(addsuffix _cpp_$1, $(DISTROS))))
cpp_targets_$1 = $(addprefix clean_, $(addsuffix _cpp_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix clean_, $(addsuffix _dotnet_$1, $(DISTROS))))
dotnet_targets_$1 = $(addprefix clean_, $(addsuffix _dotnet_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix clean_, $(addsuffix _java_$1, $(DISTROS))))
java_targets_$1 = $(addprefix clean_, $(addsuffix _java_$1, $(DISTROS)))
#$$(info Create targets: $(addprefix clean_, $(addsuffix _python_$1, $(DISTROS))))
python_targets_$1 = $(addprefix clean_, $(addsuffix _python_$1, $(DISTROS)))
.PHONY: $$(cpp_targets_$1) $$(dotnet_targets_$1) $$(java_targets_$1) $$(python_targets_$1)

$$(cpp_targets_$1): clean_%_cpp_$1:
	docker image rm -f ${IMAGE}:$$*_cpp_$1 2>/dev/null
	rm -f cache/$$*/docker_cpp_$1.tar
$$(dotnet_targets_$1): clean_%_dotnet_$1:
	docker image rm -f ${IMAGE}:$$*_dotnet_$1 2>/dev/null
	rm -f cache/$$*/docker_dotnet_$1.tar
$$(java_targets_$1): clean_%_java_$1:
	docker image rm -f ${IMAGE}:$$*_java_$1 2>/dev/null
	rm -f cache/$$*/docker_java_$1.tar
$$(python_targets_$1): clean_%_python_$1:
	docker image rm -f ${IMAGE}:$$*_python_$1 2>/dev/null
	rm -f cache/$$*/docker_python_$1.tar
endef

$(foreach stage,$(STAGES),$(eval $(call make-stage-target,$(stage))))

#############
## VAGRANT ##
#############
VMS = freebsd

targets_freebsd = $(addprefix freebsd_, $(LANGUAGES))
.PHONY: freebsd $(targets_freebsd)
freebsd: $(targets_freebsd)
$(targets_freebsd): freebsd_%: vagrant/freebsd/%/Vagrantfile
	@cd vagrant/freebsd/$* && vagrant destroy -f
	cd vagrant/freebsd/$* && vagrant box update
	cd vagrant/freebsd/$* && vagrant up

# SSH to a freebsd_<lang> vagrant machine (debug).
targets_freebsd = $(addprefix sh_freebsd_, $(LANGUAGES))
.PHONY: $(targets_freebsd)
$(targets_freebsd): sh_freebsd_%:
	cd vagrant/freebsd/$* && vagrant up
	cd vagrant/freebsd/$* && vagrant ssh

# Clean FreeBSD vagrant machine
targets_freebsd = $(addprefix clean_freebsd_, $(LANGUAGES))
.PHONY: clean_freebsd $(targets_freebsd)
clean_freebsd: $(targets_freebsd)
$(targets_freebsd): clean_freebsd_%:
	cd vagrant/freebsd/$* && vagrant destroy -f
	-rm -rf vagrant/freebsd/$*/.vagrant

##########
## GLOP ##
##########
glop_targets = $(addprefix glop_, $(STAGES))
.PHONY: $(glop_targets)
$(glop_targets): glop_%: docker/glop/Dockerfile
	#@docker image rm -f ${IMAGE}:$@ 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$* --tag ${IMAGE}:$@ -f $< ..

save_glop_targets = $(addprefix save_glop_, $(STAGES))
.PHONY: $(save_glop_targets)
$(save_glop_targets): save_glop_%: cache/glop/docker_%.tar
cache/glop/docker_%.tar: glop_%
	@rm -f $@
	mkdir -p cache/$*
	docker save ${IMAGE}:$< -o $@

sh_glop_targets = $(addprefix sh_glop_, $(STAGES))
.PHONY: $(sh_glop_targets)
$(sh_glop_targets): sh_glop_%: glop_%
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$< ${IMAGE}:$<

clean_glop_targets = $(addprefix clean_glop_, $(STAGES))
.PHONY: $(clean_glop_targets)
$(clean_glop_targets): clean_glop_%
	docker image rm -f ${IMAGE}:glop_$* 2>/dev/null
	rm -f cache/glop/docker_$*.tar

############
## ARM 64 ##
############
TARGETS = glop or-tools
STEPS = env devel build test
define make-arm-target =
#$$(info TARGET: $1)
#$$(info Create targets: $(addprefix arm_$1_, $(STEPS)))
arm_targets = $(addprefix arm_$1_, $(STEPS))
.PHONY: $$(arm_targets)
$$(arm_targets): arm_$1_%: docker/arm/$1.Dockerfile
	#@docker image rm -f ${IMAGE}:$$@ 2>/dev/null
	${DOCKER_BUILD_CMD} --target=$$* --tag ${IMAGE}:$$@ -f $$< ..

save_arm_targets = $(addprefix save_arm_$1_, $(STEPS))
.PHONY: $$(save_arm_targets)
$$(save_arm_targets): save_arm_$1_%: cache/arm/docker_$1_%.tar
cache/arm/docker_$1_%.tar: arm_$1_%
	@rm -f $$@
	mkdir -p cache/arm
	docker save ${IMAGE}:$$< -o $$@

sh_arm_targets = $(addprefix sh_arm_$1_, $(STEPS))
.PHONY: $$(sh_arm_targets)
$$(sh_arm_targets): sh_arm_$1_%: arm_$1_%
	${DOCKER_RUN_CMD} -it --name ${PROJECT}_${BUILD_SYSTEM}_$$< ${IMAGE}:$$<

clean_arm_targets = $(addprefix clean_arm_$1_, $(STEPS))
.PHONY: $$(clean_arm_targets)
$$(clean_arm_targets): clean_arm_$1_%
	docker image rm -f ${IMAGE}:arm_$1_$$* 2>/dev/null
	rm -f cache/arm/docker_$1_$$*.tar
endef

$(foreach target,$(TARGETS),$(eval $(call make-arm-target,$(target))))

# CLEAN
targets = $(addprefix clean_, $(DISTROS))
vms = $(addprefix clean_, $(VMS))
glops = $(addprefix clean_glop_, $(STAGES))
.PHONY: clean $(targets)
clean: $(targets) $(vms) $(glops)
	docker container prune -f
	docker image prune -f
	-rmdir cache/glop
	-rmdir cache
$(targets): clean_%: $(addprefix clean_%_, $(PRESTAGES)) $(addprefix clean_%_, $(STAGES))
	-rmdir cache/$*

.PHONY: distclean
distclean: clean
	-docker container rm -f $$(docker container ls -aq)
	-docker image rm -f $$(docker image ls -aq)
	-vagrant box remove -f generic/freebsd12

<MSG> Update CMake UT using Docker

<DFF> @@ -14,7 +14,7 @@ help:
 .PHONY: help all
 all: build
 
-PROJECT := ortools
+IMAGE := ortools
 #UID := $(shell id -u)
 #GID := $(shell id -g)
 #DOCKER_DEVEL_CMD := docker run --rm -it -v ${PWD}:/project -w /project --user ${UID}:${GID}
@@ -32,16 +32,16 @@ docker_alpine: cache/alpine/docker_devel.tar
 docker_ubuntu: cache/ubuntu/docker_devel.tar
 cache/%/docker_devel.tar: cmake/docker/%/Dockerfile cmake/docker/%/setup.sh
 	mkdir -p cache/$*
-	@docker image rm -f ${PROJECT}_$*:devel 2>/dev/null
-	docker build --no-cache -t ${PROJECT}_$*:devel -f $< cmake/docker/$*
-	docker save ${PROJECT}_$*:devel -o $@
+	@docker image rm -f ${IMAGE}_$*:devel 2>/dev/null
+	docker build --no-cache -t ${IMAGE}_$*:devel -f $< cmake/docker/$*
+	docker save ${IMAGE}_$*:devel -o $@
 
 # DOCKER BASH
 .PHONY: bash_alpine bash_ubuntu
 bash_alpine: cache/alpine/docker_devel.tar
-	${DOCKER_DEVEL_CMD} ${PROJECT}_alpine:devel /bin/sh
+	${DOCKER_DEVEL_CMD} ${IMAGE}_alpine:devel /bin/sh
 bash_ubuntu: cache/ubuntu/docker_devel.tar
-	${DOCKER_DEVEL_CMD} ${PROJECT}_ubuntu:devel /bin/bash
+	${DOCKER_DEVEL_CMD} ${IMAGE}_ubuntu:devel /bin/bash
 
 # CONFIGURE
 .PHONY: configure configure_alpine configure_ubuntu
@@ -52,7 +52,7 @@ cache/%/configure.log: cache/%/docker_devel.tar \
 	CMakeLists.txt cmake/external/CMakeLists.txt ortools/*/CMakeLists.txt \
 	cmake/*.cmake cmake/*Config.cmake.in patches
 	@docker load -i $<
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"cmake -H. -Bcache/$*"
 	@date > $@
 
@@ -62,41 +62,41 @@ build: build_alpine build_ubuntu
 build_alpine: cache/alpine/build.log
 build_ubuntu: cache/ubuntu/build.log
 cache/%/build.log: cache/%/configure.log ortools examples
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"cmake --build cache/$* --target all"
 	@date > $@
 
 # TEST
 .PHONY: test test_alpine test_ubuntu
-test: test_ubuntu
+test: test_alpine test_ubuntu
 test_alpine: cache/alpine/test.log
 test_ubuntu: cache/ubuntu/test.log
 cache/%/test.log: cache/%/build.log
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"cmake --build cache/$* --target test -- CTEST_OUTPUT_ON_FAILURE=1"
 	@date > $@
 
 # INSTALL
 .PHONY: install install_alpine install_ubuntu
-install: install_ubuntu
+install: install_alpine install_ubuntu
 install_alpine: cache/alpine/install.log
 install_ubuntu: cache/ubuntu/install.log
 cache/%/install.log: cmake/docker/%/InstallDockerfile cache/%/build.log
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"cmake --build cache/$* --target install -- DESTDIR=install"
-	@docker image rm -f ${PROJECT}_$*:install 2>/dev/null
-	docker build --no-cache -t ${PROJECT}_$*:install -f $< .
-	docker save ${PROJECT}_$*:install -o cache/$*/docker_install.tar
+	@docker image rm -f ${IMAGE}_$*:install 2>/dev/null
+	docker build --no-cache -t ${IMAGE}_$*:install -f $< .
+	docker save ${IMAGE}_$*:install -o cache/$*/docker_install.tar
 	@date > $@
 
 # DOCKER BASH INSTALL
 .PHONY: bash_install_alpine bash_install_ubuntu
 bash_install_alpine: cache/alpine/install.log
 	@docker load -i cache/alpine/docker_install.tar
-	${DOCKER_INSTALL_CMD} ${PROJECT}_alpine:install /bin/sh
+	${DOCKER_INSTALL_CMD} ${IMAGE}_alpine:install /bin/sh
 bash_install_ubuntu: cache/ubuntu/install.log
 	@docker load -i cache/ubuntu/docker_install.tar
-	${DOCKER_INSTALL_CMD} ${PROJECT}_ubuntu:install /bin/bash
+	${DOCKER_INSTALL_CMD} ${IMAGE}_ubuntu:install /bin/bash
 
 # TEST INSTALL of ProjectConfigs.cmake
 .PHONY: test_install test_install_alpine bash_isntall_ubuntu
@@ -105,7 +105,7 @@ test_install_alpine: cache/alpine/test_install.log
 test_install_ubuntu: cache/ubuntu/test_install.log
 cache/%/test_install.log: cache/%/install.log cmake/sample
 	@docker load -i cache/$*/docker_install.tar
-	${DOCKER_INSTALL_CMD} ${PROJECT}_$*:install /bin/sh -c \
+	${DOCKER_INSTALL_CMD} ${IMAGE}_$*:install /bin/sh -c \
 		"cmake -H. -B/cache; \
 		cmake --build /cache; \
 		cmake --build /cache --target test; \
@@ -119,9 +119,9 @@ clean_alpine: clean-alpine
 clean_ubuntu: clean-ubuntu
 clean-%:: cache/%/docker_devel.tar
 	@docker load -i $<
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"cmake --build cache/$* --target clean"
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"rm -rf cache/$*/install"
 	@rm -f cache/$*/test.log
 	@rm -f cache/$*/build.log
@@ -137,7 +137,7 @@ distclean: distclean_alpine distclean_ubuntu
 distclean_alpine: distclean-alpine
 distclean_ubuntu: distclean-ubuntu
 distclean-%::
-	${DOCKER_DEVEL_CMD} ${PROJECT}_$*:devel /bin/sh -c \
+	${DOCKER_DEVEL_CMD} ${IMAGE}_$*:devel /bin/sh -c \
 		"rm -rf cache/$*"
-	docker image rm -f ${PROJECT}_$*:devel 2>/dev/null
-	docker image rm -f ${PROJECT}_$*:install 2>/dev/null
+	docker image rm -f ${IMAGE}_$*:devel 2>/dev/null
+	docker image rm -f ${IMAGE}_$*:install 2>/dev/null

{'addition_count': 23, 'commit_subject': 'Update CMake UT using Docker', 'deletion_count': 23, 'file_extension': '', 'lang': 'Makefile', 'license': 'apache-2.0', 'repo_name': 'google/or-tools'}