GNU Makefilevariables赋值=,?=,:=和+ =是什么区别?

任何人都可以清楚地说明variables赋值在Makefiles中是如何工作的。

有什么区别:

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

我已经阅读了GNU Make手册中的部分 ,但对我仍然没有意义。

懒惰的设置

 VARIABLE = value 

正常的variables设置 – 在variables被使用的时候,它的值被recursion地扩展,而不是被声明的时候

立即设置

 VARIABLE := value 

通过简单的扩展内部值来设置一个variables – 其中的值在声明时被扩展。

设置如果不存在

 VARIABLE ?= value 

只有在没有值的情况下才能设置variables

附加

 VARIABLE += value 

将提供的值附加到现有值(或者如果该variables不存在则设置为该值)

使用=会使variables被分配一个值。 如果该variables已经有一个值,它将被replace。 这个值在使用时会被扩展。 例如:

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

使用:=类似于使用= 。 但是,在使用时不是扩展的值,而是在分配过程中进行扩展。 例如:

 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) 

如果variables之前未被赋值,则使用?=赋值给variables。 如果variables先前被分配了一个空值( VAR= ),那么我认为它仍然被认为是集合。 否则,function完全像=

使用+=就像使用= ,但不是replace该值,而是将值附加到当前值之间,其间有空格。 如果variables先前设置为:= ,那么我认为它是展开的。 所得到的价值是扩大时, 我认为使用 。 例如:

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

如果像HELLO_WORLD = $(HELLO_WORLD) world! 被使用,会导致recursion,这很可能会结束你的Makefile的执行。 如果使用A := $(A) $(B) ,结果将不会与使用+=完全相同,因为B使用:=展开,而+=不会使B展开。

我build议你用“make”做一些实验。 这是一个简单的演示,显示了=:=之间的区别。

 /* 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) 

make test打印:

 x - later y - foo bar a - later b - later bar 

在这里检查更详细的解释

当您使用VARIABLE = value ,如果value实际上是对另一个variables的引用,则只有在使用VARIABLE时才会确定该值。 举一个例子来说明:

 VAL = foo VARIABLE = $(VAL) VAL = bar # VARIABLE and VAL will both evaluate to "bar" 

当您使用VARIABLE := value ,您将得到现在的值的value 。 例如:

 VAL = foo VARIABLE := $(VAL) VAL = bar # VAL will evaluate to "bar", but VARIABLE will evaluate to "foo" 

使用VARIABLE ?= val表示如果 VARIABLE尚未设置,则只设置VARIABLE的值。 如果尚未设置,则将该值的设置推迟到使用VARIABLE (如示例1中所示)。

VARIABLE += value只是将value附加到VARIABLE 。 价值的实际价值是确定为最初设置时,使用=:=

在上面的答案中, 理解 “价值在申报/使用时间扩大”是什么意思是很重要的 。 给一个像*.c这样的值不需要任何扩展。 只有当这个string被一个命令使用时,它才会触发一些通配符。 类似地,像$(wildcard *.c)$(shell ls *.c)这样的值不需要任何扩展,即使在variables定义中使用:= ,也可以在定义时间完全评估。

在你有一些C文件的目录下试试下面的Makefile:

 VAR1 = *.c VAR2 := *.c VAR3 = $(wildcard *.c) VAR4 := $(wildcard *.c) VAR5 = $(shell ls *.c) VAR6 := $(shell ls *.c) all : touch foo.c @echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1) @echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2) @echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3) @echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4) @echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5) @echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6) rm -v foo.c 

运行make会触发一个规则,创build一个额外的(空的)C文件,名为foo.c但是这6个variables中没有一个的值为foo.c