Makefile 中的 := 和 = 有啥区别?
Posted
技术标签:
【中文标题】Makefile 中的 := 和 = 有啥区别?【英文标题】:What's the difference between := and = in Makefile?Makefile 中的 := 和 = 有什么区别? 【发布时间】:2011-06-20 06:12:07 【问题描述】:对于 Make 中的变量赋值,我看到 := 和 = 运算符。他们之间有什么区别?
【问题讨论】:
Makefile variable assignment 的可能重复项 What is the difference between the GNU Makefile variable assignments =, ?=, := and +=?的可能重复 【参考方案1】:对我来说,在实践中查看它的最佳方式是在这个 Makefile sn-p 期间:
简单赋值
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
不同的值
【讨论】:
【参考方案2】:这是一个老问题,但这个例子可以帮助我在忘记时理解差异。
使用以下 Makefile 运行 make
将立即退出:
a = $(shell sleep 3)
使用以下 Makefile 运行 make
会休眠 3 秒,然后退出:
a := $(shell sleep 3)
在前一个 Makefile 中,a
直到它在 Makefile 的其他地方使用才被评估,而在后者中,a
即使没有被使用也会立即被评估。
【讨论】:
【参考方案3】:简单赋值:=
一个简单的赋值表达式只计算一次,在第一次出现时。
例如,如果在第一次相遇期间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
更多信息请查看tutorials
【讨论】:
“一个简单的赋值表达式在第一次出现时只计算一次”:明确地说,扩展/计算是在定义变量时完成的,而不是第一次使用它。 【参考方案4】:这在 GNU Make 文档的标题为 6.2 The Two Flavors of Variables 的部分中有描述。
简而言之,用:=
定义的变量会展开一次,而用=
定义的变量会在每次使用时展开。
【讨论】:
那么说 := 更有效对吗?或者效率不是 Makefile 的真正因素? @Ungeheuer 这不是问题,因为进程调用(make
的主要工作)比这种内部变量解析的开销要大得多。【参考方案5】:
来自http://www.gnu.org/software/make/manual/make.html#Flavors:
=
定义了一个递归扩展的变量。 :=
定义了一个简单扩展的变量。
【讨论】:
以上是关于Makefile 中的 := 和 = 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Makefile 中的括号 $() 和大括号 $ 语法有啥区别?
Makefile 中的 $(objs): %.o : %.cpp 和 $(objs): $(objs:.o=.cpp) 有啥区别