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