make: Flavors

1 
1 6.2 The Two Flavors of Variables
1 ================================
1 
1 There are two ways that a variable in GNU 'make' can have a value; we
1 call them the two "flavors" of variables.  The two flavors are
1 distinguished in how they are defined and in what they do when expanded.
1 
1    The first flavor of variable is a "recursively expanded" variable.
DONTPRINTYET 11 Variables of this sort are defined by lines using '=' (⇒Setting
 Variables Setting.) or by the 'define' directive (*noteDefining
1DONTPRINTYET 11 Variables of this sort are defined by lines using '=' (⇒Setting
 Variables Setting.) or by the 'define' directive (⇒Defining

 Multi-Line Variables Multi-Line.).  The value you specify is installed
1 verbatim; if it contains references to other variables, these references
1 are expanded whenever this variable is substituted (in the course of
1 expanding some other string).  When this happens, it is called
1 "recursive expansion".
1 
1    For example,
1 
1      foo = $(bar)
1      bar = $(ugh)
1      ugh = Huh?
1 
1      all:;echo $(foo)
1 
1 will echo 'Huh?': '$(foo)' expands to '$(bar)' which expands to '$(ugh)'
1 which finally expands to 'Huh?'.
1 
1    This flavor of variable is the only sort supported by most other
1 versions of 'make'.  It has its advantages and its disadvantages.  An
1 advantage (most would say) is that:
1 
1      CFLAGS = $(include_dirs) -O
1      include_dirs = -Ifoo -Ibar
1 
1 will do what was intended: when 'CFLAGS' is expanded in a recipe, it
1 will expand to '-Ifoo -Ibar -O'.  A major disadvantage is that you
1 cannot append something on the end of a variable, as in
1 
1      CFLAGS = $(CFLAGS) -O
1 
1 because it will cause an infinite loop in the variable expansion.
1 (Actually 'make' detects the infinite loop and reports an error.)
1 
11    Another disadvantage is that any functions (⇒Functions for
 Transforming Text Functions.) referenced in the definition will be
1 executed every time the variable is expanded.  This makes 'make' run
1 slower; worse, it causes the 'wildcard' and 'shell' functions to give
1 unpredictable results because you cannot easily control when they are
1 called, or even how many times.
1 
1    To avoid all the problems and inconveniences of recursively expanded
1 variables, there is another flavor: simply expanded variables.
1 
1    "Simply expanded variables" are defined by lines using ':=' or '::='
1 (⇒Setting Variables Setting.).  Both forms are equivalent in GNU
1 'make'; however only the '::=' form is described by the POSIX standard
1 (support for '::=' was added to the POSIX standard in 2012, so older
1 versions of 'make' won't accept this form either).
1 
1    The value of a simply expanded variable is scanned once and for all,
1 expanding any references to other variables and functions, when the
1 variable is defined.  The actual value of the simply expanded variable
1 is the result of expanding the text that you write.  It does not contain
1 any references to other variables; it contains their values _as of the
1 time this variable was defined_.  Therefore,
1 
1      x := foo
1      y := $(x) bar
1      x := later
1 
1 is equivalent to
1 
1      y := foo bar
1      x := later
1 
1    When a simply expanded variable is referenced, its value is
1 substituted verbatim.
1 
1    Here is a somewhat more complicated example, illustrating the use of
11 ':=' in conjunction with the 'shell' function.  (⇒The 'shell'
 Function Shell Function.)  This example also shows use of the variable
1 'MAKELEVEL', which is changed when it is passed down from level to
11 level.  (⇒Communicating Variables to a Sub-'make'
 Variables/Recursion, for information about 'MAKELEVEL'.)
1 
1      ifeq (0,${MAKELEVEL})
1      whoami    := $(shell whoami)
1      host-type := $(shell arch)
1      MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
1      endif
1 
1 An advantage of this use of ':=' is that a typical 'descend into a
1 directory' recipe then looks like this:
1 
1      ${subdirs}:
1              ${MAKE} -C $@ all
1 
1    Simply expanded variables generally make complicated makefile
1 programming more predictable because they work like variables in most
1 programming languages.  They allow you to redefine a variable using its
1 own value (or its value processed in some way by one of the expansion
1 functions) and to use the expansion functions much more efficiently
1 (⇒Functions for Transforming Text Functions.).
1 
1    You can also use them to introduce controlled leading whitespace into
1 variable values.  Leading whitespace characters are discarded from your
1 input before substitution of variable references and function calls;
1 this means you can include leading spaces in a variable value by
1 protecting them with variable references, like this:
1 
1      nullstring :=
1      space := $(nullstring) # end of the line
1 
1 Here the value of the variable 'space' is precisely one space.  The
1 comment '# end of the line' is included here just for clarity.  Since
1 trailing space characters are _not_ stripped from variable values, just
1 a space at the end of the line would have the same effect (but be rather
1 hard to read).  If you put whitespace at the end of a variable value, it
1 is a good idea to put a comment like that at the end of the line to make
1 your intent clear.  Conversely, if you do _not_ want any whitespace
1 characters at the end of your variable value, you must remember not to
1 put a random comment on the end of the line after some whitespace, such
1 as this:
1 
1      dir := /foo/bar    # directory to put the frobs in
1 
1 Here the value of the variable 'dir' is '/foo/bar    ' (with four
1 trailing spaces), which was probably not the intention.  (Imagine
1 something like '$(dir)/file' with this definition!)
1 
1    There is another assignment operator for variables, '?='.  This is
1 called a conditional variable assignment operator, because it only has
1 an effect if the variable is not yet defined.  This statement:
1 
1      FOO ?= bar
1 
11 is exactly equivalent to this (⇒The 'origin' Function Origin
 Function.):
1 
1      ifeq ($(origin FOO), undefined)
1        FOO = bar
1      endif
1 
1    Note that a variable set to an empty value is still defined, so '?='
1 will not set that variable.
1