make: Computed Names
1
1 6.3.2 Computed Variable Names
1 -----------------------------
1
1 Computed variable names are a complicated concept needed only for
1 sophisticated makefile programming. For most purposes you need not
1 consider them, except to know that making a variable with a dollar sign
1 in its name might have strange results. However, if you are the type
1 that wants to understand everything, or you are actually interested in
1 what they do, read on.
1
1 Variables may be referenced inside the name of a variable. This is
1 called a "computed variable name" or a "nested variable reference". For
1 example,
1
1 x = y
1 y = z
1 a := $($(x))
1
1 defines 'a' as 'z': the '$(x)' inside '$($(x))' expands to 'y', so
1 '$($(x))' expands to '$(y)' which in turn expands to 'z'. Here the name
1 of the variable to reference is not stated explicitly; it is computed by
1 expansion of '$(x)'. The reference '$(x)' here is nested within the
1 outer variable reference.
1
1 The previous example shows two levels of nesting, but any number of
1 levels is possible. For example, here are three levels:
1
1 x = y
1 y = z
1 z = u
1 a := $($($(x)))
1
1 Here the innermost '$(x)' expands to 'y', so '$($(x))' expands to '$(y)'
1 which in turn expands to 'z'; now we have '$(z)', which becomes 'u'.
1
1 References to recursively-expanded variables within a variable name
1 are re-expanded in the usual fashion. For example:
1
1 x = $(y)
1 y = z
1 z = Hello
1 a := $($(x))
1
1 defines 'a' as 'Hello': '$($(x))' becomes '$($(y))' which becomes '$(z)'
1 which becomes 'Hello'.
1
1 Nested variable references can also contain modified references and
11 function invocations (⇒Functions for Transforming Text
Functions.), just like any other reference. For example, using the
11 'subst' function (⇒Functions for String Substitution and Analysis
Text Functions.):
1
1 x = variable1
1 variable2 := Hello
1 y = $(subst 1,2,$(x))
1 z = y
1 a := $($($(z)))
1
1 eventually defines 'a' as 'Hello'. It is doubtful that anyone would
1 ever want to write a nested reference as convoluted as this one, but it
1 works: '$($($(z)))' expands to '$($(y))' which becomes '$($(subst
1 1,2,$(x)))'. This gets the value 'variable1' from 'x' and changes it by
1 substitution to 'variable2', so that the entire string becomes
1 '$(variable2)', a simple variable reference whose value is 'Hello'.
1
1 A computed variable name need not consist entirely of a single
1 variable reference. It can contain several variable references, as well
1 as some invariant text. For example,
1
1 a_dirs := dira dirb
1 1_dirs := dir1 dir2
1
1 a_files := filea fileb
1 1_files := file1 file2
1
1 ifeq "$(use_a)" "yes"
1 a1 := a
1 else
1 a1 := 1
1 endif
1
1 ifeq "$(use_dirs)" "yes"
1 df := dirs
1 else
1 df := files
1 endif
1
1 dirs := $($(a1)_$(df))
1
1 will give 'dirs' the same value as 'a_dirs', '1_dirs', 'a_files' or
1 '1_files' depending on the settings of 'use_a' and 'use_dirs'.
1
1 Computed variable names can also be used in substitution references:
1
1 a_objects := a.o b.o c.o
1 1_objects := 1.o 2.o 3.o
1
1 sources := $($(a1)_objects:.o=.c)
1
1 defines 'sources' as either 'a.c b.c c.c' or '1.c 2.c 3.c', depending on
1 the value of 'a1'.
1
1 The only restriction on this sort of use of nested variable
1 references is that they cannot specify part of the name of a function to
1 be called. This is because the test for a recognized function name is
1 done before the expansion of nested references. For example,
1
1 ifdef do_sort
1 func := sort
1 else
1 func := strip
1 endif
1
1 bar := a d b g q c
1
1 foo := $($(func) $(bar))
1
1 attempts to give 'foo' the value of the variable 'sort a d b g q c' or
1 'strip a d b g q c', rather than giving 'a d b g q c' as the argument to
1 either the 'sort' or the 'strip' function. This restriction could be
1 removed in the future if that change is shown to be a good idea.
1
1 You can also use computed variable names in the left-hand side of a
1 variable assignment, or in a 'define' directive, as in:
1
1 dir = foo
1 $(dir)_sources := $(wildcard $(dir)/*.c)
1 define $(dir)_print =
1 lpr $($(dir)_sources)
1 endef
1
1 This example defines the variables 'dir', 'foo_sources', and
1 'foo_print'.
1
1 Note that "nested variable references" are quite different from
11 "recursively expanded variables" (⇒The Two Flavors of Variables
Flavors.), though both are used together in complex ways when doing
1 makefile programming.
1