GNU Make Manual
Table of Contents
Makefile
The file name can be one of GNUmakefile
, makefile
and Makefile
, but Makefile
is mostly recommended.
Include
- Include other makefiles
Static file names, wildcards, variables are all supported:
include foo *.mk $(bar)
Evaluation
immediate = deferred
immediate ?= deferred
immediate := immediate
immediate ::= immediate
immediate += deferred or immediate
immediate != immediate
immediate : immediate ; deferred
deferred
- immediate
- Expanded during when
Makefile
is parsed, included, etc. - deferred
- Expanded during when other expanding rule requires it or actual invoking(target-update)
You can take advantage of .SECONDEXPANSION
special rule and $$
to defer expanding some prerequisites:
.SECONDEXPANSION:
main_OBJS := main.o try.o test.o
main: $$($$@_OBJS)
# After the first phase:
# $($@_OBJS)
# During the second phase:
# $(main_OBJS) =>
# main.o try.o test.o
Wildcard
- Wildcard expansions within the definitions of targets and prerequisites are done by
make
- For recipes, it is done by the
shell
- Variables don't just expand wildcards, they expand only when they are used in targets or prerequisites
- To explicitly expand the wildcard in a variable, Use
$(wildcard var)
Parallel Execution
-j
or--jobs
-j 3
:: run 3 recipes in parallel-l 2.5
:: limit parallelism by load average of2.5
.NOTPARALLEL
:: inhibit parallelism
To force some targets to run parallel:
--output-sync
option is not supported the default macOSmake
(GNU Make 3.81)
Recursive Use of make
$(MAKE)
is the path ofmake
executable that is invoked- Some flags for
make
is passed automatically throughMAKEFLAGS
- The options
-C
,-f
,-o
, and-W
are not put intoMAKEFLAGS
;
Rules
- target
usually the name of a file, can also be the name of an action (Phony Targets)
- Phony Targets
- Not refer a file but just the name of an action. They are not prerequisites of something, or does not require some other prerequisites
- prerequisite
the names of files that the target depends on
- recipe
must be indented with
\t
, or set.RECIPEPREFIX
to your taste
- Line break : Like many other languages, place
\
at the end of the line. Backslash/newlines are converted into a single space character. Once that is done, all whitespace around the backslash/newline is condensed into a single space
When execute the command make <target>
:
- Reads the
Makefile
in the currenty directory - Pick
<target>
's rule or the first rule if<target>
is omitted - Process the rule recursively:
- Process the rule's prerequisites
- Run its own recipe if some of its prerequisites are newer than its own target.
Multiple Rules for One Target
- All the prerequisites mentioned in all the rules are merged into one list
- There can only be one recipe to be executed for a file.
- When there are serverl recipes for a file,
make
uses the last one given and prints an error message.
Static Pattern Rules
- Each pattern normally contains the character
%
just once. $<
is the automatic variable that hold the name matched by%
$@
is the automatic variable that hold the name of the target
Implicit Rules
- Each implicit rule has a target pattern and prerequisite patterns
- There are built-in rules for common languages
when x.c, y.c and z.c all exist will execute:
cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o
- https://www.gnu.org/software/make/manual/make.html#Using-Implicit-Rules
- https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
- https://www.gnu.org/software/make/manual/make.html#Variables-Used-by-Implicit-Rules
- https://www.gnu.org/software/make/manual/make.html#Implicit-Rule-Search-Algorithm
Pattern Rules
- A pattern rule contains the character
%
(exactly one of them) in the target
# Specifies how to make a file n.o, with another file n.c as its prerequisite,
# provided that n.c exists or can be made.
%.o : %.c ; recipe…
Double Colon Rules
- Normally, one file can be the target of several rules, and in this case, the prerequisites of the rules are merged.
- When rules are specified with
::
, the rules and their prerequisites are treated separatedly.
Targets
- There are special built-in target names to adjust
make
behaviors
Phony Targets
- Prevent the name collision between files and actions
- Prevent rules from not being treated as a implicit rule.
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
foo: baz
Prerequisites
- Normal
- Just a usual thing
- Order-only
- Placed after
|
, just specify the dependency, but not triggers the target even if it's newer.
$ make a
touch c
touch b
touch a
$ make x
touch z
touch y
touch x
$ make a
make: `a' is up to date.
$ make x
make: `x' is up to date.
$ touch c
$ make a
touch b
touch a
$ touch z
$ make x
make: `x' is up to date.
$ rm c
$ make a
touch c
touch b
touch a
$ rm z
$ make x
touch z
VPATH
Recipes
Echoing
- Recipe lines are echoed by default
- When a line starts with
@
, the echoing of that line is suppressed. - The
@
is discarded before the line is passed to the shell.
Shell for Recipe
SHELL = <path-to-shell>
.SHELLFLAGS = <flags>
.ONESHELL:
to do all invokations in a shell- Unlike most variables, the variable
SHELL
is never set from the environment.
Errors in Recipes
- To ignore errors in a recipe line, write a
-
at the beginning of the line’s text
Canned Recipes
When the same sequence of commands is useful in making various targets:
Variables
- Variable names like
.UPPERCASE
may be given special meaning in future versions of make. - Variable names are case-sensitive
- It is traditional to use upper case letters in variable names
- It is recommended to use lower case letters for variable names that serve internal purposes in the makefile
- Every environment variable that
make
sees when it starts up is transformed into amake
variable with the same name and value. - Explicit assignments will override the variables from environment.
- When
make
runs a recipe, variables defined in theMakefile
are placed into the environment of each shell.
# recursively expanded variable
# -----------------------------
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo) # prints 'Huh?', by recursive expansion
# simply expanded variable
# ------------------------
# For GNU make, '::=' is equivalent to ':='
# POSIX standard only supports '::='
x := foo
y := $(x) bar # evaluated right away
x := later
all:
echo $(y) # prints 'foo bar'
echo $(x) # prints 'later'
# like setdefulat
FOO ?= bar # set a value only if it’s not already set
# Equivalent to above
ifeq ($(origin FOO), undefined)
FOO = bar
endif
- $(origin variable)
- tell the source of the variable, like
undefined
,environment
,default
, etc.
# Set the ouptut of a shell execution to the variable
hash != printf '\043'
file_list != find . -name '*.c'
# Equivalent to above
hash := $(shell printf '\043')
var := $(shell find . -name "*.c")
# Target specific variable, wil be inherited by dependent targets
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
EXTRA_CFLAGS =
prog: private EXTRA_CFLAGS = -L/usr/local/lib # not inherited
prog: a.o b.o
- https://www.gnu.org/software/make/manual/make.html#How-to-Use-Variables
- https://www.gnu.org/software/make/manual/html_node/Flavors.html#Flavors
- https://www.gnu.org/software/make/manual/make.html#Other-Special-Variables
- https://www.gnu.org/software/make/manual/make.html#Automatic-Variables-1
- https://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html
Conditionals
libs_for_gcc = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
Functions
Define custom functions
- There is no explicit function definition, but it can be mimicked using define directive along with $(call variable,param,param,…)
CLI
Conventions
Every Makefile should contain this line:
SHELL = /bin/sh