Managing Projects with GNU Make
target1 target2 ... : prerequisite1 prerequisite2 ... command1 command2 ...It's important to put a TAB in front of every command.
Note that the above multi-target syntax is equivalent to:
target1: prerequisite1 prerequisite2 ... command1 command2 ... target2: prerequisite1 prerequisite2 ... command1 command2 ...
$(VAR)(If VAR is a single letter, one can remove the parentheses.)
To assign or define a variable VAR:
|VAR = right-hand-side||Recursively expand: The variable is evaluated every time VAR is referred and is evaluated only when VAR is referred.|
|VAR := right-hand-side||Simply expand: The variable is evaluated immediately on reading the line VAR := .. It is evaluated only once.|
|VAR ?= right-hand-side||Conditional: VAR is assigned only if it is undefined.
Note that this is the same as:
ifeq ($(origin VAR), undefined) VAR = right-hand-side endif
|VAR += right-hand-side||Appending|
A more flexible way of defining a variable is the define/endef directives. It has the following form:
define VAR command1 command2 ... ... endefFor example, the following two are equivalent:
define two-lines echo foo echo $(bar) endefand
two-lines = echo foo ; echo $(bar)
To pass down the value of variable VAR when invoking make recursively:
export VAR = right-hand-side
foo := a.o b.o c.o bar := $(foo:.o=.c)or better yet,
bar := $(foo:%.o=%.c)and bar's value would be a.c b.c c.c
prog: CFLAGS=-g prog: prog.o foo.o bar.owill set CFLAGS to -g when building prog and all of its prerequisites (prog.o, foo.o, and bar.o)
%.o: CFLAGS=-Owill assign CFLAGS to -O for all targets matching the pattern %.o
|$*||The root of targets (i.e. without extension)|
|$<||The first prerequisite|
|$+||Like $^, but includes duplicates.|
|$?||All prerequisites that are newer than the target.
This is useful when building archive libraries, e.g.
libfoo.a: bar.o baz.o $(AR) $(ARFLAGS) $@ $? $(RANLIB) $@Some useful suffix rules for managing archive libraries are here.
|$%||File name of the
archive member (libxxx.a) of the target, e.g.
libfoo.a(bar.o): bar.o $(AR) $(ARFLAGS) $@ $?Then $% would be the bar.o inside the parentheses, and $@ would be libfoo.a.
All of above variables have two variants by appending D or F. For example:
|$(@D)||The directory part of targets
It's defined as
$(patsubst %/,%,$(dir $@))
|$(@F)||The file name part of targets
It's defined as
|ARFLAGS||Flags passed to the archiver|
|CFLAGS||Flags passed to the C compiler|
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
$(FC) $(FFLAGS) $(TARGET_ARCH) -c
|CPP||The command to run the C preprocessor.|
|CPPFLAGS||Flags passed to the C preprocessor (which in fact will be passed to C/C++ compiler as well)|
|CURDIR||Current working directory|
|CXXFLAGS||Flags passed to the C++ compiler|
|Fortran 77 compiler|
|Flags passed to the Fortran 77 compiler|
|.INCLUDE_DIRS||List of directories that make searches for included makefiles|
|.LIBPATTERNS||Naming of the libraries make searches for, and their order. This
is used in the following situation, for example:
foo: foo.c -lbar $(CC) $^ -o $@Then make would execute
cc foo.c libbar.so -o fooif foo.c or libbar.so are newer than foo.
(By default, .LIBPATTERNS is defined as lib%.so lib%.a)
Make searchs for libbar.so first in the current working directory, then vpath, then VPATH, and finally, /lib and /usr/lib
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
|MAKECMDGOALS||The targets given to make on the command-line|
|MAKEFLAGS||Command-line options passed to invoke this make|
|MAKEFILES||Makefiles to be read on every invocation of make|
|MAKEFILE_LIST||List of makefiles parsed so far, in the order in which it is parsed|
|MAKELEVEL||The number of levels of recursion.|
|MAKE_VERSION||Version of GNU make.|
|RM||The command to delete files.|
|.VARIABLES||List of all global variables defined so far|
|VPATH||Directory search path for files not found in the current working directory|
|.PHONY||When it is time to consider such a target, make will run its commands
unconditionally, regardless of whether a file with that name exists
or what its last modification.
Common/standard phony targets are, for example:
.PHONY: all install clean clobber
|.DEFAULT_GOAL||If make is invoked without specifying a specific target, then by default
make will just achieve the first target in the makefile and stops.
This variable can override it.
|.EXPORT_ALL_VARIABLES||Export all variables when invoking make recursively|
|.INTERMEDIATE||Prerequisites of this special targets are treated as intermediate files an will be deleted when make finishes.|
|.DELETE_ON_ERROR||Always delete the targets if there is any error during make.|
|.PRECIOUS||Never delete the targets even if there is an error during make.|
|.SILENT||Do not echo the commands before executing them.
Also see the "Commands" section below.
|.IGNORE||Ignore the error if the commands fail.
Also see the "Commands" section below.
|.ONESHELL||Execute all commands in a single subshell.
This is useful if the commands use shell built-in commands such as cd, pushd, popd, etc.
VPATH = ../headers:../src
vpath %.c src/:src2/ vpath %.h include/
foo: bar/lose cd $(@D) && gobble $(@F) > ../$@
The default shell is /bin/sh. To override it, set the special variable SHELL.
Some special characters ("command modifiers"), when they appear in front of a command, can have different effects:
|@||Do not echo the command.
Also see the special target .SILENT
|+||Echo the command, but do not execute.|
|-||Ignore the error if the command fails.
Also see the special target .IGNORE
Suffix rules are the old-fashioned (and obsolete) way of defining implicit rules for make.
|Pattern rule||Suffix rule|
%.o: %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
.c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
(%.o): %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ $(AR) $(ARFLAGS) $@ $*.o $(RM) $*.o
.c.a: $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ $(AR) $(ARFLAGS) $@ $*.o $(RM) $*.o
%: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
.c: $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
%.tab.c %.tab.h: %.y bison -d $<
For example, if one has a file foo.c in the current working directory, then executing
make foowill execute the following command
cc foo.c -o fooeven if there is no makefile in the current working directory. This is because there is a pattern rule in make's default database:
%: %.c $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
if-conditional command1 command2 ... else more commands ... endifwhere if-conditional can be:
ifdef VAR ifndef VAR ifeq (arg1, arg2) ifneq (arg1, arg2)
$(function arg1,arg2,..)Note that there must NOT be any extraneous spaces around the commas, or between the last argument and ).
Arguments can be texts (space-separated words) or variables.
Return words in text which match/don't match
patterns (each of which can contain
$(filter foo% %bar,$(word))
|$(findstring hay,stack)||Return hay if it appears in stack, or nothing otherwise.|
|$(strip string)||Remove leading and trailing spaces of string.|
Replace from by to
For patsubst, the fromPat and toPat are patterns which may contain at most one % (the rest %'s would be ignored).
$(patsubst %.c,%.o,x.c.c bar.c)generates x.o.c bar.o
|$(sort list)||Sort the words of list.|
|$(words list)||Get the number of words in list.|
Return the nth word of list,
n starts from 1.
For wordlist, return words from the sth position to the eth position.
firstword and lastword return the first and last word, respectively.
|Each word in list is treated as a file name, and dir will extract the directory part of the word, while notdir will remove the directory part.|
Extract the extension of a file name. If no extension,
return an empty string.
basename extracts all but the extension of a file name.
realpath returns the canonical absolute name.
abspath is like realpath, but it does not resolve symbolic links.
|Append suffix or prepend prefix to each file name in list.|
Concatenate the two lists word by word.
$(join a b,.c .o)produces a.c b.o
|$(wildcard pattern)||Get a list of file names matching pattern, which can contain UNIX shell wildcards such as * or ?|
|$(shell command)||Execute the command in a subshell and return the results.|
For error, make will also terminate.