GNU Make Build automation

Version 4.4.1 · source

Start here

make
Build the default target
make <target>
Build one target
make -n
Dry run: show recipes only
make -j<N>
Build N jobs in parallel
make -f <file>
Use another makefile
make -C <dir>
Run in another directory
make <VAR>=<value>
Override a variable
make -B
Rebuild everything

Concepts

  1. Makefile rules + variables
  2. Goal target default: first rule
  3. Prerequisites built first, recursively
  4. Recipe shell lines run
Make walks the dependency graph and runs only stale recipes

Running make

make
Build the first (default) target
make <target>
Build a specific target
make -n
Print recipes without running them
make -j<N>
Run up to N recipes in parallel
-j with no number means unlimited jobs.
make -f <file>
Read this file instead of Makefile
make -C <dir>
Change to dir before reading makefiles
make <VAR>=<value>
Set a variable from the command line
Command-line values beat assignments in the makefile unless it uses override.
make -B
Rebuild all targets unconditionally
make -k
Keep going after errors
make -s
Silent: do not echo recipes
make -q
Exit status says if target is up to date
make -t
Touch targets instead of rebuilding
make -W <file>
Pretend file just changed
make -o <file>
Pretend file is old; do not remake it
make -e
Environment overrides makefile variables
make -O
Group output of parallel jobs
make -r
Disable built-in implicit rules
make -i
Ignore errors in recipes
make -j<N> -l <load>
Limit jobs by load average

Rules

<target>: <prereqs>
Rule header; recipe lines follow, each after a Tab
<a> <b>: <prereqs>
One rule for several targets
<target>: | <dir>
Order-only prerequisite: must exist, no rebuild trigger
Typical use: create an output directory without rebuilding on its mtime.
.PHONY: <target>
Target is an action, not a file
.DEFAULT_GOAL := <target>
Choose the default target
<t1> <t2> &: <prereqs>
Grouped targets: one recipe makes all
Needs GNU Make 4.3 or newer.
<target>::
Double-colon rule: independent recipes
.DELETE_ON_ERROR:
Remove target if its recipe fails
.SECONDARY: <target>
Keep intermediate file, do not delete it
.PRECIOUS: <target>
Do not delete target when interrupted
.ONESHELL:
Run a whole recipe in one shell
.SILENT:
Do not echo recipes (all, or listed targets)
include <file>
Include another makefile; error if missing
-include <file>
Include if it exists, no error otherwise

Recipe lines

@<command>
Do not echo this line
-<command>
Ignore a failure of this line
+<command>
Run even under -n (used for sub-makes)
$(MAKE) -C <dir>
Recurse into a subdirectory
Use $(MAKE), not make, so flags and the jobserver are passed down.
$$<var>
Literal $ for the shell
Make expands $ first, so shell variables need $$.
\ (end of line)
Continue the line
export <VAR>
Pass variable to recipes' environment
unexport <VAR>
Keep variable out of the environment
define <name> ... endef
Multi-line variable or canned recipe
$(call <name>,<arg>)
Call a user-defined function
$(eval <text>)
Parse text as makefile syntax

Variables

<VAR> = <value>
Recursive: expanded each time it is used
<VAR> := <value>
Simple: expanded once, at assignment
<VAR> ?= <value>
Set only if not already set
<VAR> += <value>
Append
<VAR> != <command>
Assign the output of a shell command
override <VAR> = <value>
Beat command-line values
$(<VAR>) / ${<VAR>}
Use a variable
$(<VAR>:.c=.o)
Replace suffix in each word
<target>: <VAR> = <value>
Target-specific variable
<pattern>: <VAR> = <value>
Pattern-specific variable
$(origin <VAR>)
Where a variable came from
$(value <VAR>)
Unexpanded value of a variable

Automatic variables

$@
The target
$<
The first prerequisite
$^
All prerequisites, no duplicates
$+
All prerequisites, with duplicates
$?
Prerequisites newer than the target
$*
The stem matched by % in a pattern rule
$(@D) / $(@F)
Directory and file part of $@
$(<D) / $(<F)
Directory and file part of $<
$|
Order-only prerequisites

Patterns and built-ins

%.o: %.c
Pattern rule: any .o from the matching .c
%.o: %.c | <dir>
Pattern rule with order-only dir
.SUFFIXES:
Clear the old-style suffix list
$(CC)
C compiler (default cc)
$(CFLAGS) / $(CPPFLAGS)
Compile and preprocessor flags
$(LDFLAGS) / $(LDLIBS)
Link flags and libraries
$(CXX) / $(CXXFLAGS)
C++ compiler and flags
$(RM)
Built-in rm -f
$(MAKECMDGOALS)
Targets named on the command line
$(CURDIR)
Directory make is working in
$(MAKEFILE_LIST)
Makefiles read so far
vpath %.c <dir>
Search a directory for matching prerequisites
VPATH = <dirs>
Directories to search for all prerequisites

Functions

$(wildcard <glob>)
Files matching a glob
$(patsubst <pat>,<repl>,<text>)
Pattern replace in each word
$(subst <from>,<to>,<text>)
Plain text replace
$(shell <command>)
Output of a shell command
$(foreach <v>,<list>,<text>)
Expand text per word
$(filter <pat>,<text>)
Keep words matching
$(filter-out <pat>,<text>)
Drop words matching
$(sort <list>)
Sort and remove duplicates
$(dir <names>) / $(notdir <names>)
Directory part / file part
$(basename <names>) / $(suffix <names>)
Strip or take the extension
$(addprefix <p>,<names>) / $(addsuffix <s>,<names>)
Add prefix or suffix to each word
$(if <cond>,<then>,<else>)
Conditional expression
$(word <n>,<text>)
The n-th word (1-based)
$(strip <text>)
Trim and collapse whitespace
$(error <text>) / $(warning <text>)
Abort or warn at parse time
$(info <text>)
Print a message while parsing

Conditionals

ifeq (<a>,<b>) ... else ... endif
Text equality test
ifneq (<a>,<b>)
Text inequality test
ifdef <VAR>
True if variable has a non-empty value
ifndef <VAR>
True if variable is empty or unset

Debugging

make -d
Verbose debug output
make --debug=b
Basic debugging: why targets rebuild
make -p
Print rules and variables database
make -p -n
Database without running anything
make --trace
Show why each recipe runs
Added in GNU Make 4.0.
make --warn-undefined-variables
Warn on unset variable use
make -w
Print entering/leaving directory lines
make --shuffle
Randomise prerequisite order to find missing deps
Added in GNU Make 4.4.

Recipes

Self-documenting help target
.PHONY: helphelp:	@grep -E '^[a-z-]+:.*##' $(MAKEFILE_LIST) \	  | sed 's/:.*## /\t/'build: ## compile the project
Compile C into a build directory
SRC := $(wildcard src/*.c)OBJ := $(SRC:src/%.c=build/%.o)app: $(OBJ)	$(CC) -o $@ $^ $(LDLIBS)build/%.o: src/%.c | build	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<build:	mkdir -p $@
Auto-generated header dependencies
CPPFLAGS += -MMD -MP-include $(OBJ:.o=.d)
Run a sub-make per directory
SUBDIRS := lib app.PHONY: all $(SUBDIRS)all: $(SUBDIRS)$(SUBDIRS):	$(MAKE) -C $@