Automatic Variables in Make Recipes
Modern build systems are great for real-world projects, but make
is my go-to solution for small builds on Linux.
Make defines many automatic variables to be used in recipes.
They are easy to forget. So I wrote myself a makefile. It works as an interactive reminder.1
It defines a few example rules, using a custom macro. When I run with “make”, it builds 8 targets, but the build recipes do nothing but print information about the rule.
Below is the report of test_2/baz
target:
makefile:16: Building test_2/baz (from foo) (foo y.bar z.bar newer)
RULE > test_2/baz : foo y.bar z.bar << RULE
( %/baz : foo y.bar z.bar ) << PATTERN RULE
_
AUTO > @ : test_2/baz << |
AUTO > @D : test_2 << |
AUTO > @F : baz << |
AUTO > * : test_2 << |
AUTO > *D : . << |
AUTO > *F : test_2 << | AUTOMATIC
AUTO > < : foo << | VARIABLES
AUTO > <D : . << |
AUTO > <F : foo << |
AUTO > ^ : foo y.bar z.bar << |
AUTO > ^D : . . . << |
AUTO > ^F : foo y.bar z.bar << _|
\/ ________________
\ \__ VALUE
\__ VARIABLE
Here is the makefile:
# Shell replacement to print the rule being run.
OLD_SHELL ::= $(SHELL)
SHELL = $(warning Building $@$(if $<, (from $<))\
$(if $?, ($? newer)))$(OLD_SHELL)
# Print the rule, and the automatic variables.
AUTO_VARS = @ * < ^
GEN_AUTO = "\
\nAUTO > $(1) : $$($(1))\
\nAUTO > $(1)D : $$($(1)D)\
\nAUTO > $(1)F : $$($(1)F)"
GEN_RULE = $(1) : $(2) ; @echo -e "\
\nRULE > $$@ : $$^\
\n ( "\
$(1)":"$(2)")"$(foreach var,$(AUTO_VARS),\
$(call GEN_AUTO,$(var)))"\n"
.PHONY: all
all: test_1/baz test_2/baz stem_1/a.stem_2.b
$(call GEN_RULE ,foo , )
$(call GEN_RULE ,x.% , )
$(call GEN_RULE ,%.bar , foo x.% )
$(call GEN_RULE ,%/baz , foo y.bar z.bar )
$(call GEN_RULE ,a.%.b , )
The shell replacement trick at the beginning is not mine. I am not sure of its origin, but it exists in The GNU Make Book by John Graham-Cumming. Every makefile I write starts with that snippet. Very useful.
Also, I use make
with --debug
option to find out how it matches patterns.
-
If you find errors, please report in the blog’s Issues page. ↩