make: Text Functions

1 
1 8.2 Functions for String Substitution and Analysis
1 ==================================================
1 
1 Here are some functions that operate on strings:
1 
1 '$(subst FROM,TO,TEXT)'
1      Performs a textual replacement on the text TEXT: each occurrence of
1      FROM is replaced by TO.  The result is substituted for the function
1      call.  For example,
1 
1           $(subst ee,EE,feet on the street)
1 
1      substitutes the string 'fEEt on the strEEt'.
1 
1 '$(patsubst PATTERN,REPLACEMENT,TEXT)'
1      Finds whitespace-separated words in TEXT that match PATTERN and
1      replaces them with REPLACEMENT.  Here PATTERN may contain a '%'
1      which acts as a wildcard, matching any number of any characters
1      within a word.  If REPLACEMENT also contains a '%', the '%' is
1      replaced by the text that matched the '%' in PATTERN.  Only the
1      first '%' in the PATTERN and REPLACEMENT is treated this way; any
1      subsequent '%' is unchanged.
1 
1      '%' characters in 'patsubst' function invocations can be quoted
1      with preceding backslashes ('\').  Backslashes that would otherwise
1      quote '%' characters can be quoted with more backslashes.
1      Backslashes that quote '%' characters or other backslashes are
1      removed from the pattern before it is compared file names or has a
1      stem substituted into it.  Backslashes that are not in danger of
1      quoting '%' characters go unmolested.  For example, the pattern
1      'the\%weird\\%pattern\\' has 'the%weird\' preceding the operative
1      '%' character, and 'pattern\\' following it.  The final two
1      backslashes are left alone because they cannot affect any '%'
1      character.
1 
1      Whitespace between words is folded into single space characters;
1      leading and trailing whitespace is discarded.
1 
1      For example,
1 
1           $(patsubst %.c,%.o,x.c.c bar.c)
1 
1      produces the value 'x.c.o bar.o'.
1 
11      Substitution references (⇒Substitution References
      Substitution Refs.) are a simpler way to get the effect of the
1      'patsubst' function:
1 
1           $(VAR:PATTERN=REPLACEMENT)
1 
1      is equivalent to
1 
1           $(patsubst PATTERN,REPLACEMENT,$(VAR))
1 
1      The second shorthand simplifies one of the most common uses of
1      'patsubst': replacing the suffix at the end of file names.
1 
1           $(VAR:SUFFIX=REPLACEMENT)
1 
1      is equivalent to
1 
1           $(patsubst %SUFFIX,%REPLACEMENT,$(VAR))
1 
1      For example, you might have a list of object files:
1 
1           objects = foo.o bar.o baz.o
1 
1      To get the list of corresponding source files, you could simply
1      write:
1 
1           $(objects:.o=.c)
1 
1      instead of using the general form:
1 
1           $(patsubst %.o,%.c,$(objects))
1 
1 '$(strip STRING)'
1      Removes leading and trailing whitespace from STRING and replaces
1      each internal sequence of one or more whitespace characters with a
1      single space.  Thus, '$(strip a b c )' results in 'a b c'.
1 
1      The function 'strip' can be very useful when used in conjunction
1      with conditionals.  When comparing something with the empty string
1      '' using 'ifeq' or 'ifneq', you usually want a string of just
1      whitespace to match the empty string (⇒Conditionals).
1 
1      Thus, the following may fail to have the desired results:
1 
1           .PHONY: all
1           ifneq   "$(needs_made)" ""
1           all: $(needs_made)
1           else
1           all:;@echo 'Nothing to make!'
1           endif
1 
1      Replacing the variable reference '$(needs_made)' with the function
1      call '$(strip $(needs_made))' in the 'ifneq' directive would make
1      it more robust.
1 
1 '$(findstring FIND,IN)'
1      Searches IN for an occurrence of FIND.  If it occurs, the value is
1      FIND; otherwise, the value is empty.  You can use this function in
1      a conditional to test for the presence of a specific substring in a
1      given string.  Thus, the two examples,
1 
1           $(findstring a,a b c)
1           $(findstring a,b c)
1 
1      produce the values 'a' and '' (the empty string), respectively.
1      ⇒Testing Flags, for a practical application of 'findstring'.
1 
1 '$(filter PATTERN...,TEXT)'
1      Returns all whitespace-separated words in TEXT that _do_ match any
1      of the PATTERN words, removing any words that _do not_ match.  The
1      patterns are written using '%', just like the patterns used in the
1      'patsubst' function above.
1 
1      The 'filter' function can be used to separate out different types
1      of strings (such as file names) in a variable.  For example:
1 
1           sources := foo.c bar.c baz.s ugh.h
1           foo: $(sources)
1                   cc $(filter %.c %.s,$(sources)) -o foo
1 
1      says that 'foo' depends of 'foo.c', 'bar.c', 'baz.s' and 'ugh.h'
1      but only 'foo.c', 'bar.c' and 'baz.s' should be specified in the
1      command to the compiler.
1 
1 '$(filter-out PATTERN...,TEXT)'
1      Returns all whitespace-separated words in TEXT that _do not_ match
1      any of the PATTERN words, removing the words that _do_ match one or
1      more.  This is the exact opposite of the 'filter' function.
1 
1      For example, given:
1 
1           objects=main1.o foo.o main2.o bar.o
1           mains=main1.o main2.o
1 
1      the following generates a list which contains all the object files
1      not in 'mains':
1 
1           $(filter-out $(mains),$(objects))
1 
1 '$(sort LIST)'
1      Sorts the words of LIST in lexical order, removing duplicate words.
1      The output is a list of words separated by single spaces.  Thus,
1 
1           $(sort foo bar lose)
1 
1      returns the value 'bar foo lose'.
1 
1      Incidentally, since 'sort' removes duplicate words, you can use it
1      for this purpose even if you don't care about the sort order.
1 
1 '$(word N,TEXT)'
1      Returns the Nth word of TEXT.  The legitimate values of N start
1      from 1.  If N is bigger than the number of words in TEXT, the value
1      is empty.  For example,
1 
1           $(word 2, foo bar baz)
1 
1      returns 'bar'.
1 
1 '$(wordlist S,E,TEXT)'
1      Returns the list of words in TEXT starting with word S and ending
1      with word E (inclusive).  The legitimate values of S start from 1;
1      E may start from 0.  If S is bigger than the number of words in
1      TEXT, the value is empty.  If E is bigger than the number of words
1      in TEXT, words up to the end of TEXT are returned.  If S is greater
1      than E, nothing is returned.  For example,
1 
1           $(wordlist 2, 3, foo bar baz)
1 
1      returns 'bar baz'.
1 
1 '$(words TEXT)'
1      Returns the number of words in TEXT.  Thus, the last word of TEXT
1      is '$(word $(words TEXT),TEXT)'.
1 
1 '$(firstword NAMES...)'
1      The argument NAMES is regarded as a series of names, separated by
1      whitespace.  The value is the first name in the series.  The rest
1      of the names are ignored.
1 
1      For example,
1 
1           $(firstword foo bar)
1 
1      produces the result 'foo'.  Although '$(firstword TEXT)' is the
1      same as '$(word 1,TEXT)', the 'firstword' function is retained for
1      its simplicity.
1 
1 '$(lastword NAMES...)'
1      The argument NAMES is regarded as a series of names, separated by
1      whitespace.  The value is the last name in the series.
1 
1      For example,
1 
1           $(lastword foo bar)
1 
1      produces the result 'bar'.  Although '$(lastword TEXT)' is the same
1      as '$(word $(words TEXT),TEXT)', the 'lastword' function was added
1      for its simplicity and better performance.
1 
1    Here is a realistic example of the use of 'subst' and 'patsubst'.
1 Suppose that a makefile uses the 'VPATH' variable to specify a list of
11 directories that 'make' should search for prerequisite files (⇒
 'VPATH' Search Path for All Prerequisites General Search.).  This
1 example shows how to tell the C compiler to search for header files in
1 the same list of directories.
1 
1    The value of 'VPATH' is a list of directories separated by colons,
1 such as 'src:../headers'.  First, the 'subst' function is used to change
1 the colons to spaces:
1 
1      $(subst :, ,$(VPATH))
1 
1 This produces 'src ../headers'.  Then 'patsubst' is used to turn each
1 directory name into a '-I' flag.  These can be added to the value of the
1 variable 'CFLAGS', which is passed automatically to the C compiler, like
1 this:
1 
1      override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
1 
1 The effect is to append the text '-Isrc -I../headers' to the previously
1 given value of 'CFLAGS'.  The 'override' directive is used so that the
1 new value is assigned even if the previous value of 'CFLAGS' was
11 specified with a command argument (⇒The 'override' Directive
 Override Directive.).
1