makefile 中不同等号的区别
在 Makefile 中,不同的赋值操作符(=, :=, ?=, +=)具有不同的行为和用途。本文介绍它们的区别。
1. 递归展开赋值(=)
- 行为:变量的值在使用时才会展开(延迟展开),引用的是变量最终的值。
- 特点:若变量在后续被重新赋值,新值会影响当前变量的值。
- 示例:
A = 1 B = $(A) # B 的值在引用时确定 A = 2 all: @echo $(B) # 输出 2(引用了最新的 A)
2. 立即展开赋值(:=)
- 行为:变量的值在定义时立即展开,后续的变量修改不会影响已定义的值。
- 特点:适用于需要固定当前值的场景。
- 示例:
A := 1 B := $(A) # B 的值立即展开为 1 A := 2 all: @echo $(B) # 输出 1(B 的值已固定)
3. 条件赋值(?=)
- 行为:仅当变量未定义时赋值,否则保留原值。
- 特点:用于设置默认值,允许用户覆盖。
- 示例:
C ?= default # 如果 C 未定义,则赋值为 "default" all: @echo $(C) # 输出 default(若用户未定义 C)
4. 追加赋值(+=)
- 行为:向变量追加值,追加方式取决于变量的原始类型:
- 若变量由
=定义,追加的值会延迟展开。 - 若变量由
:=定义,追加的值会立即展开。
- 若变量由
- 示例:
# 示例 1:使用 `=` VAR = one VAR += $(TWO) # TWO 后续定义,会被展开 TWO = 2 all: @echo $(VAR) # 输出 "one 2" # 示例 2:使用 `:=` VAR := one VAR += $(TWO) # TWO 此时未定义,展开为空 TWO := 2 all: @echo $(VAR) # 输出 "one "(TWO 在追加时为空)
总结表
| 操作符 | 名称 | 展开时机 | 使用场景 |
|——–|——————–|—————|———————————-|
| = | 递归展开赋值 | 使用时展开 | 需要动态引用最新值 |
| := | 立即展开赋值 | 定义时展开 | 需要固定当前值 |
| ?= | 条件赋值 | 定义时检查 | 设置默认值,允许用户覆盖 |
| += | 追加赋值 | 依赖原始类型 | 向列表或字符串追加内容 |
留下评论