Makefile
Makefile is the declarative language for the make(1) build system. The syntax should be written to a file named Makefile.
Contents
Rules
A rule has three components: a target, 0 or more prerequisites, and 0 or more recipes.
hello: hello.cpp g++ -o hello hello.cpp
hello is a target. With this Makefile in the working directory, it can be built by calling make hello in a terminal.
hello.cpp is a prerequisite. There can be any number of prerequisites; anything after the colon on the target line is treated as one. Before hello can be built, this prerequisite must be satisfied by either...
running another rule to build hello.cpp
locating hello.cpp as a file in the working directory
Note: if a prerequisite is satisfied with a file and it is older than the target file, make(1) will short circuit as the target does not need to be re-built
The remainder is a recipe. Every tabbed, newline-delimited line following a target line is a recipe. Each recipe is run in a discrete subprocess.
Noisy Rules
When executing a rule, each recipe is printed to the terminal before the recipe is executed. This can improve debugging. This can also create an extremely noisy terminal.
To make a recipe not print before executing, prefix it with @.
To make a recipe silent, redirect the output (i.e. >/dev/null 2>&1).
If errors can be ignored, consider adding || true to the end.
Variables in Rules
To access an environment variable, prefix with two dolar signs ($$).
demo: for number in 1 2 3 4; do \ echo $$number; \ done
Each recipe is executed in a discrete subprocess. As such, changes to environment variables disappear after execution.
demo: @export DEMO="YES" echo "Do variables carry over between recipes? $${DEMO:-NO}!"
This will print Do variables carry over between recipes? NO!.
Phony Rules
make(1) can also be used to automate processes that aren't necessarily about making a file.
A common example is a clean rule.
.PHONY: clean clean: rm -f hello
The .PHONY component ensures that make(1) does not look for a clean file. If there were such a file, make(1) might short circuit; it would believe that the rule is already satisfied.
Pattern Rules
Many programs have a generic and abstract-able build process. Consider the following:
%.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
For any foo.o file, make(1) knows that it can be built with cc -c foo.c -o foo.o.
Automatic Variables
Automatic variables are critical to making use of pattern rules. These are populated for every rule.
Variable |
Contents |
$@ |
file name of the target |
$^ |
names of all the prerequisites, with spaces between them |
$< |
name of the first prerequisite |
$? |
names of all the prerequisites that are newer than the target, with spaces between them |