f78 Functions for String Substitution and Analysis Contents|Index|Previous|Next

Functions for String Substitution and Analysis

The following functions operate on strings.

$(subst from, to, text)
Performs a textual replacement on the text
text: each occurrence of from is replaced by to. The result is substituted for the function call.

For example, $(subst ee,EE,feet on the street) substitutes the string ‘fEEt on the strEEt’.

$(patsubst pattern, replacement, text)
Finds whitespace-separated words in
text that match pattern and replaces them with replacement. In this string, pattern may contain a ‘%’ 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.

‘%’ 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 compares file names ffb 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 are a simpler way to get the effect of the patsubst function (see Substitution References).

$(var: pattern=replacement)

The previous example of a substitution reference is equivalent to the following example’s input.

$(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)
Removes leading and trailing whitespace from string and replaces each internal sequence of one or more whitespace characters with a single space. Thus, ‘$(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 an empty string using ifeq or ifneq, you usually want a string of just whitespace to match the empty string (see Conditional Parts of Makefiles).

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)
Searches in for an occurrence of find. If it occurs, the value is find; otherwise, the value is empty. You can use this function in a conditional to test for the presence of a specific substring in a given string.

Thus, the two following examples produce, respectively, the values ‘a’ and an empty string.

$(findstring a,a b c)

$(findstring a,b c)

See Conditions that Test Flags for a practical application of findstring.

$(filter pattern ...,text)
Removes all whitespace-separated words in text that do not match any of the pattern words, returning only words that do match. The patterns are written using ‘%’, just like the patterns used in the patsubst function.

The filter function can be used to separate out different types of strings (such as file names) in a variable. Consider the following, for example.

sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
        cc $(filter %.c %.s,$(sources)) -o foo

With this statement, ‘foo’ depends on ‘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)
Removes all whitespace-separated words in
text that do match the pattern words, returning only the words that do not match. This is the exact opposite of the filter function. Consider the following for example.

objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o

Given the previous lines, the following then generates a list which contains all the object files not in ‘mains’.

$(filter-out $(mains),$(objects))

$(sort list)
Sorts the words of
list in lexical order, removing duplicate words. The output is a list of words separated by single spaces.

Thus, $(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.

The following 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 dependency files (see VPATH: Search Path for All Dependencies). The following 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< 682 /FONT>’. 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, as in the following.

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).

0