Here are some functions that operate on strings:
$(subst
from,
to,
text)
$(subst ee,EE,feet on the street)
substitutes the string fEEt on the strEEt
.
$(patsubst
pattern,
replacement,
text)
%
which acts as a wildcard,
matching any number of any characters within a word. If
replacement also contains a %
, the %
is replaced
by the text that matched the %
in pattern. Only the first
%
in the pattern and replacement is treated this
way; any subsequent %
is unchanged.
%
characters in patsubst
function invocations 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 file names or has a stem
substituted into it. Backslashes that are not in danger of quoting
%
characters go unmolested. For example, the pattern
the\%weird\\%pattern\\
has the%weird\
preceding the
operative %
character, and pattern\\
following it. The
final two backslashes are left alone because they cannot affect any
%
character.
Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded.
For example,
$(patsubst %.c,%.o,x.c.c bar.c)
produces the value x.c.o bar.o
.
Substitution references (see Substitution References) are a simpler way to get the effect of the patsubst
function:
$(var:pattern=replacement)
is equivalent to
$(patsubst pattern,replacement,$(var))
The second shorthand simplifies one of the most common uses of
patsubst
: replacing the suffix at the end of file names.
$(var:suffix=replacement)
is equivalent to
$(patsubst %suffix,%replacement,$(var))
For example, you might have a list of object files:
objects = foo.o bar.o baz.o
To get the list of corresponding source files, you could simply write:
$(objects:.o=.c)
instead of using the general form:
$(patsubst %.o,%.c,$(objects))
$(strip
string)
$(strip a b c )
results in a b c
.
The function strip
can be very useful when used in conjunction
with conditionals. When comparing something with the empty string
using
ifeq
or ifneq
, you usually want a string of
just whitespace to match the empty string (see Conditionals).
Thus, the following may fail to have the desired results:
.PHONY: all ifneq "$(needs_made)" "" all: $(needs_made) else all:;@echo 'Nothing to make!' endif
Replacing the variable reference $(needs_made)
with the
function call $(strip $(needs_made))
in the ifneq
directive would make it more robust.
$(findstring
find,
in)
$(findstring a,a b c) $(findstring a,b c)
produce the values a
and (the empty string),
respectively. See Testing Flags, for a practical application of
findstring
.
$(filter
pattern...,
text)
%
, just like the patterns
used in the patsubst
function above.
The filter
function can be used to separate out different types
of strings (such as file names) in a variable. For example:
sources := foo.c bar.c baz.s ugh.h foo: $(sources) cc $(filter %.c %.s,$(sources)) -o foo
says that foo
depends of foo.c
, bar.c
,
baz.s
and ugh.h
but only foo.c
, bar.c
and
baz.s
should be specified in the command to the
compiler.
$(filter-out
pattern...,
text)
filter
function.
For example, given:
objects=main1.o foo.o main2.o bar.o mains=main1.o main2.o
the following generates a list which contains all the object files not
in mains
:
$(filter-out $(mains),$(objects))
$(sort
list)
$(sort foo bar lose)
returns the value bar foo lose
.
Incidentally, since sort
removes duplicate words, you can use
it for this purpose even if you don't care about the sort order.
$(word
n,
text)
$(word 2, foo bar baz)
returns bar
.
$(wordlist
s,
e,
text)
$(wordlist 2, 3, foo bar baz)
returns bar baz
.
$(words
text)
$(word $(words
text),
text)
.
$(firstword
names...)
For example,
$(firstword foo bar)
produces the result foo
. Although $(firstword
text)
is the same as $(word 1,
text)
, the
firstword
function is retained for its simplicity.
Here is a realistic example of the use of subst
and
patsubst
. Suppose that a makefile uses the VPATH
variable
to specify a list of directories that make
should search for
prerequisite files
(see VPATH
Search Path for All Prerequisites).
This example shows how to
tell the C compiler to search for header files in the same list of
directories.
The value of VPATH
is a list of directories separated by colons,
such as src:../headers
. First, the subst
function is used to
change the colons to spaces:
$(subst :, ,$(VPATH))
This produces src ../headers
. Then patsubst
is used to turn
each directory name into a -I
flag. These can be added to the
value of the variable CFLAGS
, which is passed automatically to the C
compiler, like this:
override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
The effect is to append the text -Isrc -I../headers
to the
previously given value of CFLAGS
. The override
directive is
used so that the new value is assigned even if the previous value of
CFLAGS
was specified with a command argument (see The override
Directive).