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