Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function "patsubst" in Makefile

Tags:

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.

like image 392
Ji Cha Avatar asked Aug 24 '15 06:08

Ji Cha


People also ask

What is := in makefile?

Expanded assignment = defines a recursively-expanded variable. := defines a simply-expanded variable.

How do I use IFEQ in makefile?

The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.


1 Answers

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:

  • function.c +146: The function patsubst_expand_pat
  • misc.c +337: The function find_next_token
  • misc.c +325: The function next_token

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
like image 177
jmlemetayer Avatar answered Sep 19 '22 17:09

jmlemetayer