当前位置: 首页 > news >正文

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中使用这些赋值操作符。

http://www.jsqmd.com/news/275088/

相关文章:

  • 生成式软件制造--AI驱动的软件开发 - 教程
  • C++ 线程互斥锁 lock_guard
  • 大模型应用工程师崛起之路:从入门到年薪60万+的完整指南
  • 人工智能应用-机器视觉:绘画大师 04.​​​​​​​​​​​​​​基于风格迁移的绘画大师
  • C++ 实现【精准可控】内存占用测试工具(指定内存大小,实打实占用物理内存,亲测可用)
  • typescript-类的静态属性和静态方法
  • 解锁AI记忆新范式:人类情景记忆如何提升大模型性能
  • 人工智能应用-机器视觉:绘画大师 05.还原毕加索的隐藏画
  • 揭秘!提示工程架构师优化提示系统用户参与策略的关键技巧
  • 【教程4>第10章>第25节】基于FPGA的图像Robert变换开发——理论分析与matlab仿真
  • AAAI 2025论文分享|Agent4Edu:基于大语言模型生成式智能体的个性化学习模拟器
  • Node.js代码统计神器
  • 存储技术全解:从基础到前沿
  • 存储技术全解:从基础到前沿
  • 基于广义Benders分解法的综合能源系统优化规划Matlab代码
  • SCADA与数字孪生(Digital Twin)系统的异同点在哪里?
  • 基于多目标粒子群算法冷热电联供综合能源系统运行优化Matlab实现
  • 洛谷 P10962:Computer ← 换根DP
  • SCADA与数字孪生(Digital Twin)系统的异同点在哪里?
  • AI狂飙与冷思考:一个准码农的2026开年观察
  • 完整教程:人机交互(如 VR 手柄追踪、光标移动、手势识别)的滤波算法
  • 【读书笔记】《稻盛和夫自传》
  • 《把脉行业与技术趋势》-65-当你的人生轨迹与民族复兴的长波、技术革命的中波、行业爆发的短波同频共振时,平凡的努力,也会被时代放大成非凡的成就——这,便是“着道”的现代诠释。
  • AI生成SQL的安全风险与测试框架
  • 线段树合并
  • 454. 四数相加 II-day06
  • 《把脉行业与技术趋势》-69-股票的周期、产品的周期、企业的周期的相似性与不同,以及它们各自在不同阶段关注的重点和核心要素不同
  • 大数据毕设选题推荐:基于大数据技术的Django框架下的学习资源推送系统的设计与实现基于Django+大数据的学习资源推送系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 若思中国发布2026年十大最具影响力战略咨询大师推荐榜 - 资讯焦点
  • 大模型测试的“评估指标”:BLEU?ROUGE?都不够!