The perfect Makefile template
Recently, I stumbled upon this Makefile template, and I can’t recall where I got this from. Funny thing is that my Makefile recipes nowadays resamble a lot with this.
.SILENT:
.PHONY: help
## This help screen
help:
printf "Available targets\n\n"
awk '/^[a-zA-Z\-\_0-9]+:/ { \
helpMessage = match(lastLine, /^## (.*)/); \
if (helpMessage) { \
helpCommand = substr($$1, 0, index($$1, ":")-1); \
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
printf "%-30s %s\n", helpCommand, helpMessage; \
} \
} \
{ lastLine = $$0 }' $(MAKEFILE_LIST)
GLOBAL_VAR := "I am a global var"
GLOBAL_VAR_WITH_DEFAULT_VALUE ?= "Run 'GLOBAL_VAR_WITH_DEFAULT_VALUE=value make echo_var_with_default_value' to override this value"
.PHONY: echo_string
## A target that echoes a string literal
echo_string:
@echo "This is a single text string"
.PHONY: echo_multiline_string
## A target that echoes a multiline string
echo_multiline_string:
@echo "This is the first line\n" \
"This is the second line\n" \
"This is the third line\n"
.PHONY: install
## Install python requirments
install:
pip install -r requirements.txt
.PHONY: freeze
## Freeze python requirments
freeze:
pip freeze > requirements.txt
.PHONY: echo_global_var
## A target that echoes a global variable defined in the Makefile
echo_global_var:
@echo ${GLOBAL_VAR}
.PHONY: echo_local_var
## A target that echoes a local variable
echo_local_var:
$(eval LOCAL_VAR := 'I am a local var')
@echo ${LOCAL_VAR}
.PHONY: echo_var_with_default_value
## A target that echoes a local variable
echo_var_with_default_value:
@echo ${GLOBAL_VAR_WITH_DEFAULT_VALUE}
.PHONY: echo_shell_exec
## Echo the results of a shell execution assignment to a variable
echo_shell_exec:
@echo $(shell whoami)
.PHONY: echo_env_var
## Echo the results of a shell execution
echo_env_var:
@echo ${SHELL}
.PHONY: assign_shell_exec
## Echo the results of a shell execution assignment to a variable
assign_shell_exec:
$(eval SHELL := $(shell echo ${SHELL}))
@echo "Shell: ${SHELL}"
.PHONY: check_env_variable
## Check if ENV variable is defined
check_env_variable:
ifndef $(ENV_VAR)
@echo "'ENV_VAR' is not defined. Try running 'ENV_VAR=ENV_VAR make check_env_variable'"
else
@echo "$(ENV_VAR) is defined"
endif
@echo "Done checking ENV_VAR"
.PHONY: curl_ip
## Echo the results of a curl GET
curl_ip:
@echo $(shell curl -X GET 'https://checkip.amazonaws.com/')