Makefile中字符串内嵌通配符目标的正确写法及精简实现
失效原因
你编写的q_% : @echo %规则达不到预期,核心原因是Make的模式通配符%仅在规则的目标、依赖声明行完成文本匹配与替换,不会自动穿透到规则下属的shell执行命令(即recipe部分)。直接在命令行中写%,Make会将这个字符原样传递给shell执行,最终只会输出一个孤立的%字符,无法匹配到目标名中的对应片段。
正确精简实现
需要在命令行中读取模式匹配结果时,要使用Make内置的自动变量$*——这个变量的取值,就是当前规则匹配时通配符%所对应的全部文本内容。
对应改写后的单条规则,即可完全替代你之前三个重复硬编码的目标:
q_%: @echo $*
其中$*的取值逻辑完全匹配原有硬编码的输出预期:比如执行make q_abc时,模式规则会匹配q_abc目标,去掉固定前缀q_后,$*的值就是abc,最终执行的命令就是@echo abc,和你逐行写的硬编码逻辑完全一致。
改写后所有原有目标的执行效果与原冗余配置完全一致:
$ make q_abc abc $ make q_def def $ make q_ghi ghi
实用补充说明
- 后续新增任意
q_前缀的构建目标,都不需要再追加重复的规则片段,直接执行make q_任意内容即可自动适配对应的echo逻辑,彻底消除冗余配置。 - 规则可以无缝扩展依赖关系:如果后续目标需要绑定同前缀的源文件,只需要在规则行追加依赖即可,比如
q_%: source/%.o就可以自动为所有q_*目标匹配对应的同前缀object文件作为依赖,不需要逐个目标写依赖声明。 - 特殊场景转义注意:如果你的Makefile片段是嵌套在Docker构建脚本、CI流水线配置这类需要多层解析的场景中编写,需要将
$*改写为$$*做双重转义,避免上层解析器提前吃掉$符号导致变量失效;纯本地编写的Makefile直接写$*即可正常工作。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

