读懂和编写Makefile需掌握的关键基础知识(常用符号、先解析再执行、make命令的第一个动作、规则的概念、目标及伪目标的相关概念、文件更新机制、几个重要的自动化变量等知识)

01-符号=、符号:=、符号+=

区分符号=和符号:=

Makefile 中,符号 :== 都用于定义变量,但它们的行为方式不同,主要体现在变量值的计算和展开时机上。


1. :=(简单赋值,立即展开)

  • 特点:使用 := 定义的变量会在赋值时立即计算和展开右边的值,然后将结果赋给变量。
  • 用途:当变量的值在定义时已经确定,并且不会再依赖于其他变量的值发生变化时,适合使用 :=

示例

FOO := $(BAR)
BAR := hello
  • 这里 FOO 的值在定义时就会被计算。当 FOO := $(BAR) 被执行时,BAR 的值(hello)被立即展开并赋值给 FOO
  • 最终结果:FOO = hello

2. =(递归赋值,延迟展开)

  • 特点:使用 = 定义的变量不会立即计算右边的值,而是延迟到变量被引用时才计算和展开右边的内容。
  • 用途:当变量的值可能依赖于其他变量的值发生变化时,适合使用 =

示例

FOO = $(BAR)
BAR = hello
  • 这里 FOO 的值在定义时不会被计算,而是保留 $(BAR) 作为变量的值。
  • FOO 被引用时,BAR 的值才会被计算并展开。
  • 最终结果:FOO = hello

3. 两者的区别总结

符号 行为 展开时机 典型用途
:= 简单赋值,立即计算和展开 定义时展开 值已确定、不依赖其他变量的情况
= 递归赋值,保留引用,延迟展开 使用时展开 依赖于其他变量或需要动态计算的情况

4. 对比示例

BAR = hello
FOO = $(BAR)
BAZ := $(BAR)
BAR = world

all:
    @echo FOO = $(FOO)
    @echo BAZ = $(BAZ)
  • 结果
    FOO = world
    BAZ = hello
    

解释

  • FOO 使用了 = 定义,它延迟展开,因此 FOO 的值在 BAR 被重新赋值后变成 world
  • BAZ 使用了 := 定义,它在赋值时立即展开 BAR 的值,因此固定为 hello

5. 性能方面的考虑

  • := 性能更高:由于变量值在定义时已展开,后续使用时无需再进行计算。
  • = 更灵活:允许变量的值依赖其他变量动态变化。

总结建议

  • 使用 :=:如果变量的值是固定的,或在定义时已确定,可以使用 := 提高效率和简洁性。
  • 使用 =:如果变量的值需要动态变化,或依赖于其他变量的值,使用 = 提供更多的灵活性。

根据具体需求选择适当的赋值方式,可以编写更高效、清晰的 Makefile

符号+=

符号+=为追加赋值,变量的值会被追加到现有的值后面。
比如:

FOO := hello
FOO += world

上面这条两条语句使得变量FOO的值为 hello world

02-需要知道的几个基本常识

02-1-Makefile文件并不是顺序执行,而是先解析再执行

关于这一点的最直接的例子就是伪目标的定义和声明语句:

PHONY := __build
......
......
......
.PHONY : $(PHONY)

变量PHONY用于存储Makefile中的所有伪目标名,但是直到文Makefile的最后一行才对存储在变量PHONY中的所有伪目标名进行声明,但是中间的语句会用到这些伪目标名,这就充分证明了Makefile文件并不是顺序执行,而是先解析再执行。
关于伪目标的详细解释,请看本文第03点的第2小点的第⑵点。

02-2-make命令执行时到底是执行哪个Makefile文件

如果make命令是下面这种形式:

make 目标名

那么make就会进入当前目录查找名为Makefile的文件开始执行构建。

如果make命令是下面这种形式:

make -C<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值