Makefile递归构建模式下仅首个目标被执行的原因及解决方案
问题原因与解决办法
这是Make的默认特性导致的——当你不指定具体目标运行make时,它只会执行顶层Makefile里第一个被定义的目标。你的原顶层Makefile中,$(test_list)展开后第一个目标是test1,所以Make只会执行这个目标对应的规则,不会自动处理后面的test2;当你调换test_list顺序时,第一个目标变成test2,自然也就只构建它了。
解决构建所有目标的问题
你只需要在顶层Makefile中添加一个all目标,把所有测试目标作为它的依赖,让all成为第一个目标即可。就像你附的修改后的版本那样:
test_list := test1 test2 .PHONY : all $(test_list) all : $(test_list) # 让all依赖所有测试目标,成为第一个目标 $(test_list): make -C build/$@ -f Makefile.inc
这样当你运行make时,Make会默认执行all目标,它会依次触发test1和test2的构建规则,两个子项目就都会被编译了。
优化clean目标的写法
你原来的clean规则需要手动列出每个可执行文件,不够灵活,其实可以递归调用每个子目录的clean目标,这样新增测试项目时不用修改顶层clean规则:
.PHONY: clean clean: @for test in $(test_list); do \ make -C build/$$test -f Makefile.inc clean; \ done
这样会遍历所有测试项目,调用各自build/$test目录下的clean规则,自动清理对应的.o文件和可执行文件,比手动写路径更简洁可靠。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

