3.6. Modifying Variable Expansion

Variables need not always be expanded verbatim. PMake defines several modifiers that may be applied to a variable's value before it is expanded. You apply a modifier by placing it after the variable name with a colon between the two, like so:

${VARIABLE:modifier}

Each modifier is a single character followed by something specific to the modifier itself. You may apply as many modifiers as you want - each one is applied to the result of the previous and is separated from the previous by another colon.

There are seven ways to modify a variable's expansion, most of which come from the C shell variable modification characters:

Mpattern

This is used to select only those words (a word is a series of characters that are neither spaces nor tabs) that match the given pattern. The pattern is a wildcard pattern like that used by the shell, where * means 0 or more characters of any sort; ? is any single character; [abcd] matches any single character that is either a, b, c or d (there may be any number of characters between the brackets); [0-9] matches any single character that is between 0and 9 (i.e. any digit. This form may be freely mixed with the other bracket form), and \ is used to escape any of the characters *, ?, [ or :, leaving them as regular characters to match themselves in a word. For example, the system makefile <makedepend.mk> uses $(CFLAGS:M-[ID]*) to extract all the -I and -D flags that would be passed to the C compiler. This allows it to properly locate include files and generate the correct dependencies.

Npattern

This is identical to :M except it substitutes all words that do not match the given pattern.

S/search-string/replacement-string/[g]

Causes the first occurrence of search-string in the variable to be replaced by replacement-string, unless the g flag is given at the end, in which case all occurrences of the string are replaced. The substitution is performed on each word in the variable in turn. If search-string begins with a ^, the string must match starting at the beginning of the word. If search-string ends with a $, the string must match to the end of the word (these two may be combined to force an exact match). If a backslash precedes these two characters, however, they lose their special meaning. Variable expansion also occurs in the normal fashion inside both the search-string and the replacement-string, except that a backslash is used to prevent the expansion of a $, not another dollar sign, as is usual. Note that search-string is just a string, not a pattern, so none of the usual regularexpression/wildcard characters have any special meaning save ^ and $. In the replacement string, the & character is replaced by the search-string unless it is preceded by a backslash. You are allowed to use any character except colon or exclamation point to separate the two strings. This so-called delimiter character may be placed in either string by preceding it with a backslash.

T

Replaces each word in the variable expansion by its last component (its “tail”). For example, given:

OBJS = ../lib/a.o b /usr/lib/libm.a
TAILS = $(OBJS:T)

the variable TAILS would expand to a.o b libm.a.

H

This is similar to :T, except that every word is replaced by everything but the tail (the “head”). Using the same definition of OBJS, the string $(OBJS:H) would expand to ../lib /usr/lib. Note that the final slash on the heads is removed and anything without a head is replaced by the empty string.

E

:E replaces each word by its suffix (“extension”). So $(OBJS:E) would give you .o .a.

R

This replaces each word by everything but the suffix (the “root” of the word). $(OBJS:R) expands to ../lib/a b /usr/lib/libm.

In addition, the System V style of substitution is also supported. This looks like:

$(VARIABLE:search-string=replacement)

It must be the last modifier in the chain. The search is anchored at the end of each word, so only suffixes or whole words may be replaced.

This, and other documents, can be downloaded from ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

For questions about FreeBSD, read the documentation before contacting <[email protected]>.
For questions about this documentation, e-mail <[email protected]>.