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