Makefile空规则与模式匹配的疑问及规则限制需求
问题解答
一、空规则目标的处理机制及可靠性
这既不是别名,也不是什么特殊的“穿透”机制,而是GNU Make的标准隐式规则匹配逻辑:
- 当执行
make print-a时,Make首先找到显式定义的print-a目标,但这个目标没有任何命令或依赖; - 此时Make会自动尝试寻找能生成该目标的隐式/模式规则——你的
print-%规则刚好匹配print-a(%会匹配后缀a); - 匹配成功后,Make就会执行这个模式规则的命令。
这个行为是完全可靠的,属于GNU Make的规范行为。只要确保模式规则的匹配逻辑不会和其他规则冲突,就可以稳定使用。需要注意:如果显式目标有自己的命令或依赖,就不会触发隐式规则查找了——只有显式目标无命令,且(如果是文件型目标)文件不存在或过时的时候,才会触发这个逻辑。
二、限制模式规则匹配范围并保留bash补全
最直接且优雅的方式是使用静态模式规则,同时显式声明合法目标,既可以限制匹配范围,又能让bash自动补全识别合法目标:
# 定义合法的后缀列表 VALID_SUFFIXES := a b c # 显式声明所有合法目标为PHONY(避免和同名文件冲突) .PHONY: $(addprefix print-,$(VALID_SUFFIXES)) # 静态模式规则:仅匹配print-a/print-b/print-c $(addprefix print-,$(VALID_SUFFIXES)): print-%: @echo "Printing suffix: $*"
效果说明:
- 匹配限制:执行
make print-d时,Make会直接报错No rule to make target 'print-d',完全不会触发规则; - bash补全:因为显式声明了
print-a、print-b、print-c这些目标,bash的make补全脚本会自动扫描到它们——敲make print-后按Tab键,会自动补全出这三个合法目标。
如果一定要用普通模式规则(比如需要更灵活的逻辑),也可以在规则里加条件判断拦截非法后缀,同时保留显式目标用于补全:
VALID_SUFFIXES := a b c .PHONY: $(addprefix print-,$(VALID_SUFFIXES)) # 空规则仅用于让bash补全识别目标 $(addprefix print-,$(VALID_SUFFIXES)): print-%: @if [ -n "$(filter $*,$(VALID_SUFFIXES))" ]; then \ echo "Printing suffix: $*"; \ else \ echo "Error: Target print-$* is not supported" >&2; \ exit 1; \ fi
内容的提问来源于stack exchange,提问作者Kamil Dziedzic
相关产品推荐
相关产品推荐

