Makefile 中的 := 和 = 有什么区别?
对于 Make 中的变量赋值,我看到 := 和 = 运算符。他们之间有什么区别?
For variable assignment in Make, I see := and = operator. What's the difference between them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
简单赋值
:=
简单赋值表达式仅在第一次出现时计算一次。
例如,如果在第一次遇到时
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
有关更多信息,请查看这些 教程
Simple assignment
:=
A simple assignment expression is evaluated only once, at the very first occurrence.
For example, if
CC :=${GCC} ${FLAGS}
during the first encounter is evaluated togcc -W
theneach time
${CC}
occurs it will be replaced withgcc -W
.Recursive assignment
=
A Recursive assignment expression is evaluated everytime the variable is encountered
in the code. For example, a statement like
CC = ${GCC} {FLAGS}
will be evaluated only whenan action like
${CC} file.c
is executed. However, if the variableGCC
is reassigned i.eGCC=c++
then the${CC}
will be converted toc++ -W
after the reassignment.Conditional assignment
?=
Conditional assignment assigns a value to a variable only if it does not have a value
Appending
+=
Assume that
CC = gcc
then the appending operator is used likeCC += -w
then
CC
now has the valuegcc -W
For more check out these tutorials
GNU Make 文档中标题为 6.2 的部分对此进行了描述变量的两种风格
。
简而言之,用
:=
定义的变量会扩展一次,但用=
定义的变量每次使用时都会扩展。This is described in the GNU Make documentation, in the section titled 6.2 The Two Flavors of Variables
.
In short, variables defined with
:=
are expanded once, but variables defined with=
are expanded whenever they are used.对我来说,在实践中看到它的最好方法是在这个 Makefile 片段中:
简单赋值
运行
将产生:(
相同值)
扩展赋值
运行
将产生:
不同值
For me, the best way to see it in practice is during this Makefile snippet:
Simple assignment
Running
Will produce:
( Same value )
Expanded assignment
Running
Will produce:
Different values
来自 http://www.gnu.org/software/make/manual/ make.html#Flavors:
=
定义递归扩展变量。:=
定义简单扩展变量。From http://www.gnu.org/software/make/manual/make.html#Flavors:
=
defines a recursively-expanded variable.:=
defines a simply-expanded variable.这是一个老问题,但这个例子可以帮助我在我忘记时理解其中的区别。
使用以下 Makefile 运行
make
将立即退出:使用以下 Makefile 运行
make
将休眠 3 秒,然后退出:在前一个 Makefile 中,
a< /code> 直到在 Makefile 中的其他地方使用时才被评估,而在后者中,即使没有使用,也会立即评估
a
。This is an old question but this example helps me understand the difference whenever I forget.
Running
make
with the following Makefile will instantly exit:Running
make
with the following Makefile will sleep for 3 seconds, and then exit:In the former Makefile,
a
is not evaluated until it's used elsewhere in the Makefile, while in the lattera
is evaluated immediately even though it's not used.递归赋值
=
每次使用时都会进行评估,但不是按照在配方命令中遇到它的顺序,而是在运行任何配方命令之前进行评估。基于以下示例:
输出:
Recursive assignment
=
is evaluated everytime it is used, but not in the order of when it is encountered among the recipe commands, but rather before running any recipe command.Based on the following example:
Outputs:
=
称为递归扩展变量或惰性扩展变量。在下面的示例中,当 make 读取此行时,仅将右侧 VAR1 中的值存储到左侧 VAR1 中,而不进行扩展。当 make 尝试读取左侧定义的 $(VAR1) 时。这是不断重复并导致无限循环
输出:
:=
称为扩展变量或在 make 读取此行时即时,右侧的变量被扩展并将结果值保存到左侧手边。请参阅下面的程序输出
输出:
编辑:
已经有很好的答案了。我在 Udemy 的 make 培训课程上偶然发现了这个概念,并给出了很好的例子。
=
called recursive expanded variable or lazy expanded variable. in below example, when make read this linemake just stored value from righthand side VAR1 into lefthand side VAR1 without expanding. When make tried to read $(VAR1) which is defined on left hand side. this is keep repeating and result into infinite loop
Output:
:=
called expanded variable or instantwhen make read this line, variable on righthand side are expnaded and saved resulting value into left hand side. please see below program output
Output:
EDIT:
There are already good answer. I came across about this concept on Udemy training course of make with good example.