Ji Cha
Ji Cha

Reputation: 959

Function "patsubst" in Makefile

From the docs:

$(patsubst PATTERN,REPLACEMENT,TEXT)

Finds whitespace-separated words in TEXT that match PATTERN and replaces them with REPLACEMENT. Here PATTERN may contain a % which acts as a wildcard, matching any number of any characters within a word.
...
Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded.



Now, given a makefile, is:

# The pattern for patsubst, does NOT contain '%'
foo := $(patsubst  x,y,x    x    x)
# The pattern for patsubst, does contain '%'
bar := $(patsubst x%,y,x    x    x)


# The variable 'foo', is a result from a patsubst-pattern, that did NOT contain a '%'
# The variable 'bar', is a result from a patsubst-pattern, that did contain a '%'
all ::
    @echo 'foo is: "$(foo)"'
    @echo 'bar is: "$(bar)"'



Executing, we get:

foo is: "y    y    y"
bar is: "y y y"



So, it is obvious, that Make, may or may not "fold" all whitespace into one and single whitespace.

Or, did I do something wrong.

Upvotes: 31

Views: 70201

Answers (1)

jmlemetayer
jmlemetayer

Reputation: 4952

In fact all is explained in the doc:

Finds whitespace-separated words in TEXT ...

means that one or more spaces have to separate the words.

... that match PATTERN ...

means that it select only words that match a pattern (which can include some spaces).

... and replaces them with REPLACEMENT.

means that the selected patterns will be replace by a replacement.


A picture is worth a thousand words.

For PATTERN = X:

           +----  SEPARATORS  ----+
           |                      |
   +-------+-------+     +--------+------+
   |               |     |               | 
X  space space space  X  space space space  x
|                     |                     |
+---------------------+---------------------+
                      |
                   PATTERNS

For PATTERN = X%:

                 +----  SEPARATORS  ---+
                 |                     |
               +-+-+                 +-+-+
               |   |                 |   | 
X  space space space  X  space space space  x
|            |        |            |        |
+------+-----+        +------+-----+        |
       |                     |              |
       +---  PATTERNS  ------+--------------+

Interesting thing:

When you use the % character in your pattern, you can re-use it in the replacement, like this:

$(patsubst x%,y%,xa xb xc)
# Will be "ya yb yc"

But when you have space character in the % variable, make will strip them in the replacement.

$(patsubst x%,y%,xa   xb   xc)
# Will also be "ya yb yc"

EDIT: After reading the source code, the interesting things are:

So here is the behavior:

  1. If no % in the pattern, this is a simple substitution (which keep the spaces).
  2. Else it split the text by words and get rid of all spaces (using the isblank function).
  3. Finally, it does the replacement

Upvotes: 31

Related Questions