对于 Make 中的变量赋值,我看到 := 和 = 运算符。他们之间有什么区别?
6 回答
简单的分配:=
一个简单的赋值表达式只在第一次出现时计算一次。例如,如果CC :=${GCC} ${FLAGS}
在第一次遭遇期间评估为 ,gcc -W
那么每次${CC}
发生时它都会被替换为gcc -W
。
递归赋值=
每次在代码中遇到变量时都会计算递归赋值表达式。例如,CC = ${GCC} {FLAGS}
只有在执行 like 操作时才会评估语句 like ${CC} file.c
。但是,如果重新分配变量GCC
,即重新分配
GCC=c++
后将${CC}
转换为c++ -W
。
条件赋值?=
条件赋值仅在变量没有值时才为其赋值
追加+=
假设然后像
thenCC = gcc
一样使用附加运算符,现在具有值CC += -w
CC
gcc -W
有关更多信息,请查看这些教程
这在 GNU Make 文档的6.2 The Two Flavors of Variables 一节中有描述。
简而言之,用 定义的变量:=
会扩展一次,但用 定义的变量=
在使用时都会被扩展。
对我来说,在实践中查看它的最佳方式是在这个 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)
跑步
make tt
将产生:
sex 22 jan 2021 14:56:08 -03
sex 22 jan 2021 14:56:10 -03
不同的价值观
来自http://www.gnu.org/software/make/manual/make.html#Flavors:
=
定义一个递归扩展的变量。 :=
定义了一个简单扩展的变量。
这是一个老问题,但这个例子可以帮助我在忘记时理解差异。
make
使用以下 Makefile运行将立即退出:
a = $(shell sleep 3)
使用以下 Makefile运行make
会休眠 3 秒,然后退出:
a := $(shell sleep 3)
在前一个 Makefile 中,a
直到它在 Makefile 的其他地方使用才被评估,而在后者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