GNU make manual 翻译( 一百六十四)
继续翻译
When you add to a variable's value with `+=', `make' acts essentially as if you had included the extra text in the initial definition of the variable. If you defined it first with `:=', making it a simply-expanded variable, `+=' adds to that simply-expanded definition, and expands the new text before appending it to the old value just as `:=' does (see *note Setting Variables: Setting, for a full explanation of `:='). In fact, variable := value variable += more is exactly equivalent to: variable := value variable := $(variable) more On the other hand, when you use `+=' with a variable that you defined first to be recursively-expanded using plain `=', `make' does something a bit different. Recall that when you define a recursively-expanded variable, `make' does not expand the value you set for variable and function references immediately. Instead it stores the text verbatim, and saves these variable and function references to be expanded later, when you refer to the new variable (*note The Two Flavors of Variables: Flavors.). When you use `+=' on a recursively-expanded variable, it is this unexpanded text to which `make' appends the new text you specify. variable = value variable += more is roughly equivalent to: temp = value variable = $(temp) more except that of course it never defines a variable called `temp'. The importance of this comes when the variable's old value contains variable references. Take this common example: CFLAGS = $(includes) -O ... CFLAGS += -pg # enable profiling The first line defines the `CFLAGS' variable with a reference to another variable, `includes'. (`CFLAGS' is used by the rules for C compilation; *note Catalogue of Implicit Rules: Catalogue of Rules.) Using `=' for the definition makes `CFLAGS' a recursively-expanded variable, meaning `$(includes) -O' is _not_ expanded when `make' processes the definition of `CFLAGS'. Thus, `includes' need not be defined yet for its value to take effect. It only has to be defined before any reference to `CFLAGS'. If we tried to append to the value of `CFLAGS' without using `+=', we might do it like this: CFLAGS := $(CFLAGS) -pg # enable profiling This is pretty close, but not quite what we want. Using `:=' redefines `CFLAGS' as a simply-expanded variable; this means `make' expands the text `$(CFLAGS) -pg' before setting the variable. If `includes' is not yet defined, we get ` -O -pg', and a later definition of `includes' will have no effect. Conversely, by using `+=' we set `CFLAGS' to the _unexpanded_ value `$(includes) -O -pg'. Thus we preserve the reference to `includes', so if that variable gets defined at any later point, a reference like `$(CFLAGS)' still uses its value.
当你用 `+='来向变量加入值的时候, `make' 就像是你在变量的初始定义里包含了额外的文本一样处理。
如果你之前先用:=来定义此变量,使其成为一个简单扩展变量,那么`+=' 就向这个简单扩展定义追加,并在准备连接到旧的值之前,扩展到新的文本(参见 *note Setting Variables: Setting, for a
full explanation of `:=')。事实上
variable := value
variable += more
精确等同于:
variable := value
variable := $(variable) more
另一方面, 当你在一个事前按照递归扩展式定义的变量使用`+=' ,`make' 的动作会有一点不同。
请回忆一下,当你定义了一个递归扩展的变量,`make' 不会马上扩展你设定的变量或者函数参照的值。相反地,它会逐字逐句地存储此文本值,存储变量和函数参照的值,以备之后当你参照新变量的时候进行扩展(*note The Two Flavors of Variables: Flavors)。当你对一个嵌套扩展的变量使用了+=,make 把你所指定的新的文本连接到这个目前暂时无法确定的文本之上。
variable = value
variable += more
大致相当于:
当 temp的值有定义的情况除外。当变量的旧值包含了变量参照的时候,重要性就体现出来的。
看下面的的普通例子:
CFLAGS = $(includes) -O
...
CFLAGS += -pg # enable profiling
第一行定义了包含对应一个变量 includes 的参照的变量 CFLAGS。(CFLAGS是在规则李被C编译器使用的;*note Catalogue of Implicit Rules: Catalogue of Rules.) 因为使用=,使得CFLAGS成为一个递归式调用的变量,意味着 $(includes) -O 在make 处理 对CFLAGS 定义的时候,不会被扩展。
因此,到此时,includes 还不需要被定义 ,它的值现在还没有起作用。它只需要被载CFLAGS的参照被利用之前定义就可以了。如果我们试图不使用+= 来追加值给CFLAGS,我们也许可以像这样来做:
CFLAGS := $(CFLAGS) -pg # enable profiling
Conversely, by using `+=' we set `CFLAGS' to the
_unexpanded_ value `$(includes) -O -pg'. Thus we preserve the
reference to `includes', so if that variable gets defined at any later
point, a reference like `$(CFLAGS)' still uses its value.
这已经很接近了,但不是我们就想要的东西。使用 := 重新定义 CFLAGS 为一个简单扩展变量;这意味着 make 在设置变量之前,扩展了 文本 $(CFLAGS) -pg。如果 includes 还没有定义好,我们会获得 -O -pg,而后面的对 includes 的定义就没有效果了。
后文待续