Makefile 学习:$ 是转义/引用符号

0 阅读1分钟

在 Makefile 中,$转义/引用符号,专门用于触发变量展开和函数调用。它本身不是运算符,而是告诉 Make:"后面的内容是变量名或函数,请替换为实际值"。

语法含义示例
$(VAR)引用变量值$(WHEREAMI)bldc/
${VAR}同上(另一种括号风格)${ROOT_DIR}
$@ $<单字符自动变量$@ = 目标名
$(func args)调用内置函数$(dir path)
$$转义为字面量 $$$VAR → 文本 $VAR

为什么需要括号?

# 无括号:只能引用单字符变量
$a          # 变量 a(单个字母)

# 有括号:引用多字符变量
$(WHEREAMI) # 变量 WHEREAMI

# 混合场景
$ab         # 歧义:变量 a 后面跟字母 b?
            # Make 解析为:$(a)b

$(ab)       # 明确:变量 ab

WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
#          ↑    ↑        ↑
#          │    │        └─ 函数调用,需要 $(
#          │    └─ 函数调用,需要 $(
#          └─ 整个表达式用 $() 包裹

$(1)_BUILD_MACROS = -DHW_SOURCE=\"$$($(1)_HW_SRC_FILE)\"
#                   ↑
#                   └─ $$ 转义:最终输出文本 $,不是变量引用
#                      用于生成 shell 命令中的字面量 $

$$ 的特殊用途

define FW_TEMPLATE
fw_$(1)_vescfw:
	@echo "Building $(1)"
	$(V1) $(MAKE) build_args='-DVAR=\"$$VALUE\"'
	#                             ↑↑
	#                             这里需要输出 $VALUE 给 shell
	#                             但 Make 会先解析一层
	#                             $$ → 保留一个 $ 给下游
endef

展开过程

Make 解析阶段:
  $$ → 替换为单个 $

最终传递给 shell 的命令:
  -DVAR="$VALUE"
  # 这里的 $VALUE 是 shell 变量,不是 Make 变量

对比其他语言

语言变量引用符号
Shell$VAR${VAR}
Makefile$(VAR)${VAR}$@
Python无符号,直接写变量名
C无符号,标识符即变量
Perl$VAR
PHP$VAR

Makefile 的 $ 设计受 Shell 影响,但强制用 () 包裹以区分多字符变量。


总结

$ = "Make,请展开后面的变量或函数"

没有 $,Make 把内容当纯文本;有 $,触发替换机制。$$ 则是"我要一个字面量的 $,留给下游程序用"。