对于 Make 中的变量赋值,我看到: = 和 = 操作符。它们之间的区别是什么?
来自 http://www.gnu.org/software/make/manual/make.html#Flavors:
=定义一个递归展开的变量。 :=定义一个简单展开的变量。
=
:=
这在 GNU Make 文档中有描述,在标题为 < a href = “ http://www.GNU.org/software/Make/hand/html _ node/Flavors.html # Flavor”rel = “ noReferrer”> 6.2 The Two Flavor of Variables 的章节中有描述 .
简而言之,用 :=定义的变量可以展开一次,但是用 =定义的变量只要使用就可以展开。
一个简单的赋值表达式只在第一次出现时求值一次。 例如,如果在第一次遭遇时 CC :=${GCC} ${FLAGS}被评估为 gcc -W,那么 每次 ${CC}发生它将被取代与 gcc -W。
CC :=${GCC} ${FLAGS}
gcc -W
${CC}
每次遇到变量时都计算递归赋值表达式 例如,像 CC = ${GCC} {FLAGS}这样的语句只有在 执行类似于 ${CC} file.c的操作 GCC=c++然后 ${CC}将被转换为 c++ -W后,重新分配。
CC = ${GCC} {FLAGS}
${CC} file.c
GCC=c++
c++ -W
?=
条件赋值只有在变量没有值时才给它赋值
+=
假设使用 CC = gcc,然后使用附加运算符,就像使用 CC += -w一样 那么 CC现在的值就是 gcc -W
CC = gcc
CC += -w
CC
想了解更多,请看这些 教程
对我来说,在实践中看到它的最佳方式是在这个 Makefile 片段中:
XX := $(shell date) // date will be executed once tt: @echo $(XX) $(shell sleep 2) @echo $(XX)
跑步
make tt
将产生:
sex 22 jan 2021 14:56:08 -03 sex 22 jan 2021 14:56:08 -03
(一样值)
XX = $(shell date) // date will be executed every time you use XX tt: @echo $(XX) $(shell sleep 2) @echo $(XX)
sex 22 jan 2021 14:56:08 -03 sex 22 jan 2021 14:56:10 -03
不同的 值
这是一个古老的问题,但是这个例子可以帮助我理解当我忘记的时候的区别。
使用以下 Makefile 运行 make将立即退出:
make
a = $(shell sleep 3)
在以下 Makefile 模式下运行 make将睡眠3秒钟,然后退出:
a := $(shell sleep 3)
在前一种生成文件中,在 Makefile 其他地方使用之前,不会对 a进行评估,而在后一种文件中,即使没有使用,也会立即对 a进行评估。
a
每次使用递归赋值 =时,都会计算它,但不是按照在菜谱命令中遇到它的顺序,而是按照运行任何菜谱命令的 之前顺序。
基于以下例子:
default: target1 target2 target1 target2: @echo "Running at: `gdate +%s.%N`" @echo "Simple assignment: $(SIMPLE_ASSIGNMENT)" @echo "Recursive assignment: $(RECURSIVE_ASSIGNMENT)" sleep 1 @echo "Running at: `gdate +%s.%N`" @echo "Simple assignment: $(SIMPLE_ASSIGNMENT)" @echo "Recursive assignment: $(RECURSIVE_ASSIGNMENT)" @echo SIMPLE_ASSIGNMENT := $(shell gdate +%s.%N) RECURSIVE_ASSIGNMENT = $(shell gdate +%s.%N)
产出:
❯ make Running at: 1645056840.980488000 Simple assignment: 1645056840.949181000 Recursive assignment: 1645056840.958590000 sleep 1 Running at: 1645056842.008998000 Simple assignment: 1645056840.949181000 Recursive assignment: 1645056840.969616000 Running at: 1645056842.047367000 Simple assignment: 1645056840.949181000 Recursive assignment: 1645056842.027600000 sleep 1 Running at: 1645056843.076696000 Simple assignment: 1645056840.949181000 Recursive assignment: 1645056842.035901000