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.mzph.cn/news/1190853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026.1.10 作业 - # P14063 [PO Final 2022] 海滩 / Badstrand

2026.1.10 作业 - # P14063 [PO Final 2022] 海滩 / Badstrand题目描述 Maja 厌倦了海岸被大湖占据,她想要修建一个又长又漂亮的公用海滩。现在,她计划买下海岸边的一块土地来建造海滩。 Maja 预算为 \(B\) 克朗。有…

AndroidStudio汉化步骤

代码视图切换按钮:

突破AI产品经理求职难关:技术认知、产品思维与落地能力三大必修课

文章介绍了AI产品经理必备的三大核心能力:技术直觉与认知边界(理解技术基础概念和边界)、AI产品感(从用户真实需求出发创造价值)、AI产品的落地与评估(具备落地经验和科学评估方法)。优秀的AI产…

基于模块化设计的可定制多领域推理系统

基于模块化设计的可定制多领域推理系统 关键词:模块化设计、可定制、多领域推理系统、推理算法、应用场景 摘要:本文围绕基于模块化设计的可定制多领域推理系统展开深入探讨。首先介绍了该系统的背景,包括目的、预期读者、文档结构和相关术语。接着阐述了核心概念与联系,给…

C++ 线程互斥锁 lock_guard

std::lock_guard是 C11 标准库提供的RAII 风格的互斥锁封装类,核心目的是自动管理互斥锁的加锁 / 解锁,从根本上避免 “忘记解锁导致死锁”“异常导致锁无法释放” 这类低级且致命的错误。一、先理解核心:RAII 设计思想lock_guard的底层是RAI…

大模型应用工程师崛起之路:从入门到年薪60万+的完整指南

本文全面解析大模型应用工程师职业,介绍其定义、职责及广阔就业前景。数据显示该岗位70.8%月薪达20K-50K,年薪24-60万。文章提供系统学习路径,包括Python入门、大模型核心原理、Transformer架构、微调技术及企业级实战项目。职业发展可走技术…

人工智能应用-机器视觉:绘画大师 04.​​​​​​​​​​​​​​基于风格迁移的绘画大师

利用深度神经网络的这种内容-风格分离能力可以实现图片的风格迁移,即将一张图片 B 的风格迁移到另一张图片 A 上。换句话说,就是希望得到一张图片,该图片在内容上与 A 一致,但在风格上与 B 一致。实现这一目标的方法如…

计算机大数据毕设实战-基于django的蔬菜销售分析与预测可视化系统蔬菜产品销售预测可视化系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

C++ 实现【精准可控】内存占用测试工具(指定内存大小,实打实占用物理内存,亲测可用)

前言在做程序性能验证、硬件资源测试、帧率影响实验(比如验证内存占用量对摄像头 / 图像处理 / 算法推理帧率的影响)时,我们经常需要人为、精准的占用指定大小的内存空间,以此模拟不同的内存负载环境。Windows 自带的内存查看工具…

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

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

解锁AI记忆新范式:人类情景记忆如何提升大模型性能

本文探讨了如何借鉴人类情景记忆机制改进记忆增强型大语言模型。当前AI记忆系统在数据使用上低效且不符合人类认知直觉。文章对比了LLM与人脑记忆系统的五大关键差异:动态更新、事件分割、选择性、时间连续性和检索竞争。通过引入类人记忆机制,不仅能让A…

人工智能应用-机器视觉:绘画大师 05.还原毕加索的隐藏画

在艺术史上,一些大画家也曾经历过艰难时刻。例如,毕加索在 1901—1904 年间经历了极度的经济困境。 为了节省开支,他不得不在已经使用过的画布上创作新作品。如图 26.7所示,通过 X 射线扫描,人们发现毕加索在这一时期…

揭秘!提示工程架构师优化提示系统用户参与策略的关键技巧

揭秘!提示工程架构师优化提示系统用户参与策略的关键技巧 一、引言:为什么你精心设计的AI系统,用户只用了一次? 上周,我朋友小A的吐槽让我印象深刻——他花了一个月搭建的AI旅游助手,上线3天用户留存率只…

【教程4>第10章>第25节】基于FPGA的图像Robert变换开发——理论分析与matlab仿真

目录 1.软件版本 2.图像Robert变换理论概述 3.图像Robert变换提取的matlab仿真测试 欢迎订阅FPGA/MATLAB/Simulink系列教程 《★教程1:matlab入门100例》 《★教程2:fpga入门100例》 《★教程3:simulink入门60例》 《★教程4:FPGA/MATLAB/Simulink联合开发入门与进阶X例》

学霸同款2026继续教育AI论文平台TOP10:毕业论文写作全测评

学霸同款2026继续教育AI论文平台TOP10:毕业论文写作全测评 2026继续教育AI论文平台测评:选对工具,提升写作效率 在当前学术环境日益严格的背景下,继续教育群体在撰写毕业论文时面临诸多挑战,如选题困难、文献检索繁琐、…

AAAI 2025论文分享|Agent4Edu:基于大语言模型生成式智能体的个性化学习模拟器

本推文介绍了AAAI 2025收录的一篇论文《Agent4Edu: Generating Learner Response Data by Generative Agents for Intelligent Education Systems》。Agent4Edu是一种基于大语言模型的个性化学习模拟器,旨在解决智能教育系统中高质量学习者响应数据稀缺、传统模拟方…

空气能十大领军品牌盘点:绿色能源时代的创新力量 - 资讯焦点

在“双碳”目标全面推进和清洁能源转型的浪潮中,空气能行业正迎来前所未有的发展机遇。作为高效、环保、可再生的能源利用方式,空气能技术已在采暖、制冷、热水等多个领域展现出强大的竞争力和市场潜力。本文盘点当前…

2025 AI大模型薪资狂欢:小白程序员入行最后黄金时机,年薪百万不是梦!非常详细建议收藏

文章分析了2025年AI大模型领域高薪就业趋势,指出供需失衡和政策支持导致AI岗位薪资暴涨,大模型算法工程师平均月薪7万。文章介绍五大高薪岗位及所需技能,提供提升竞争力的方法,并强调技术红利窗口期正在关闭,现在是入行…

Node.js代码统计神器

统计代码行数使用Node.js编写一个脚本,统计指定目录下所有文件的代码行数。const fs require(fs); const path require(path);function countLinesInFile(filePath) {const content fs.readFileSync(filePath, utf-8);return content.split(\n).length; }functio…

大数据毕设选题推荐:基于django的菜价可视化系统蔬菜销售分析与预测可视化系统【附源码、mysql、文档、调试+代码讲解+全bao等】

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…