Makefile模式规则链式调用失效问题求助
解决Makefile模式规则无法匹配的问题
你的简化Makefile代码如下:
.PHONY: FORCE FORCE: a-%-b: FORCE @echo 'a-$*-b' c-%-d: a-%-b
执行make a-test-b可正常输出a-test-b,但执行make c-test-d时出现报错:
make: *** No rule to make target `c-test-d'. Stop.
对比另一段可行的Makefile代码:
%.txt1: touch $*.txt1 %.txt2: %.txt1 cp $< $@
执行make test.txt2能正常先创建test.txt1再复制为test.txt2。
问题原因
两段代码的核心区别在于:带命令的模式规则才是有效的生成规则。
在你的第一段代码中,c-%-d: a-%-b没有定义任何执行命令,Make会将其视为单纯的依赖声明,而非能生成目标c-%-d的规则。当Make尝试构建c-test-d时,找不到任何可以生成该目标的实际规则,因此报错。
而对比的代码中,%.txt2: %.txt1后面带有cp $< $@命令,是完整的生成规则,Make可以通过这个规则来生成目标文件。
解决方案
给c-%-d模式规则添加执行命令即可,哪怕是一个无意义的空操作命令,比如@true:
.PHONY: FORCE FORCE: a-%-b: FORCE @echo 'a-$*-b' c-%-d: a-%-b @true # 空操作命令,仅用于让Make识别这是一个有效生成规则
执行make c-test-d时,Make会先构建依赖a-test-b(输出a-test-b),然后执行@true,最终完成构建。
如果需要c-%-d本身输出内容,也可以添加对应的echo命令:
.PHONY: FORCE FORCE: a-%-b: FORCE @echo 'a-$*-b' c-%-d: a-%-b @echo 'c-$*-d'
这样执行make c-test-d会依次输出a-test-b和c-test-d。
补充说明
如果你的需求仅仅是通过c-%-d触发a-%-b的执行,也可以通过其他方式关联,但最直接可靠的方式还是确保模式规则带有明确的命令,让Make识别其为有效生成规则。
内容的提问来源于stack exchange,提问作者Egor Tensin
相关产品推荐
相关产品推荐

