GNU Make¶
Resources¶
Colored Help¶
Sample Makefile
See origin My Ultimate Makefile for Golang Projects
GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)
all: help
## Build:
build: ## Build your project and put the output binary in out/bin/
@echo "build target"
clean: ## Remove build related file
@echo clean target
vendor: ## Copy of all packages needed to support builds and tests in the vendor directory
@echo vendor target
watch: ## Run the code with cosmtrek/air to have automatic reload on changes
@echo watch target
## Test:
test: ## Run the tests of the project
@echo test target
coverage: ## Run the tests of the project and export the coverage
@echo coverage target
## Docker:
docker-build: ## Use the dockerfile to build the container
@echo docker-build target
docker-release: ## Release the container with tag latest and version
@echo docker-release target
## Help:
help: ## Show this help.
@echo ''
@echo 'Usage:'
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
Functions¶
VERSION := snapshot
NAME := myapp_name
# sample make function: $(call fn_build,1:arg,2:arg,3:arg)
define fn_build
@echo arg 1: $(1)
@echo arg 2: $(2)
@echo arg 3: $(3)
endef
.PHONY: build-service
build-service:
$(call fn_build,$@,$(NAME),$(VERSION))
output
➜ make build-service VERSION=1.0.3
arg 1: build-service
arg 2: myapp_name
arg 3: 1.0.3
Automatic Variables¶
Variable | Details |
---|---|
$@ | is the file name of the target of the rule |
$< | is the name of the first prerequisite |
$? | is the name of all the prerequisites that are newer than the target, with spaces between them. If the target does not exist, all prerequisites will be included |
$^ | is the name of all the prerequisites, with spaces between them |
Sample Makefile
main: one two
@echo '$$@:' $@
@echo '$$<:' $<
@echo '$$?:' $?
@echo '$$^:' $^
@touch main
one:
@touch one
two:
@touch two
clean:
@rm -f main one two
Output
➜ make main
$@: main
$<: one
$?: one two
$^: one two
# update file "one"
➜ touch one
# output for '$?' has been changed
➜ make main
$@: main
$<: one
$?: one
$^: one two
Loops and Lists¶
List variable in Makefile can be single-line or multi-line (can contain comments).
LIST_MULTILINE += AAA # Comment 1
LIST_MULTILINE += BBB # Comment 2
LIST_MULTILINE += CCC # Comment 3
LIST_MULTILINE += DDD # Comment 4
# single-line
LIST = Xxx Yyy Zzz
.PHONY: print-list
print-list:
@for i in $(LIST_MULTILINE); do \
echo elem: $$i; \
done
@echo '-------------'
@for i in $(LIST); do \
echo elem: $$i; \
done
output
➜ make print-list
elem: AAA
elem: BBB
elem: CCC
elem: DDD
-------------
elem: Xxx
elem: Yyy
elem: Zzz