• No results found

Here are some functions that 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’. $(patsubstpattern,replacement,text)

Finds whitespace-separated words intextthat matchpatternand replaces them with replacement. Here pattern may contain a ‘%’ which acts as a wildcard, matching any number of any characters within a word. Ifreplacementalso con- tains a ‘%’, the ‘%’ is replaced by the text that matched the ‘%’ inpattern. Only the first ‘%’ in thepatternandreplacement is treated this way; any subsequent ‘%’ is unchanged.

‘%’ characters inpatsubst 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 ‘%’ char- acters 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 Section 6.3.1 [Substitution References], page 52) are a simpler way to get the effect of thepatsubst 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

$(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 inter- nal 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 condi- tionals. 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 Chapter 7 [Conditionals], page 61).

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 theifneqdirective would make it more robust. $(findstring find,in)

Searches infor 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 examples,

$(findstring a,a b c) $(findstring a,b c)

produce the values ‘a’ and ‘’ (the empty string), respectively. See Section 7.3 [Testing Flags], page 64, for a practical application offindstring.

$(filterpattern...,text)

Returns all whitespace-separated words intextthatdomatch any of thepattern

words, removing any words that do not match. The patterns are written using ‘%’, just like the patterns used in thepatsubstfunction above.

Thefilterfunction 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 com- piler.

$(filter-out pattern...,text)

Returns all whitespace-separated words in text that do not match any of the

pattern words, removing the words that do match one or more. This is the exact opposite of thefilterfunction.

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

$(sortlist)

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, sincesortremoves duplicate words, you can use it for this purpose even if you don’t care about the sort order.

$(wordn,text)

Returns the nth word oftext. The legitimate values of n start from 1. If n is bigger than the number of words in text, the value is empty. For example,

$(word 2, foo bar baz) returns ‘bar’.

$(wordlists,e,text)

Returns the list of words in text starting with word s and ending with word e

(inclusive). The legitimate values of s and e start from 1. If s is bigger than the number of words intext, the value is empty. Ife is bigger than the number of words in text, words up to the end of textare returned. If s is greater than

e, nothing is returned. For example, $(wordlist 2, 3, foo bar baz) returns ‘bar baz’.

$(words text)

Returns the number of words in text. Thus, the last word of text is $(word $(words text),text).

$(firstword names...)

The argumentnamesis regarded as a series of names, separated by whitespace. The value is the first name in the series. The rest of the names are ignored. For example,

$(firstword foo bar)

produces the result ‘foo’. Although $(firstword text)is the same as$(word 1,text), thefirstword function is retained for its simplicity.

Here is a realistic example of the use of subst and patsubst. Suppose that a makefile uses theVPATHvariable to specify a list of directories thatmakeshould search for prerequisite files (see Section 4.4.1 [VPATH Search Path for All Prerequisites], page 21). This example shows how to tell the C compiler to search for header files in the same list of directories.

The value ofVPATHis a list of directories separated by colons, such as ‘src:../headers’. First, the substfunction 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 Section 6.7 [The overrideDirective], page 57).