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

来源:互联网 发布:h5开心农场源码 编辑:程序博客网 时间:2024/05/15 10:30

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.

shareimprove this question
 

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
 
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
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 = worldHELLO_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 = worldHELLO_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 = helloHELLO_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
 
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
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 = fooVARIABLE = $(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 = fooVARIABLE := $(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
 
 
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
up vote15down vote

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

/* Filename: Makefile*/x := fooy := $(x) barx := latera = foob = $(a) bara = latertest:    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
原创粉丝点击