make: Appending

1 
1 6.6 Appending More Text to Variables
1 ====================================
1 
1 Often it is useful to add more text to the value of a variable already
1 defined.  You do this with a line containing '+=', like this:
1 
1      objects += another.o
1 
1 This takes the value of the variable 'objects', and adds the text
1 'another.o' to it (preceded by a single space).  Thus:
1 
1      objects = main.o foo.o bar.o utils.o
1      objects += another.o
1 
1 sets 'objects' to 'main.o foo.o bar.o utils.o another.o'.
1 
1    Using '+=' is similar to:
1 
1      objects = main.o foo.o bar.o utils.o
1      objects := $(objects) another.o
1 
1 but differs in ways that become important when you use more complex
1 values.
1 
1    When the variable in question has not been defined before, '+=' acts
1 just like normal '=': it defines a recursively-expanded variable.
1 However, when there _is_ a previous definition, exactly what '+=' does
11 depends on what flavor of variable you defined originally.  ⇒The
 Two Flavors of Variables Flavors, for an explanation of the two flavors
1 of variables.
1 
1    When you add to a variable's value with '+=', 'make' acts essentially
1 as if you had included the extra text in the initial definition of the
1 variable.  If you defined it first with ':=' or '::=', making it a
1 simply-expanded variable, '+=' adds to that simply-expanded definition,
1 and expands the new text before appending it to the old value just as
1 ':=' does (see ⇒Setting Variables Setting, for a full explanation
1 of ':=' or '::=').  In fact,
1 
1      variable := value
1      variable += more
1 
1 is exactly equivalent to:
1 
1      variable := value
1      variable := $(variable) more
1 
1    On the other hand, when you use '+=' with a variable that you defined
1 first to be recursively-expanded using plain '=', 'make' does something
1 a bit different.  Recall that when you define a recursively-expanded
1 variable, 'make' does not expand the value you set for variable and
1 function references immediately.  Instead it stores the text verbatim,
1 and saves these variable and function references to be expanded later,
11 when you refer to the new variable (⇒The Two Flavors of Variables
 Flavors.).  When you use '+=' on a recursively-expanded variable, it is
1 this unexpanded text to which 'make' appends the new text you specify.
1 
1      variable = value
1      variable += more
1 
1 is roughly equivalent to:
1 
1      temp = value
1      variable = $(temp) more
1 
1 except that of course it never defines a variable called 'temp'.  The
1 importance of this comes when the variable's old value contains variable
1 references.  Take this common example:
1 
1      CFLAGS = $(includes) -O
1      ...
1      CFLAGS += -pg # enable profiling
1 
1 The first line defines the 'CFLAGS' variable with a reference to another
1 variable, 'includes'.  ('CFLAGS' is used by the rules for C compilation;
1 ⇒Catalogue of Built-In Rules Catalogue of Rules.)  Using '=' for
1 the definition makes 'CFLAGS' a recursively-expanded variable, meaning
1 '$(includes) -O' is _not_ expanded when 'make' processes the definition
1 of 'CFLAGS'.  Thus, 'includes' need not be defined yet for its value to
1 take effect.  It only has to be defined before any reference to
1 'CFLAGS'.  If we tried to append to the value of 'CFLAGS' without using
1 '+=', we might do it like this:
1 
1      CFLAGS := $(CFLAGS) -pg # enable profiling
1 
1 This is pretty close, but not quite what we want.  Using ':=' redefines
1 'CFLAGS' as a simply-expanded variable; this means 'make' expands the
1 text '$(CFLAGS) -pg' before setting the variable.  If 'includes' is not
1 yet defined, we get ' -O -pg', and a later definition of 'includes' will
1 have no effect.  Conversely, by using '+=' we set 'CFLAGS' to the
1 _unexpanded_ value '$(includes) -O -pg'.  Thus we preserve the reference
1 to 'includes', so if that variable gets defined at any later point, a
1 reference like '$(CFLAGS)' still uses its value.
1