少于 1 分钟阅读 次阅读

在 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 在追加时为空)
    

总结表

| 操作符 | 名称 | 展开时机 | 使用场景 | |——–|——————–|—————|———————————-| | = | 递归展开赋值 | 使用时展开 | 需要动态引用最新值 | | := | 立即展开赋值 | 定义时展开 | 需要固定当前值 | | ?= | 条件赋值 | 定义时检查 | 设置默认值,允许用户覆盖 | | += | 追加赋值 | 依赖原始类型 | 向列表或字符串追加内容 |

留下评论