阮一峰的网络日志 » 首页 » 档案

http://www.ruanyifeng.com/blog/developer/

http://www.ruanyifeng.com/blog/developer/

http://www.ruanyifeng.com/blog/developer/




http://www.ruanyifeng.com/blog/developer/



http://stackoverflow.com/questions/448910/makefile-variable-assignment


Can anybody give a clear explanation of how variable assignment really works in Makefiles.

What is the difference between :

 VARIABLE = value
 VARIABLE ?= value
 VARIABLE := value
 VARIABLE += value

I have read the section in GNU Make's manual, but it still doesn't make sense to me.

share improve this question
 

4 Answers

up vote 515 down vote accepted

Lazy Set

VARIABLE = value

Normal setting of a variable - values within it are recursively expanded when the variable is used, not when it's declared

Immediate Set

VARIABLE := value

Setting of a variable with simple expansion of the values inside - values within it are expanded at declaration time.

Set If Absent

VARIABLE ?= value

Setting of a variable only if it doesn't have a value

Append

VARIABLE += value

Appending the supplied value to the existing value (or setting to that value if the variable didn't exist)

share improve this answer
 
5 
Does A += B expand B? That is if if I do A += B, and then B += C, would A evaluate to concatenation of ${B} and ${C}? –  mezhaka  Feb 1 '13 at 12:46
3 
As the linked section of the manual says. += operates according to whatever simple or recursive semantics the original assignment had. So yes, it will expand the RHS but whether it does that immediately or in a deferred manner depends on the type of the variable on the LHS. –  Etan Reisner  Mar 3 '13 at 21:02
2 
What do you mean when you say variable value is expanded? –  Сашко Лихенко  Feb 20 '15 at 21:45
 
@СашкоЛихенко have a look here to get meaning of expansiongnu.org/software/make/manual/make.html#Flavors –  Umair R  Feb 25 '15 at 9:12 
1 
is "set if absent" lazy or immediate? can i "lazy set if absent" and "immediate set if abset"? –  Woodrow Barlow  Apr 1 at 14:55

Using = causes the variable to be assigned a value. If the variable already had a value, it is replaced. This value will be expanded when it is used. For example:

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)

Using := is similar to using =. However, instead of the value being expanded when it is used, it is expanded during the assignment. For example:

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

Using ?= assigns the variable a value iff the variable was not previously assigned. If the variable was previously assigned a blank value (VAR=), it is still considered set I think. Otherwise, functions exactly like =.

Using += is like using =, but instead of replacing the value, the value is appended to the current one, with a space in between. If the variable was previously set with :=, it is expanded I think. The resulting value is expanded when it is used I think. For example:

HELLO_WORLD = hello
HELLO_WORLD += world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

If something like HELLO_WORLD = $(HELLO_WORLD) world! were used, recursion would result, which would most likely end the execution of your Makefile. If A := $(A) $(B) were used, the result would not be the exact same as using += because B is expanded with := whereas += would not cause B to be expanded.

share improve this answer
 
2 
Thanks, this is a really very good explanation! –  Baiyan Huang  Dec 11 '11 at 12:01
1 
a consequence of that is therefore VARIABLE = literal and VARIABLE := literal are always equivalent. Did I get that right? –  aiao  May 3 '14 at 21:43 
 
@aiao, yes as literals are invariant to their uses –  Sebastian Godelet  May 15 '14 at 18:01
 
+1; "If the variable was previously assigned a blank value (VAR=), it is still considered set". Verifying this (make 3.82). –  jdknight  Feb 24 '15 at 15:34

When you use VARIABLE = value, if value is actually a reference to another variable, then the value is only determined when VARIABLE is used. This is best illustrated with an example:

VAL = foo
VARIABLE = $(VAL)
VAL = bar

# VARIABLE and VAL will both evaluate to "bar"

When you use VARIABLE := value, you get the value of value as it is now. For example:

VAL = foo
VARIABLE := $(VAL)
VAL = bar

# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

Using VARIABLE ?= val means that you only set the value of VARIABLE if VARIABLE is not set already. If it's not set already, the setting of the value is deferred until VARIABLE is used (as in example 1).

VARIABLE += value just appends value to VARIABLE. The actual value of value is determined as it was when it was initially set, using either = or :=.

share improve this answer
 
 
Actually, in your first example, VARIABLE is $(VAL) and VAL is bar. VARIABLE expanded when it is used. –  strager  Jan 15 '09 at 23:27
1 
Yes, the comments are explaining what would happen when they are used. –  mipadi  Jan 15 '09 at 23:28
 
Ah; I guess you corrected it, or I misread "evaluate" as "be." –  strager  Jan 15 '09 at 23:35

I suggest you do some experiments using "make". Here is a simple demo, showing the difference between = and :=.

/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later

a = foo
b = $(a) bar
a = later

test:
    echo x - $(x)
    echo y - $(y)
    echo a - $(a)
    echo b - $(b)

Now, save the file and type make test, I think that would answer your question.

Check more elaborate explanation here


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值