1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
<h1 class="section">Functions for String Substitution and Analysis</h1> <p>Here are some functions that operate on strings: </p> <dl compact> <dt id="$(subst from,to,text)"><code>$(subst <var>from</var>,<var>to</var>,<var>text</var>)</code></dt> <dd>
<p>Performs a textual replacement on the text <var>text</var>: each occurrence of <var>from</var> is replaced by <var>to</var>. The result is substituted for the function call. For example, </p> <div class="example"> <pre class="example">$(subst ee,EE,feet on the street)
</pre>
</div> <p>produces the value ‘<samp>fEEt on the strEEt</samp>’. </p> </dd> <dt id="$(patsubst pattern,replacement,text)"><code>$(patsubst <var>pattern</var>,<var>replacement</var>,<var>text</var>)</code></dt> <dd>
<p>Finds whitespace-separated words in <var>text</var> that match <var>pattern</var> and replaces them with <var>replacement</var>. Here <var>pattern</var> may contain a ‘<samp>%</samp>’ which acts as a wildcard, matching any number of any characters within a word. If <var>replacement</var> also contains a ‘<samp>%</samp>’, the ‘<samp>%</samp>’ is replaced by the text that matched the ‘<samp>%</samp>’ in <var>pattern</var>. Words that do not match the pattern are kept without change in the output. Only the first ‘<samp>%</samp>’ in the <var>pattern</var> and <var>replacement</var> is treated this way; any subsequent ‘<samp>%</samp>’ is unchanged. </p> <p>‘<samp>%</samp>’ characters in <code>patsubst</code> function invocations can be quoted with preceding backslashes (‘<samp>\</samp>’). Backslashes that would otherwise quote ‘<samp>%</samp>’ characters can be quoted with more backslashes. Backslashes that quote ‘<samp>%</samp>’ 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 ‘<samp>%</samp>’ characters go unmolested. For example, the pattern <samp>the\%weird\\%pattern\\</samp> has ‘<samp>the%weird\</samp>’ preceding the operative ‘<samp>%</samp>’ character, and ‘<samp>pattern\\</samp>’ following it. The final two backslashes are left alone because they cannot affect any ‘<samp>%</samp>’ character. </p> <p>Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded. </p> <p>For example, </p> <div class="example"> <pre class="example">$(patsubst %.c,%.o,x.c.c bar.c)
</pre>
</div> <p>produces the value ‘<samp>x.c.o bar.o</samp>’. </p> <p>Substitution references (see <a href="substitution-refs">Substitution References</a>) are a simpler way to get the effect of the <code>patsubst</code> function: </p> <div class="example"> <pre class="example">$(<var>var</var>:<var>pattern</var>=<var>replacement</var>)
</pre>
</div> <p>is equivalent to </p> <div class="example"> <pre class="example">$(patsubst <var>pattern</var>,<var>replacement</var>,$(<var>var</var>))
</pre>
</div> <p>The second shorthand simplifies one of the most common uses of <code>patsubst</code>: replacing the suffix at the end of file names. </p> <div class="example"> <pre class="example">$(<var>var</var>:<var>suffix</var>=<var>replacement</var>)
</pre>
</div> <p>is equivalent to </p> <div class="example"> <pre class="example">$(patsubst %<var>suffix</var>,%<var>replacement</var>,$(<var>var</var>))
</pre>
</div> <p>For example, you might have a list of object files: </p> <div class="example"> <pre class="example">objects = foo.o bar.o baz.o
</pre>
</div> <p>To get the list of corresponding source files, you could simply write: </p> <div class="example"> <pre class="example">$(objects:.o=.c)
</pre>
</div> <p>instead of using the general form: </p> <div class="example"> <pre class="example">$(patsubst %.o,%.c,$(objects))
</pre>
</div> </dd> <dt id="$(strip string)"><code>$(strip <var>string</var>)</code></dt> <dd>
<p>Removes leading and trailing whitespace from <var>string</var> and replaces each internal sequence of one or more whitespace characters with a single space. Thus, ‘<samp>$(strip a b c )</samp>’ results in ‘<samp>a b c</samp>’. </p> <p>The function <code>strip</code> can be very useful when used in conjunction with conditionals. When comparing something with the empty string ‘’ using <code>ifeq</code> or <code>ifneq</code>, you usually want a string of just whitespace to match the empty string (see <a href="conditionals">Conditionals</a>). </p> <p>Thus, the following may fail to have the desired results: </p> <div class="example"> <pre class="example">.PHONY: all
ifneq "$(needs_made)" ""
all: $(needs_made)
else
all:;@echo 'Nothing to make!'
endif
</pre>
</div> <p>Replacing the variable reference ‘<samp><span class="nolinebreak">$(needs_made)</span></samp>’ with the function call ‘<samp>$(strip <span class="nolinebreak">$(needs_made))</span></samp>’ in the <code>ifneq</code> directive would make it more robust. </p> </dd> <dt id="$(findstring find,in)"><code>$(findstring <var>find</var>,<var>in</var>)</code></dt> <dd>
<p>Searches <var>in</var> for an occurrence of <var>find</var>. If it occurs, the value is <var>find</var>; 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, </p> <div class="example"> <pre class="example">$(findstring a,a b c)
$(findstring a,b c)
</pre>
</div> <p>produce the values ‘<samp>a</samp>’ and ‘’ (the empty string), respectively. See <a href="testing-flags">Testing Flags</a>, for a practical application of <code>findstring</code>. </p> </dd> <dt id="$(filter pattern…,text)"><code>$(filter <var>pattern</var>…,<var>text</var>)</code></dt> <dd>
<p>Returns all whitespace-separated words in <var>text</var> that <em>do</em> match any of the <var>pattern</var> words, removing any words that <em>do not</em> match. The patterns are written using ‘<samp>%</samp>’, just like the patterns used in the <code>patsubst</code> function above. </p> <p>The <code>filter</code> function can be used to separate out different types of strings (such as file names) in a variable. For example: </p> <div class="example"> <pre class="example">sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
</pre>
</div> <p>says that <samp>foo</samp> depends of <samp>foo.c</samp>, <samp>bar.c</samp>, <samp>baz.s</samp> and <samp>ugh.h</samp> but only <samp>foo.c</samp>, <samp>bar.c</samp> and <samp>baz.s</samp> should be specified in the command to the compiler. </p> </dd> <dt id="$(filter-out pattern…,text)"><code>$(filter-out <var>pattern</var>…,<var>text</var>)</code></dt> <dd>
<p>Returns all whitespace-separated words in <var>text</var> that <em>do not</em> match any of the <var>pattern</var> words, removing the words that <em>do</em> match one or more. This is the exact opposite of the <code>filter</code> function. </p> <p>For example, given: </p> <div class="example"> <pre class="example">objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
</pre>
</div> <p>the following generates a list which contains all the object files not in ‘<samp>mains</samp>’: </p> <div class="example"> <pre class="example">$(filter-out $(mains),$(objects))
</pre>
</div> </dd> <dt id="$(sort list)"><code>$(sort <var>list</var>)</code></dt> <dd>
<p>Sorts the words of <var>list</var> in lexical order, removing duplicate words. The output is a list of words separated by single spaces. Thus, </p> <div class="example"> <pre class="example">$(sort foo bar lose)
</pre>
</div> <p>returns the value ‘<samp>bar foo lose</samp>’. </p> <p>Incidentally, since <code>sort</code> removes duplicate words, you can use it for this purpose even if you don’t care about the sort order. </p> </dd> <dt id="$(word n,text)"><code>$(word <var>n</var>,<var>text</var>)</code></dt> <dd>
<p>Returns the <var>n</var>th word of <var>text</var>. The legitimate values of <var>n</var> start from 1. If <var>n</var> is bigger than the number of words in <var>text</var>, the value is empty. For example, </p> <div class="example"> <pre class="example">$(word 2, foo bar baz)
</pre>
</div> <p>returns ‘<samp>bar</samp>’. </p> </dd> <dt id="$(wordlist s,e,text)"><code>$(wordlist <var>s</var>,<var>e</var>,<var>text</var>)</code></dt> <dd>
<p>Returns the list of words in <var>text</var> starting with word <var>s</var> and ending with word <var>e</var> (inclusive). The legitimate values of <var>s</var> start from 1; <var>e</var> may start from 0. If <var>s</var> is bigger than the number of words in <var>text</var>, the value is empty. If <var>e</var> is bigger than the number of words in <var>text</var>, words up to the end of <var>text</var> are returned. If <var>s</var> is greater than <var>e</var>, nothing is returned. For example, </p> <div class="example"> <pre class="example">$(wordlist 2, 3, foo bar baz)
</pre>
</div> <p>returns ‘<samp>bar baz</samp>’. </p> </dd> <dt id="$(words text)"><code>$(words <var>text</var>)</code></dt> <dd>
<p>Returns the number of words in <var>text</var>. Thus, the last word of <var>text</var> is <code>$(word $(words <var>text</var>),<var>text</var>)</code>. </p> </dd> <dt id="$(firstword names…)"><code>$(firstword <var>names</var>…)</code></dt> <dd>
<p>The argument <var>names</var> is 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. </p> <p>For example, </p> <div class="example"> <pre class="example">$(firstword foo bar)
</pre>
</div> <p>produces the result ‘<samp>foo</samp>’. Although <code>$(firstword
<var>text</var>)</code> is the same as <code>$(word 1,<var>text</var>)</code>, the <code>firstword</code> function is retained for its simplicity. </p> </dd> <dt id="$(lastword names…)"><code>$(lastword <var>names</var>…)</code></dt> <dd>
<p>The argument <var>names</var> is regarded as a series of names, separated by whitespace. The value is the last name in the series. </p> <p>For example, </p> <div class="example"> <pre class="example">$(lastword foo bar)
</pre>
</div> <p>produces the result ‘<samp>bar</samp>’. Although <code>$(lastword
<var>text</var>)</code> is the same as <code>$(word $(words <var>text</var>),<var>text</var>)</code>, the <code>lastword</code> function was added for its simplicity and better performance. </p>
</dd> </dl> <p>Here is a realistic example of the use of <code>subst</code> and <code>patsubst</code>. Suppose that a makefile uses the <code>VPATH</code> variable to specify a list of directories that <code>make</code> should search for prerequisite files (see <a href="general-search"><code>VPATH</code> Search Path for All Prerequisites</a>). This example shows how to tell the C compiler to search for header files in the same list of directories. </p> <p>The value of <code>VPATH</code> is a list of directories separated by colons, such as ‘<samp>src:../headers</samp>’. First, the <code>subst</code> function is used to change the colons to spaces: </p> <div class="example"> <pre class="example">$(subst :, ,$(VPATH))
</pre>
</div> <p>This produces ‘<samp>src ../headers</samp>’. Then <code>patsubst</code> is used to turn each directory name into a ‘<samp>-I</samp>’ flag. These can be added to the value of the variable <code>CFLAGS</code>, which is passed automatically to the C compiler, like this: </p> <div class="example"> <pre class="example">override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
</pre>
</div> <p>The effect is to append the text ‘<samp>-Isrc -I../headers</samp>’ to the previously given value of <code>CFLAGS</code>. The <code>override</code> directive is used so that the new value is assigned even if the previous value of <code>CFLAGS</code> was specified with a command argument (see <a href="override-directive">The <code>override</code> Directive</a>). </p><div class="_attribution">
<p class="_attribution-p">
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc. <br>Licensed under the GNU Free Documentation License.<br>
<a href="https://www.gnu.org/software/make/manual/html_node/Text-Functions.html" class="_attribution-link">https://www.gnu.org/software/make/manual/html_node/Text-Functions.html</a>
</p>
</div>
|