1PROJECT := cpu_features 2BRANCH := $(shell git rev-parse --abbrev-ref HEAD) 3SHA1 := $(shell git rev-parse --verify HEAD) 4 5# General commands 6.PHONY: help 7BOLD=\e[1m 8RESET=\e[0m 9 10help: 11 @echo -e "${BOLD}SYNOPSIS${RESET}" 12 @echo -e "\tmake <target> [NOCACHE=1]" 13 @echo 14 @echo -e "${BOLD}DESCRIPTION${RESET}" 15 @echo -e "\ttest build inside docker container to have a reproductible build." 16 @echo 17 @echo -e "${BOLD}MAKE TARGETS${RESET}" 18 @echo -e "\t${BOLD}help${RESET}: display this help and exit." 19 @echo 20 @echo -e "\t${BOLD}<platform>_<stage>${RESET}: build <stage> docker image using an Ubuntu:latest x86_64 base image." 21 @echo -e "\t${BOLD}save_<platform>_<stage>${RESET}: Save the <stage> docker image." 22 @echo -e "\t${BOLD}sh_<platform>_<stage>${RESET}: run a container using the <stage> docker image (debug purpose)." 23 @echo -e "\t${BOLD}clean_<platform>_<stage>${RESET}: Remove cache and docker image." 24 @echo 25 @echo -e "\tWith ${BOLD}<platform>${RESET}:" 26 @echo -e "\t\t${BOLD}amd64${RESET} (linux/amd64)" 27 @echo -e "\t\t${BOLD}arm64${RESET} (linux/arm64)" 28 @echo 29 @echo -e "\tWith ${BOLD}<stage>${RESET}:" 30 @echo -e "\t\t${BOLD}env${RESET}" 31 @echo -e "\t\t${BOLD}devel${RESET}" 32 @echo -e "\t\t${BOLD}build${RESET}" 33 @echo -e "\t\t${BOLD}test${RESET}" 34 @echo -e "\te.g. 'make amd64_build'" 35 @echo 36 @echo -e "\t${BOLD}clean${RESET}: Remove cache and ALL docker images." 37 @echo 38 @echo -e "\t${BOLD}NOCACHE=1${RESET}: use 'docker build --no-cache' when building container (default use cache)." 39 @echo -e "\t${BOLD}VERBOSE=1${RESET}: use 'docker build --progress=plain' when building container." 40 @echo 41 @echo -e "branch: $(BRANCH)" 42 @echo -e "sha1: $(SHA1)" 43 44# Need to add cmd_platform to PHONY otherwise target are ignored since they do not 45# contain recipe (using FORCE do not work here) 46.PHONY: all 47all: build 48 49# Delete all implicit rules to speed up makefile 50MAKEFLAGS += --no-builtin-rules 51.SUFFIXES: 52# Remove some rules from gmake that .SUFFIXES does not remove. 53SUFFIXES = 54# Keep all intermediate files 55# ToDo: try to remove it later 56.SECONDARY: 57 58# Docker image name prefix. 59IMAGE := ${PROJECT} 60 61DOCKER_BUILDX_CMD := docker buildx build 62ifdef NOCACHE 63DOCKER_BUILDX_CMD := ${DOCKER_BUILDX_CMD} --no-cache 64endif 65ifdef VERBOSE 66DOCKER_BUILDX_CMD := ${DOCKER_BUILDX_CMD} --progress=plain 67endif 68DOCKER_RUN_CMD := docker run --rm --init --net=host 69 70############ 71## NATIVE ## 72############ 73# ref: https://go.dev/doc/install/source#environment 74# ref: https://github.com/containerd/containerd/blob/269548fa27e0089a8b8278fc4fc781d7f65a939b/platforms/platforms.go#L80-L94 75PLATFORMS := amd64 arm64 76STAGES := env devel build test 77 78define make-platform-stage-target = 79$1_$2: docker/Dockerfile 80 ${DOCKER_BUILDX_CMD} \ 81 --platform linux/$1 \ 82 --build-arg PLATFORM="$1" \ 83 --target=$2 \ 84 --tag ${IMAGE}:$1_$2 \ 85 -f $$< ../.. 86 87save_$1_$2: cache/$1/docker_$2.tar 88cache/$1/docker_$2.tar: $1_$2 89 @rm -f $$@ 90 mkdir -p cache/$1 91 docker save ${IMAGE}:$1_$2 -o $$@ 92 93sh_$1_$2: $1_$2 94 ${DOCKER_RUN_CMD} --platform linux/$1 -it --name ${IMAGE}_$1_$2 ${IMAGE}:$1_$2 95 96clean_$1_$2: 97 docker image rm -f ${IMAGE}:$1_$2 2>/dev/null 98 rm -f cache/$1/docker_$2.tar 99endef 100 101define make-platform-target = 102$(foreach stage,$(STAGES),$(eval $(call make-platform-stage-target,$1,$(stage)))) 103 104# merge 105.PHONY: clean_$1 106clean_$1: $(addprefix clean_$1_, $(STAGES)) 107 -rmdir cache/$1 108endef 109 110$(foreach platform,$(PLATFORMS),$(eval $(call make-platform-target,$(platform)))) 111 112## MERGE ## 113.PHONY: clean 114clean: $(addprefix clean_, $(PLATFORMS)) 115 docker container prune -f 116 docker image prune -f 117 -rmdir cache 118 119.PHONY: distclean 120distclean: clean 121 -docker container rm -f $$(docker container ls -aq) 122 -docker image rm -f $$(docker image ls -aq) 123