为何GNU Make中自动变量$^为空?PREREQ已正确设置
问题背景与现象
使用场景
多个Makefile共享部分逻辑,但先决条件差异明显,因此引入Common.mk统一管理公共逻辑,通过PREREQ变量为不同Makefile指定专属先决条件。
问题现象
$(PREREQ)能正确输出设定值,但自动变量$^却为空,不符合预期。
复现步骤
Common.mk内容
all: $(PREREQ) echo $^ echo $(PREREQ) A B:
Makefile内容
include Common.mk PREREQ ?= A
执行结果
执行make命令后输出:
echo echo A A
但调换Makefile中两行顺序,或执行make PREREQ=B时,$^能正常输出对应值。使用GNU Make 4.3版本。
原因分析
这是GNU Make的解析顺序规则直接导致的:
- Makefile是从上到下逐行解析执行的,当执行
include Common.mk时,PREREQ变量还未被定义(PREREQ ?= A写在include之后),此时解析all: $(PREREQ)时,$(PREREQ)是空值,all目标的先决条件被设置为空。 - 虽然后续
PREREQ被赋值为A,但Make不会回溯重新解析已经处理过的规则,因此all目标的先决条件始终为空,自动变量$^(代表目标的所有先决条件集合)自然也为空。
特殊情况生效的原因
- 调换Makefile行顺序:先执行
PREREQ ?= A,PREREQ已有值,再includeCommon.mk时,解析all: $(PREREQ)能正确将A作为先决条件,$^也就有了对应值。 - 命令行传参
PREREQ=B:命令行传入的变量属于全局变量,优先级高于Makefile内部赋值,在Make启动初始化阶段就已设置完成,includeCommon.mk时PREREQ已有值,规则解析自然正确。
内容的提问来源于stack exchange,提问作者mrjoops
相关产品推荐
相关产品推荐

