Gre*_*ill 62
这在GNU Make文档的标题为6.2 The Two Flavors of Variables 的部分中有描述.
简而言之,定义的变量:=
被扩展一次,但定义的变量=
在使用时会被扩展.
Amj*_*jad 46
简单赋值表达式仅在第一次出现时计算一次.例如,如果CC :=${GCC} ${FLAGS}
在第一次遭遇期间进行评估,gcc -W
那么每次${CC}
发生时都将替换为gcc -W
.
每次在代码中遇到变量时,都会计算递归赋值表达式.例如,CC = ${GCC} {FLAGS}
只有在${CC} file.c
执行类似操作时才会评估类似的语句.但是,如果GCC
重新分配
变量,GCC=c++
那么${CC}
将c++ -W
在重新分配后转换为变量.
条件赋值仅在变量没有值时才为变量赋值
假设CC = gcc
则使用追加操作像CC += -w
那么CC
现在拥有价值gcc -W
有关更多信息,请查看这些教程
对我来说,在实践中看到它的最好方法是在这个 Makefile 片段中:
XX := $(shell date) // date will be executed once
tt:
@echo $(XX)
$(shell sleep 2)
@echo $(XX)
Run Code Online (Sandbox Code Playgroud)
跑步
make tt
Run Code Online (Sandbox Code Playgroud)
将产生:
sex 22 jan 2021 14:56:08 -03
sex 22 jan 2021 14:56:08 -03
Run Code Online (Sandbox Code Playgroud)
(相同的值)
XX = $(shell date) // date will be executed every time you use XX
tt:
@echo $(XX)
$(shell sleep 2)
@echo $(XX)
Run Code Online (Sandbox Code Playgroud)
跑步
make tt
Run Code Online (Sandbox Code Playgroud)
将产生:
sex 22 jan 2021 14:56:08 -03
sex 22 jan 2021 14:58:08 -03
Run Code Online (Sandbox Code Playgroud)
不同的价值观
这是一个老问题,但这个例子可以帮助我在我忘记时理解其中的区别。
make
使用以下 Makefile运行将立即退出:
a = $(shell sleep 3)
Run Code Online (Sandbox Code Playgroud)
make
使用以下 Makefile运行将休眠 3 秒,然后退出:
a := $(shell sleep 3)
Run Code Online (Sandbox Code Playgroud)
在前一个 Makefile 中,a
只有在 Makefile 中的其他地方使用时才会对其进行求值,而在后者中,a
即使未使用它也会立即求值。