Makefile中有什么区别:=和=?

pro*_*eek 78 makefile gnu-make colon-equals

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

Gre*_*ill 62

这在GNU Make文档的标题为6.2 The Two Flavors of Variables 的部分中有描述.

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

  • 那么说:=更有效率是否正确?或者效率不是真正的Makefiles因素? (3认同)
  • @Ungeheuer 这不是问题,因为进程调用(`make` 的主要工作)的开销比这种内部变量解析要大得多。 (3认同)

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

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

  • “简单的赋值表达式仅在第一次出现时计算一次”:需要明确的是,扩展/计算是在定义变量时完成的,而不是第一次使用它时完成的。 (2认同)

Oli*_*rth 11

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

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


Edg*_*eal 8

对我来说,在实践中看到它的最好方法是在这个 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)

不同的价值观


And*_*pov 6

这是一个老问题,但这个例子可以帮助我在我忘记时理解其中的区别。

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即使未使用它也会立即求值。