news 2026/2/10 13:07:02

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/7 21:37:20

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

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

作者头像 李华
网站建设 2026/2/7 22:59:56

Linux命令-kexec(从当前正在运行的内核引导到一个新内核)

kexec 是 Linux 系统中一项强大的功能,从当前正在运行的内核直接引导到一个新内核,而无需经过耗时的 BIOS/UEFI 硬件初始化过程。这在需要频繁重启(如内核开发、系统测试)或构建高可用性系统时特别有用。 ⚙️ 使用前提 在开始使用…

作者头像 李华
网站建设 2026/2/8 0:14:51

jetson orin(jetpack6.2)安装gazebo和gazebo_ros_pkgs

目前 Debian/Ubuntu 官方仅提供了基于 Amd64 架构的 Gazebo 软件包,尚未发布 Arm64 版本。因此,在 Ubuntu 22.04 系统中无法通过官方源直接获取适用于 Arm64 架构的 Gazebo 安装包。 解决办法: 1.安装gazebo (1)换源安…

作者头像 李华
网站建设 2026/2/10 10:25:24

【课程设计/毕业设计】基于Python的网络小说分析系统设计与实现【附源码、数据库、万字文档】

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

作者头像 李华