summaryrefslogtreecommitdiff
path: root/devdocs/gnu_make/computed-names.html
diff options
context:
space:
mode:
Diffstat (limited to 'devdocs/gnu_make/computed-names.html')
-rw-r--r--devdocs/gnu_make/computed-names.html72
1 files changed, 72 insertions, 0 deletions
diff --git a/devdocs/gnu_make/computed-names.html b/devdocs/gnu_make/computed-names.html
new file mode 100644
index 00000000..a83c4b00
--- /dev/null
+++ b/devdocs/gnu_make/computed-names.html
@@ -0,0 +1,72 @@
+ <h1 class="subsection">Computed Variable Names</h1> <p>Computed variable names are an advanced concept, very useful in more sophisticated makefile programming. In simple situations you need not consider them, but they can be extremely useful. </p> <p>Variables may be referenced inside the name of a variable. This is called a <em>computed variable name</em> or a <em>nested variable reference</em>. For example, </p> <div class="example"> <pre class="example">x = y
+y = z
+a := $($(x))
+</pre>
+</div> <p>defines <code>a</code> as ‘<samp>z</samp>’: the ‘<samp>$(x)</samp>’ inside ‘<samp>$($(x))</samp>’ expands to ‘<samp>y</samp>’, so ‘<samp>$($(x))</samp>’ expands to ‘<samp>$(y)</samp>’ which in turn expands to ‘<samp>z</samp>’. Here the name of the variable to reference is not stated explicitly; it is computed by expansion of ‘<samp>$(x)</samp>’. The reference ‘<samp>$(x)</samp>’ here is nested within the outer variable reference. </p> <p>The previous example shows two levels of nesting, but any number of levels is possible. For example, here are three levels: </p> <div class="example"> <pre class="example">x = y
+y = z
+z = u
+a := $($($(x)))
+</pre>
+</div> <p>Here the innermost ‘<samp>$(x)</samp>’ expands to ‘<samp>y</samp>’, so ‘<samp>$($(x))</samp>’ expands to ‘<samp>$(y)</samp>’ which in turn expands to ‘<samp>z</samp>’; now we have ‘<samp>$(z)</samp>’, which becomes ‘<samp>u</samp>’. </p> <p>References to recursively-expanded variables within a variable name are re-expanded in the usual fashion. For example: </p> <div class="example"> <pre class="example">x = $(y)
+y = z
+z = Hello
+a := $($(x))
+</pre>
+</div> <p>defines <code>a</code> as ‘<samp>Hello</samp>’: ‘<samp>$($(x))</samp>’ becomes ‘<samp>$($(y))</samp>’ which becomes ‘<samp>$(z)</samp>’ which becomes ‘<samp>Hello</samp>’. </p> <p>Nested variable references can also contain modified references and function invocations (see <a href="functions">Functions for Transforming Text</a>), just like any other reference. For example, using the <code>subst</code> function (see <a href="text-functions">Functions for String Substitution and Analysis</a>): </p> <div class="example"> <pre class="example">x = variable1
+variable2 := Hello
+y = $(subst 1,2,$(x))
+z = y
+a := $($($(z)))
+</pre>
+</div> <p>eventually defines <code>a</code> as ‘<samp>Hello</samp>’. It is doubtful that anyone would ever want to write a nested reference as convoluted as this one, but it works: ‘<samp>$($($(z)))</samp>’ expands to ‘<samp>$($(y))</samp>’ which becomes ‘<samp>$($(subst 1,2,$(x)))</samp>’. This gets the value ‘<samp>variable1</samp>’ from <code>x</code> and changes it by substitution to ‘<samp>variable2</samp>’, so that the entire string becomes ‘<samp>$(variable2)</samp>’, a simple variable reference whose value is ‘<samp>Hello</samp>’. </p> <p>A computed variable name need not consist entirely of a single variable reference. It can contain several variable references, as well as some invariant text. For example, </p> <div class="example"> <pre class="example">a_dirs := dira dirb
+1_dirs := dir1 dir2
+</pre>
+
+<pre class="example">a_files := filea fileb
+1_files := file1 file2
+</pre>
+
+<pre class="example">ifeq "$(use_a)" "yes"
+a1 := a
+else
+a1 := 1
+endif
+</pre>
+
+<pre class="example">ifeq "$(use_dirs)" "yes"
+df := dirs
+else
+df := files
+endif
+
+dirs := $($(a1)_$(df))
+</pre>
+</div> <p>will give <code>dirs</code> the same value as <code>a_dirs</code>, <code>1_dirs</code>, <code>a_files</code> or <code>1_files</code> depending on the settings of <code>use_a</code> and <code>use_dirs</code>. </p> <p>Computed variable names can also be used in substitution references: </p> <div class="example"> <pre class="example">a_objects := a.o b.o c.o
+1_objects := 1.o 2.o 3.o
+
+sources := $($(a1)_objects:.o=.c)
+</pre>
+</div> <p>defines <code>sources</code> as either ‘<samp>a.c b.c c.c</samp>’ or ‘<samp>1.c 2.c 3.c</samp>’, depending on the value of <code>a1</code>. </p> <p>The only restriction on this sort of use of nested variable references is that they cannot specify part of the name of a function to be called. This is because the test for a recognized function name is done before the expansion of nested references. For example, </p> <div class="example"> <pre class="example">ifdef do_sort
+func := sort
+else
+func := strip
+endif
+</pre>
+
+<pre class="example">bar := a d b g q c
+</pre>
+
+<pre class="example">foo := $($(func) $(bar))
+</pre>
+</div> <p>attempts to give ‘<samp>foo</samp>’ the value of the variable ‘<samp>sort a d b g q c</samp>’ or ‘<samp>strip a d b g q c</samp>’, rather than giving ‘<samp>a d b g q c</samp>’ as the argument to either the <code>sort</code> or the <code>strip</code> function. This restriction could be removed in the future if that change is shown to be a good idea. </p> <p>You can also use computed variable names in the left-hand side of a variable assignment, or in a <code>define</code> directive, as in: </p> <div class="example"> <pre class="example">dir = foo
+$(dir)_sources := $(wildcard $(dir)/*.c)
+define $(dir)_print =
+lpr $($(dir)_sources)
+endef
+</pre>
+</div> <p>This example defines the variables ‘<samp>dir</samp>’, ‘<samp>foo_sources</samp>’, and ‘<samp>foo_print</samp>’. </p> <p>Note that <em>nested variable references</em> are quite different from <em>recursively expanded variables</em> (see <a href="flavors">The Two Flavors of Variables</a>), though both are used together in complex ways when doing makefile programming. </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/Computed-Names.html" class="_attribution-link">https://www.gnu.org/software/make/manual/html_node/Computed-Names.html</a>
+ </p>
+</div>