You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写适用于所有子文件夹的Makefile规则?

多同结构子目录的Makefile构建解决方案

目录结构

tests
|- test1
   |- file1
   |- file2
|- test2
   |- file1
   |- file2

需求

编写Makefile规则,同时处理test1、test2等子目录,生成的my_program目标文件与依赖的file1、file2处于相同子目录中。

错误尝试及问题分析

尝试1:模式规则报错

TESTS = test1 test2
.PHONY : all
all: $(addsuffix /my_program, $(TESTS))

%/my_program : %/file1 %/file2
   clang $< -o $@

错误信息:

No rule to make target `AddStruct/my_program', needed by `all'.  Stop.

问题:若报错中出现AddStruct,大概率是TESTS变量包含了不存在的目录;另外命令中使用$<仅会传入第一个依赖文件,编译会遗漏file2。

尝试2:通配符规则导致冗余编译

*/my_program : */file1 */file2
   clang $< -o $@

问题:Make会将所有*/file1和*/file2作为依赖,生成所有可能的组合编译命令(如用test2的文件编译test1的目标),不符合需求。

尝试3:依赖列表使用自动化变量报错

*/my_program : $(@D)/file1 $(@D)/file2
   clang $< -o $@

错误信息:

make: *** No rule to make target `(@D)/file1', needed by `test1/my_program'. Stop.

问题:$(@D)是自动化变量,仅能在规则的命令部分使用,无法在依赖列表中解析,Make会将其当作字面量文件名处理,导致找不到文件。

正确解决方案

使用Make的模式规则(%匹配),配合正确的自动化变量:

TESTS = test1 test2
.PHONY : all
all: $(addsuffix /my_program, $(TESTS))

# 模式规则:%匹配子目录名,如test1、test2
%/my_program : %/file1 %/file2
	clang $^ -o $@

说明

  • %作为通配符匹配子目录前缀,比如目标test1/my_program会匹配%为test1,依赖自动对应test1/file1和test1/file2;
  • $^代表所有依赖文件,确保file1和file2都被传入clang编译;
  • 若之前报错是因为TESTS中包含不存在的目录,只需修正TESTS变量为实际存在的子目录即可。

内容的提问来源于stack exchange,提问作者Santiago Cuellar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:22:55