diff options
-rw-r--r-- | _notes/makefile.md | 64 | ||||
-rw-r--r-- | _posts/2020-05-20-makefile-escaping.md | 3 |
2 files changed, 67 insertions, 0 deletions
diff --git a/_notes/makefile.md b/_notes/makefile.md new file mode 100644 index 0000000..777e04d --- /dev/null +++ b/_notes/makefile.md @@ -0,0 +1,64 @@ +--- +title: GNU Make +--- +Best practices for my Makefiles (sorry for the botched highlighting). + +```make +# Put this in the top of the Makefile: + +MAKEFLAGS += --no-builtin-rules --no-builtin-variables --warn-undefined-variables +unexport MAKEFLAGS +.DEFAULT_GOAL := all +.DELETE_ON_ERROR: +.SUFFIXES: +SHELL := bash +.SHELLFLAGS := -eu -o pipefail -c + +escape = $(subst ','\'',$(1)) + +define noexpand +ifeq ($$(origin $(1)),environment) + $(1) := $$(value $(1)) +endif +ifeq ($$(origin $(1)),environment override) + $(1) := $$(value $(1)) +endif +ifeq ($$(origin $(1)),command line) + override $(1) := $$(value $(1)) +endif +endef + +# OK, now some examples of how to use it: + +.PHONY: all +all: test-escape test-noexpand + +# Always put command arguments in single quotes. +# Escape variables and shell output using the escape function. + +var_with_quote := Includes ' quote + +.PHONY: test-escape +test-escape: + printf '%s\n' '$(call escape,$(var_with_quote))' + printf '%s\n' '$(call escape,$(shell echo "Includes ' quote"))' + +# The above recipe will print "Includes ' quote" twice. + +# If you define variables using ?= or use environment variables in your +# Makefile, use noexpand on them (to safeguard against ${accidental} +# references). + +var_with_default ?= Accidental reference? +$(eval $(call noexpand,var_with_default)) + +$(eval $(call noexpand,env_var)) + +.PHONY: test-noexpand +test-noexpand: + printf '%s\n' '$(call escape,$(var_with_default))' + printf '%s\n' '$(call escape,$(env_var))' + +# The above recipe will print "Accidental ${reference}" twice if you run using +# env_var='Accidental ${reference}' make var_with_default='Accidental ${reference}' +``` diff --git a/_posts/2020-05-20-makefile-escaping.md b/_posts/2020-05-20-makefile-escaping.md index d16e3b5..bf29657 100644 --- a/_posts/2020-05-20-makefile-escaping.md +++ b/_posts/2020-05-20-makefile-escaping.md @@ -35,6 +35,9 @@ variable, but the same rules should apply for all similar `sh`-like shells. TL;DR ----- +Visit [this page]({{ site.baseurl }}{% link _notes/makefile.md %}) for an all-in-one Makefile. +{: .alert .alert-info } + * Put the prologue above at the top of your Makefile. * Quote command arguments in Makefiles using single quotes `'`. * Don't use `'` and `$` in stuff like file paths/environment variable values, |