146

对于 Make 中的变量赋值,我看到 := 和 = 运算符。他们之间有什么区别?

4

6 回答 6

114

简单的分配:=

一个简单的赋值表达式只在第一次出现时计算一次。例如,如果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
CCgcc -W

有关更多信息,请查看这些教程

于 2017-11-22T16:29:15.180 回答
109

这在 GNU Make 文档的6.2 The Two Flavors of Variables 一节中有描述。

简而言之,用 定义的变量:=会扩展一次,但用 定义的变量=在使用时都会被扩展。

于 2011-02-02T20:40:24.497 回答
20

对我来说,在实践中查看它的最佳方式是在这个 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

不同的价值观

于 2021-01-22T18:20:48.417 回答
12

来自http://www.gnu.org/software/make/manual/make.html#Flavors

=定义一个递归扩展的变量。 :=定义了一个简单扩展的变量。

于 2011-02-02T20:40:15.080 回答
1

这是一个老问题,但这个例子可以帮助我在忘记时理解差异。

make使用以下 Makefile运行将立即退出:

a = $(shell sleep 3)

使用以下 Makefile运行make会休眠 3 秒,然后退出:

a := $(shell sleep 3)

在前一个 Makefile 中,a直到它在 Makefile 的其他地方使用才被评估,而在后者a中,即使它没有被使用,也会立即被评估。

于 2021-04-04T17:22:19.633 回答
0

递归赋值=在每次使用时都会被评估,但不是按照在配方命令中遇到的顺序,而是运行任何配方命令之前。

基于以下示例:

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
于 2022-02-17T00:04:57.713 回答