Answers:
VARIABLE = value
变量的常规设置,但在value
字段中提及的任何其他变量都将在使用该变量的位置递归扩展其值,而不是声明该变量时的值
VARIABLE := value
使用内部值的简单扩展设置变量-声明时扩展其中的值。
VARIABLE ?= value
仅在没有值的情况下设置变量。value
总是在VARIABLE
访问时评估。相当于
ifeq ($(origin FOO), undefined)
FOO = bar
endif
有关更多详细信息,请参见文档。
VARIABLE += value
将提供的值附加到现有值(如果变量不存在,则设置为该值)
使用=
将为变量分配一个值。如果变量已经具有值,则将其替换。使用时将扩展该值。例如:
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)
使用?=
会为变量分配一个值,前提是该变量先前未分配。如果该变量先前分配了一个空白值(VAR=
),我认为仍将其视为set 。否则,功能与完全相同=
。
使用+=
就像使用一样=
,但是代替替换值,该值被附加到当前值后,中间有一个空格。我认为:=
,如果该变量先前已设置,则将其扩展。我认为,使用它时,结果值会扩展。例如:
HELLO_WORLD = hello
HELLO_WORLD += world!
# This echoes "hello world!"
echo $(HELLO_WORLD)
如果使用了类似的东西HELLO_WORLD = $(HELLO_WORLD) world!
,则将导致递归,这很可能会终止Makefile的执行。如果A := $(A) $(B)
使用了,其结果不会是完全一样的使用+=
,因为B
与扩大:=
,而+=
不会造成B
被扩大。
VARIABLE = literal
并且VARIABLE := literal
始终是等效的。我说对了吗?
我建议您使用“ 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
@
在每个配方前都使用a ,以免造成结果重复。
/* ... */
阻止评论
当使用时VARIABLE = value
,如果value
实际上是对另一个变量的引用,则仅在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
if 的值VARIABLE
(尚未设置)。如果尚未设置,则将值的设置推迟到VARIABLE
使用为止(如示例1中所示)。
VARIABLE += value
只是附加value
到VARIABLE
。value
使用=
或来确定初始设置时的实际值:=
。
在以上答案中,重要的是要了解 “在声明/使用时扩展值”的含义。给一个像*.c
并不需要任何扩展。仅当命令使用此字符串时,它才可能触发一些glob。类似地,即使我们在变量定义中使用过,类似$(wildcard *.c)
或的值$(shell ls *.c)
也不需要任何扩展,并且在定义时会完全求:=
值。
在有一些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
将触发一个规则,该规则将创建一个额外的(空)C文件,foo.c
该文件被调用,但6个变量中的任何一个都不具有foo.c
其值。