news 2026/2/2 5:55:30

Makefile中 =、:=和 ?=的使用方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Makefile中 =、:=和 ?=的使用方法

理解Makefile中=:=?=这三个赋值操作符的区别,对编写可靠高效的构建脚本至关重要。下面这个表格能帮你快速把握它们的核心差异。

特性

=(递归扩展赋值)

:=(简单扩展赋值)

?=(条件赋值)

赋值时机

变量被使用(引用)时才展开求值

变量定义时就立即展开求值

仅当变量此前未定义过时才进行赋值

值是否可变

是,最终值取决于引用时所有相关变量的最终值

否,定义后值就固定不变

取决于首次赋值使用的操作符

展开方式

递归展开,可引用后定义的变量

直接展开,只能引用前面已定义的变量

行为取决于使用的是=还是:=

性能特点

每次引用都可能重新展开,开销较大

仅展开一次,性能较好

-

💡 如何选择赋值操作符

了解区别后,关键在于知道何时使用它们。

  • 优先使用:=

    大多数情况下推荐使用:=。它能产生可预测的行为,且因为只计算一次,性能更好。特别适合定义:

    • 工具链路径CC := gcc

    • 目录路径SRC_DIR := src

    • 通过函数生成的文件列表SOURCES := $(wildcard $(SRC_DIR)/*.c)(避免重复执行wildcard

  • 谨慎使用=

    使用=可能导致变量的值不确定,因为它会引用最终值而非当前值。它适用于需要动态计算的场景,但使用时务必确保清楚变量之间的依赖关系。

  • 适时使用?=

    ?=主要用于在Makefile中提供可被覆盖的默认值。例如,你可以为编译器设置一个默认值,但允许用户在命令行覆盖它:

    CC ?= gcc # 用户可以通过 `make CC=clang` 来覆盖默认值

🧪 通过示例加深理解

看几个例子,直观感受它们的区别。

示例1:基本赋值与引用

# 递归扩展赋值 (=) x = foo y = $(x) bar # 此时y的值尚未确定,它记录的是"$(x) bar"这个表达式 x = later # 简单扩展赋值 (:=) a := foo b := $(a) bar # 此时b的值立即确定为"foo bar" a := later test: @echo "y (using =) -> $(y)" # 输出: y (using =) -> later bar @echo "b (using :=) -> $(b)" # 输出: b (using :=) -> foo bar

y的值在echo命令执行时才最终确定,使用的是x的最终值later。而b在定义时就已经固定为foo bar,之后a的变化与它无关。

示例2:条件赋值的生效场景

# 场景1:变量从未被定义 SOME_VAR ?= default_value # 场景2:变量已被定义(即使值为空,也算已定义) ANOTHER_VAR = # 空值也是已定义 ANOTHER_VAR ?= this_will_be_ignored demo: @echo "SOME_VAR: $(SOME_VAR)" # 输出: SOME_VAR: default_value @echo "ANOTHER_VAR: $(ANOTHER_VAR)" # 输出: ANOTHER_VAR: (空)

?=仅在变量完全未定义时起作用。如果变量被定义过,即使其值为空,?=赋值也会被忽略。

💎 简单总结

记住这三个操作符的核心特征:

  • :=​ 是"立即兑现"​ ,定义时值就固定了。

  • =​ 是"打白条"​ ,值在使用时才确定,可能变化。

  • ?=​ 是"设置默认"​ ,只有当变量从未被设置过时才生效。

一个实用的法则是:当不确定时,优先使用:=;需要设置可被覆盖的默认值时,使用?=​ 。

希望这些解释和示例能帮助你更自信地在Makefile中使用这些赋值操作符。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/1 11:48:16

《把脉行业与技术趋势》-69-股票的周期、产品的周期、企业的周期的相似性与不同,以及它们各自在不同阶段关注的重点和核心要素不同

这是一个极具战略价值的问题。股票、产品、企业三者虽相互嵌套、彼此影响,但它们的周期逻辑、驱动因素和阶段重心存在显著差异。理解其相似性与不同点,并掌握各阶段的核心关注要素,是投资者、创业者和管理者做出正确决策的关键。一、三者的本…

作者头像 李华
网站建设 2026/1/29 21:23:28

typescript-类的静态属性和静态方法

我们上一节看到了类,里面都是类的实例属性和实例方法,即需要实例化后才可以进行访问的。什么是静态属性和静态方法?静态属性和静态方法是不需要实例化就可以访问的属性和方法(不需要实例化是指不需要new来生成对象)。还是以上一节的Person类举…

作者头像 李华
网站建设 2026/1/30 18:37:03

八段锦练习注意要点

八段锦是中国古代流传下来的一套气功功法,以八个精心编排的动作著称。它不仅能活动筋骨,长期坚持还能调理脏腑功能,改善整体的身心状态。 以肢体运动为主要特点的导引健身养生术它通过肢体运动强壮筋骨,疏通经络,调和气…

作者头像 李华
网站建设 2026/1/30 1:39:51

学霸同款8个AI论文网站,本科生搞定毕业论文!

学霸同款8个AI论文网站,本科生搞定毕业论文! 论文写作的“学霸同款”神器,你真的不能错过 对于大多数本科生来说,撰写毕业论文是一段既紧张又充满挑战的过程。从选题到开题,再到撰写和降重,每一个环节都需要…

作者头像 李华