The criterion for being out of date is speciﬁed in terms of the prerequisites, which
consist of ﬁle names separated by spaces. (Wildcards and archive members (seeChapter11
[Archives], page 129)areallowedheretoo.) Atargetisoutofdateifitdoesnotexistorifit
is older than any of the prerequisites (by comparison of last-modiﬁcationtimes). The idea is
that the contents of the target ﬁle are computed based on information in the prerequisites,
so if any of the prerequisites changes, the contents of the existing target ﬁle are no longer
How to update is speciﬁed by a recipe. This is one or more lines to be executed by
the shell (normally ‘sh’), but with some extra features (seeChapter5[WritingRecipesin
Rules], page 41).
4.2 Types of Prerequisites
There are actually two diﬀerent types of prerequisites understood by GNU make: normal
prerequisites such as described in the previous section, and order-only prerequisites. A
normal prerequisite makes two statements: ﬁrst, it imposes an order in which recipes will
be invoked: the recipes for all prerequisites of a target will be completed before the recipe
for the target is run. Second, it imposes a dependency relationship: if any prerequisite is
newer than the target, then the target is considered out-of-date and must be rebuilt.
Normally, this is exactly what you want: if a target’s prerequisite is updated, then the
target should also be updated.
Occasionally, however, you have a situation where you want to impose a speciﬁc ordering
on the rules to be invoked without forcing the target to be updated if one of those rules is
executed. Inthat case, youwant to deﬁne order-only prerequisites. Order-only prerequisites
can be speciﬁed by placing a pipe symbol (|) in the prerequisites list: any prerequisites to
the left of the pipe symbol are normal; any prerequisites to the right are order-only:
targets : normal-prerequisites | order-only-prerequisites
The normal prerequisites section may of course be empty. Also, you may still declare
multiple lines of prerequisites for the same target: they are appended appropriately (normal
prerequisites are appended to the list of normal prerequisites; order-only prerequisites are
appended to the list of order-only prerequisites). Note that if you declare the same ﬁle to
be both a normal and an order-only prerequisite, the normal prerequisite takes precedence
(since they have a strict superset of the behavior of an order-only prerequisite).
Consider anexample where your targets are to be placed ina separate directory, and that
directory might not exist before make is run. In this situation, you want the directory to
be created before any targets are placed into it but, because the timestamps on directories
change whenever a ﬁle is added, removed, or renamed, we certainly don’t want to rebuild
all the targets whenever the directory’s timestamp changes. One way to manage this is with
order-only prerequisites: make the directory an order-only prerequisite on all the targets:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
Chapter 4: Writing Rules
$(OBJS): | $(OBJDIR)
Now the rule to create the objdir directory will be run, if needed, before any ‘.o’ is
built, but no ‘.o’ will be built because the objdir directory timestamp changed.
4.3 Using Wildcard Characters in File Names
Asingle ﬁle name can specify many ﬁles using wildcard characters. The wildcard characters
in make are ‘*’, ‘?’ and ‘[...]’, the same as in the Bourne shell. For example, *.c speciﬁes
alist of all the ﬁles (in the working directory) whose names end in ‘.c’.
The character ‘~’ at the beginning of a ﬁle name also has special signiﬁcance. If alone,
or followed by a slash, it represents your home directory. For example ~/bin expands to
/home/you/bin. If the ‘~’ is followed by a word, the string represents the home directory
of the user named by that word. For example ~john/bin expands to /home/john/bin. On
systems which don’t have a home directory for each user (suchas MS-DOS or MS-Windows),
this functionality can be simulated by setting the environment variable HOME.
Wildcard expansion is performed by make automatically in targets and in prerequisites.
In recipes, the shell is responsible for wildcard expansion. In other contexts, wildcard
expansion happens only if you request it explicitly with the wildcard function.
The special signiﬁcance of a wildcard character can be turned oﬀ by preceding it with
abackslash. Thus, foo\*bar would refer to a speciﬁc ﬁle whose name consists of ‘foo’, an
asterisk, and ‘bar’.
4.3.1 Wildcard Examples
Wildcards can be used in the recipe of a rule, where they are expanded by the shell. For
example, here is a rule to delete all the object ﬁles:
rm -f *.o
Wildcards are also useful in the prerequisites of a rule. With the following rule in the
makeﬁle, ‘make print’ will print all the ‘.c’ ﬁles that have changed since the last time you
lpr -p $?
This rule uses print as an empty target ﬁle; seeSection4.7[EmptyTargetFilestoRecord
Events], page 31. (Theautomaticvariable‘$?’isusedtoprintonlythoseﬁles s thathave
Wildcard expansion does not happen when you deﬁne a variable. Thus, if you write this:
objects = *.o
then the value of the variable objects is the actual string ‘*.o’. However, if you use the
value of objects in a target or prerequisite, wildcard expansion will take place there. If
Library SDK class:DocImage SDK for .NET: HTML Viewer, View, Annotate, Convert, Print
.NET Document Imaging SDK, view, annotate, convert, process, and print Word, Excel, PowerPoint, PDF, TIFF, DICOM, BMP, JPEG, GIF, PNG, JPEG 2000 & JBIG2 in .NET www.rasteredge.com
you use the value of objects in a recipe, the shell may perform wildcard expansion when
the recipe runs. To set objects to the expansion, instead use:
objects := $(wildcard *.o)
4.3.2 Pitfalls of Using Wildcards
Now here is an example of a naive way of using wildcard expansion, that does not do what
you would intend. Suppose you would like to say that the executable ﬁle foo is made from
all the object ﬁles in the directory, and you write this:
objects = *.o
foo : $(objects)
cc -o foo $(CFLAGS) $(objects)
The value of objects is the actual string ‘*.o’. Wildcard expansion happens in the rule
for foo, so that each existing ‘.o’ ﬁle becomes a prerequisite of foo and will be recompiled
But what if you delete all the ‘.o’ ﬁles? When a wildcard matches no ﬁles, it is left as it
is, so then foo will depend on the oddly-named ﬁle *.o. Since no such ﬁle is likely to exist,
make will give you an error saying it cannot ﬁgure out how to make *.o. This is not what
Actually it is possible to obtain the desired result with wildcard expansion, but you need
more sophisticated techniques, including the wildcard function and string substitution.
These are described in the following section.
Microsoft operating systems (MS-DOS and MS-Windows) use backslashes to separate
directories in pathnames, like so:
This is equivalent to the Unix-style c:/foo/bar/baz.c (the c: part is the so-called drive
letter). When make runs on these systems, it supports backslashes as well as the Unix-
style forward slashes in pathnames. However, this support does not include the wildcard
expansion, where backslash is a quote character. Therefore, you must use Unix-style slashes
in these cases.
4.3.3 The Function wildcard
Wildcard expansion happens automatically in rules. But wildcard expansion does not nor-
mally take place when a variable is set, or inside the arguments of a function. If you want
to do wildcard expansion in such places, you need to use the wildcard function, like this:
This string, used anywhere in a makeﬁle, is replaced by a space-separated list of names
of existing ﬁles that match one of the given ﬁle name patterns. If no existing ﬁle name
matches a pattern, then that pattern is omitted from the output of the wildcard function.
Note that this is diﬀerent from how unmatched wildcards behave in rules, where they are
used verbatim rather than ignored (seeSection4.3.2[WildcardPitfall],page24).
One use of the wildcard function is to get a list of all the C source ﬁles in a directory,
Chapter 4: Writing Rules
We can change the list of C source ﬁles into a list of object ﬁles by replacing the ‘.c’
suﬃx with ‘.o’ in the result, like this:
$(patsubst %.c,%.o,$(wildcard *.c))
(Here we have used another function, patsubst. See e Section 8.2 [Functions for String
Substitution and Analysis], page 84.)
Thus, a makeﬁle to compile all C source ﬁles in the directory andthenlink them together
could be written as follows:
objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects)
cc -o foo $(objects)
(This takes advantage of the implicit rule for compiling C programs, so there is no need to
write explicit rules for compiling the ﬁles. SeeSection6.2[TheTwoFlavorsofVariables],
4.4 Searching Directories for Prerequisites
For large systems, it is often desirable to put sources in a separate directory from the
binaries. The directory search features of make facilitate this by searching several directories
automatically to ﬁnd a prerequisite. When you redistribute the ﬁles among directories, you
do not need to change the individual rules, just the search paths.
4.4.1 VPATH: Search Path for All Prerequisites
The value of the make variable VPATH speciﬁes a list of directories that make should search.
Most often, the directories are expected to contain prerequisite ﬁles that are not in the
current directory; however, make uses VPATH as a search list for both prerequisites and
targets of rules.
Thus, if a ﬁle that is listed as a target or prerequisite does not exist in the current
directory, make searches the directories listed in VPATH for a ﬁle with that name. If a ﬁle is
found in one of them, that ﬁle may become the prerequisite (see below). Rules may then
specify the names of ﬁles in the prerequisite list as if they allexisted in the current directory.
In the VPATH variable, directory names are separated by colons or blanks. The order in
which directories are listed is the order followed by make in its search. (On MS-DOS and
MS-Windows, semi-colons are used as separators of directory names in VPATH, since the
colon can be used in the pathname itself, after the drive letter.)
VPATH = src:../headers
speciﬁes a path containing two directories, src and ../headers, which make searches in
With this value of VPATH, the following rule,
foo.o : foo.c
is interpreted as if it were written like this:
foo.o : src/foo.c
assuming the ﬁle foo.c does not exist in the current directory but is found in the directory
4.4.2 The vpath Directive
Similar to the VPATH variable, but more selective, is the vpath directive (note lower case),
which allows you to specify a search path for a particular class of ﬁle names: those that
match a particular pattern. Thus you can supply certain search directories for one class of
ﬁle names and other directories (or none) for other ﬁle names.
There are three forms of the vpath directive:
vpath pattern directories
Specify the search path directories for ﬁle names that match pattern.
The search path, directories, is a list of directories to be searched, separated
by colons (semi-colons on MS-DOS and MS-Windows) or blanks, just like the
search path used in the VPATH variable.
Clear out the search path associated with pattern.
Clear all search paths previously speciﬁed with vpath directives.
Avpath pattern is a string containing a ‘%’ character. The string must match the ﬁle
name of a prerequisite that is being searched for, the ‘%’ character matching any sequence
of zero or more characters (as in pattern rules; see Section10.5[DeﬁningandRedeﬁning
Pattern Rules], page 118). Forexample,%.hmatchesﬁlesthatendin.h. . (Ifthereis s no
‘%’, the pattern must match the prerequisite exactly, which is not useful very often.)
‘%’ characters in a vpath directive’s pattern can be quoted with preceding backslashes
(‘\’). Backslashes that would otherwise quote ‘%’ characters can be quoted with more
backslashes. Backslashes that quote ‘%’ characters or other backslashes are removed from
the pattern before it is compared to ﬁle names. Backslashes that are not in danger of
quoting ‘%’ characters go unmolested.
When a prerequisite fails to exist in the current directory, if the pattern in a vpath
directive matches the name of the prerequisite ﬁle, then the directories in that directive are
searched just like (and before) the directories in the VPATH variable.
vpath %.h ../headers
tells make to look for any prerequisite whose name ends in .h in the directory ../headers
if the ﬁle is not found in the current directory.
If several vpath patterns match the prerequisite ﬁle’s name, then make processes each
matching vpath directive one by one, searching all the directories mentioned in each di-
rective. make handles multiple vpath directives in the order in which they appear in the
makeﬁle; multiple directives with the same pattern are independent of each other.
Chapter 4: Writing Rules
vpath %.c foo
vpath %.c bar
will look for a ﬁle ending in ‘.c’ in foo, then blish, then bar, while
vpath %.c foo:bar
will look for a ﬁle ending in ‘.c’ in foo, then bar, then blish.
4.4.3 How Directory Searches are Performed
When a prerequisite is found through directory search, regardless of type (general or se-
lective), the pathname located may not be the one that make actually provides you in the
prerequisite list. Sometimes the path discovered through directory search is thrown away.
The algorithmmake uses todecide whether tokeepor abandona path foundvia directory
search is as follows:
1. If a target ﬁle does not exist at the path speciﬁed in the makeﬁle, directory search is
2. If the directory search is successful, that path is kept and this ﬁle is tentatively stored
as the target.
3. All prerequisites of this target are examined using this same method.
4. After processing the prerequisites, the target may or may not need to be rebuilt:
a. If the target does not need to be rebuilt, the path to the ﬁle found during directory
search is used for any prerequisite lists which contain this target. In short, if make
doesn’t need to rebuild the target then youuse the path found via directory search.
b. If the target does need to be rebuilt (is out-of-date), the pathname found during
directory search is thrown away, and the target is rebuilt using the ﬁle name
speciﬁed in the makeﬁle. In short, if make must rebuild, then the target is rebuilt
locally, not in the directory found via directory search.
This algorithm may seem complex, but in practice it is quite often exactly what you
Other versions of make use a simpler algorithm: if the ﬁle does not exist, and it is found
via directory search, then that pathname is always used whether or not the target needs
to be built. Thus, if the target is rebuilt it is created at the pathname discovered during
If, in fact, this is the behavior you want for some or all of your directories, you can use
the GPATH variable to indicate this to make.
GPATH has the same syntax and format as VPATH (that is, a space- or colon-delimited list
of pathnames). If an out-of-date target is found by directory search in a directory that also
appears in GPATH, then that pathname is not thrown away. The target is rebuilt using the
4.4.4 Writing Recipes with Directory Search
When a prerequisite is found in another directory through directory search, this cannot
change the recipe of the rule; they will execute as written. Therefore, you must write the
recipe with care so that it will look for the prerequisite in the directory where make ﬁnds it.
This is done with the automatic variables such as ‘$^’ (see Section10.5.3[Automatic
Variables], page 120). Forinstance,thevalueof‘$^’isalistofalltheprerequisitesofthe
rule, including the names of the directories in which they were found, and the value of ‘$@’
is the target. Thus:
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
(The variable CFLAGS exists so you can specify ﬂags for C compilation by implicit rules; we
use it here for consistency so it will aﬀect all C compilations uniformly; see e Section10.3
[Variables Used by Implicit Rules], page 115.)
Often the prerequisites include header ﬁles as well, which you do not want to mention
in the recipe. The automatic variable ‘$<’ is just the ﬁrst prerequisite:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc -c $(CFLAGS) $< -o $@
4.4.5 Directory Search and Implicit Rules
The search through the directories speciﬁed in VPATH or with vpath also happens during
consideration of implicit rules (seeChapter10[UsingImplicitRules],page111).
For example, when a ﬁle foo.o has no explicit rule, make considers implicit rules, such
as the built-in rule to compile foo.c if that ﬁle exists. If such a ﬁle is lacking in the current
directory, the appropriate directories are searched for it. If foo.c exists (or is mentioned
in the makeﬁle) in any of the directories, the implicit rule for C compilation is applied.
The recipes of implicit rules normally use automatic variables as a matter of necessity;
consequently they will use the ﬁle names found by directory search with no extra eﬀort.
4.4.6 Directory Search for Link Libraries
Directory search applies in a special way to libraries used with the linker. This special
feature comes into play when you write a prerequisite whose name is of the form ‘-lname’.
(You can tell something strange is going on here because the prerequisite is normally the
name of a ﬁle, and the ﬁle name of a library generally looks like libname.a, not like
When a prerequisite’s name has the form ‘-lname’, make handles it specially by searching
for the ﬁle libname.so, and, if it is not found, for the ﬁle libname.a inthe current directory,
in directories speciﬁed by matching vpath search paths and the VPATH searchpath,and then
in the directories /lib, /usr/lib, and prefix/lib (normally /usr/local/lib, but MS-
DOS/MS-Windows versions of make behave as if preﬁx is deﬁned to be the root of the
DJGPP installation tree).
For example, if there is a /usr/lib/libcurses.a library on your system (and no
/usr/lib/libcurses.so ﬁle), then
foo : foo.c -lcurses
cc $^ -o $@
would cause the command ‘cc foo.c /usr/lib/libcurses.a -o foo’ to be executed when
foo is older than foo.c or than /usr/lib/libcurses.a.
Although the default set of ﬁles to be searched for is libname.so and libname.a, this
is customizable via the .LIBPATTERNS variable. Each word in the value of this variable is
Chapter 4: Writing Rules
apattern string. When a prerequisite like ‘-lname’ is seen, make will replace the percent
in each pattern in the list with name and perform the above directory searches using each
library ﬁle name.
The default value for .LIBPATTERNS is ‘lib%.so lib%.a’, which provides the default
behavior described above.
You can turn oﬀ link library expansion completely by setting this variable to an empty
4.5 Phony Targets
Aphony target is one that is not really the name of a ﬁle; rather it is just a name for a
recipe to be executed when you make an explicit request. There are two reasons to use a
phony target: to avoid a conﬂict with a ﬁle of the same name, and to improve performance.
If you write a rule whose recipe will not create the target ﬁle, the recipe will be executed
every time the target comes up for remaking. Here is an example:
rm *.o temp
Because the rm command does not create a ﬁle named clean, probably no such ﬁle will
ever exist. Therefore, the rm command will be executed every time you say ‘make clean’.
In this example, the clean target will not work properly if a ﬁle named clean is ever
created in this directory. Since it has no prerequisites, clean would always be considered
up to date and its recipe would not be executed. To avoid this problem you can explicitly
declare the target to be phony by making it a prerequisite of the special target .PHONY (see
Section 4.8 [Special Built-in Target Names], page 32)asfollows:
rm *.o temp
Once this is done, ‘make clean’ will run the recipe regardless of whether there is a ﬁle
Phony targets are also useful in conjunction with recursive invocations of make (see
Section 5.7 [Recursive Use of make], page 50). Inthis s situation the e makeﬁle will often
contain a variable which lists a number of sub-directories to be built. A simplistic way to
handle this is to deﬁne one rule with a recipe that loops over the sub-directories, like this:
SUBDIRS = foo bar baz
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
There are problems with this method, however. First, any error detected in a sub-make
is ignored by this rule, so it will continue to build the rest of the directories even when one
fails. This can be overcome by adding shell commands to note the error and exit, but then
it will do so even if make is invoked with the -k option, which is unfortunate. Second, and
perhaps more importantly, you cannot take advantage of make’s ability to build targets in
parallel (seeSection5.4[ParallelExecution],page47), since there is only one rule.
By declaring the sub-directories as .PHONY targets (you must do this as the sub-directory
obviously always exists; otherwise it won’t be built) you can remove these problems:
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
$(MAKE) -C $@
Here we’ve also declared that the foo sub-directory cannot be built until after the baz
sub-directory is complete; this kind of relationship declaration is particularly important
when attempting parallel builds.
The implicit rule search (seeChapter10[ImplicitRules],page111) is skipped for .PHONY
targets. This is why declaring a target as .PHONY is good for performance, even if you are
not worried about the actual ﬁle existing.
Aphony target should not be a prerequisite of a real target ﬁle; if it is, its recipe will
be run every time make goes to update that ﬁle. As long as a phony target is never a
prerequisite of a real target, the phony target recipe will be executed only when the phony
target is a speciﬁed goal (seeSection9.2[ArgumentstoSpecifytheGoals],page99).
Phony targets can have prerequisites. When one directory contains multiple programs,
it is most convenient to describe all of the programs in one makeﬁle ./Makefile. Since the
target remade by default will be the ﬁrst one in the makeﬁle, it is common to make this
aphony target named ‘all’ and give it, as prerequisites, all the individual programs. For
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils.o
Now you can say just ‘make’ to remake all three programs, or specify as arguments the ones
to remake (as in ‘make prog1 prog3’). Phoniness is not inherited: the prerequisites of a
phony target are not themselves phony, unless explicitly declared to be so.
When one phony target is a prerequisite of another, it serves as a subroutine of the other.
For example, here ‘make cleanall’ will delete the object ﬁles, the diﬀerence ﬁles, and the
.PHONY: cleanall cleanobj cleandiff
Documents you may be interested
Documents you may be interested