GNU Make中引用子目录目标文件的更简洁方法咨询
优化子目录目标文件引用的两种方案
以下方案均兼容GNU Make 4.1版本,无需额外配置:
方案1:最小改动的简洁写法(推荐)
利用GNU Make内置的addsuffix函数,直接基于你已经定义好的SUBDIRS列表生成目标文件匹配规则,既比硬写*/*.o严谨(不会匹配到SUBDIRS列表外的其他目录的.o文件),写法也非常简洁:
把链接规则里的*/*.o直接替换为$(addsuffix /*.o, $(SUBDIRS))即可。
如果要进一步避免把不存在的路径传入链接命令,可以再套一层wildcard函数做过滤:$(wildcard $(addsuffix /*.o, $(SUBDIRS)))
修改后的链接规则示例:
$(PROGRAM): $(OBJECTS) ${SUBDIRS} $(CXX) -o $(PROGRAM) ${OBJECTS} $(wildcard $(addsuffix /*.o, $(SUBDIRS))) $(LIBS)
方案2:适合复杂项目的显式收集写法
如果后续子目录结构变复杂,存在部分子目录.o不需要参与链接的情况,可以用显式变量收集的方式做更精细的控制:
- 每个子目录的Makefile中定义该目录需要参与链接的目标文件变量:
# 以util子目录的Makefile为例 SUBOBJS := file1.o file2.o file3.o
- 顶层Makefile中用
foreach循环批量收集所有子目录的目标文件路径:
SUB_OBJECTS := $(foreach dir, $(SUBDIRS), $(addprefix $(dir)/, $(shell $(MAKE) -C $(dir) -pRrq : 2>/dev/null | awk -v RS= -F: '/^SUBOBJS/ {print $$2}')))
之后链接时直接用$(SUB_OBJECTS)指代所有子目录的目标文件即可,不会引入意外的.o文件。
额外优化提示
你当前的Makefile中$(PROGRAM)的依赖包含了.PHONY类型的$(SUBDIRS),会导致每次执行make都会重新执行链接操作,即使所有目标文件都没有更新。如果要避免这个冗余操作,可以把每个子目录的标记文件作为依赖,而非直接依赖子目录phony目标。
内容的提问来源于stack exchange,提问作者Alex Hajnal
相关产品推荐
相关产品推荐

