您的位置:首页 > 理论基础 > 计算机网络

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

2016-06-27 14:34 701 查看
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


Makefile
variable assignment

up
vote392down
votefavorite
191

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.

makefile gnu-make
shareimprove
this question
edited Feb
25 '14 at 6:21





Tshepang
4,419105698

asked Jan 15 '09 at 23:19





mmoris
2,36831110

 add
a comment


4 Answers

activeoldestvotes

up vote515down
voteaccepted


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)

shareimprove
this answer
edited Aug
25 '15 at 15:04





Eric
3,35131732

answered Jan 15 '09 at 23:25





Alnitak
205k41263340

 
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
add
a comment





up vote146down
vote
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.

shareimprove
this answer
edited Jan
15 '09 at 23:40

answered Jan 15 '09 at 23:34





strager
56.8k1297148

 
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
add
a comment
up vote19down
vote
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 
:=
.

shareimprove
this answer
answered Jan 15 '09 at 23:26





mipadi
203k46370393

 
 
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
add
a comment
up vote15down
vote
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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: