GNU Make实现仅特定子目录变更时编译对应文件
解决Makefile批量子目录编译的依赖问题
看起来你现在的问题是Makefile把所有输出文件都绑定到了所有源文件上,导致改一个小文件就要全量编译——这确实挺影响效率的,咱们来调整一下Makefile,让每个.out文件只依赖对应子目录的文件,同时把输出统一放到outDir里。
修正后的Makefile代码
# 定义源文件根目录和输出目录 SRCS_DIR := src OUT_DIR := outDir # 获取src下的所有一级子目录 SRCS_SUBDIRS := $(wildcard $(SRCS_DIR)/*) # 提取子目录的纯名称(去掉src/前缀) SUBDIRS_NAMES := $(notdir $(SRCS_SUBDIRS)) # 生成目标输出文件列表:outDir/SubDir1.out、outDir/SubDir2.out等 OUTPUT_FILES := $(addprefix $(OUT_DIR)/,$(SUBDIRS_NAMES:=.out)) # 静态模式规则:每个.out文件仅关联对应子目录的所有.c和.h文件 $(OUTPUT_FILES): $(OUT_DIR)/%.out: $(SRCS_DIR)/%/*.c $(SRCS_DIR)/%/*.h # 确保输出目录存在,避免编译时因目录缺失报错 @mkdir -p $(OUT_DIR) # 调用你的自定义编译脚本,这里假设脚本接收「子目录路径」和「输出文件路径」作为参数 # 你可以根据自己脚本的参数要求调整这里的写法 myCustomScript $(SRCS_DIR)/$* $@ # 总目标:生成所有子目录的.out文件后执行自定义处理 Process_Outputs: $(OUTPUT_FILES) CustomProcess $@
关键调整说明
- 依赖关系修正:用静态模式规则
$(OUTPUT_FILES): $(OUT_DIR)/%.out: $(SRCS_DIR)/%/*.c $(SRCS_DIR)/%/*.h,把每个outDir/XXX.out和src/XXX/下的所有.c、.h文件精准绑定,这样只有对应子目录的文件变化时,才会重新编译这个子目录的.out文件,不会触发全量编译。 - 输出目录管理:添加
@mkdir -p $(OUT_DIR)确保输出目录存在,避免编译时因为目录不存在抛出错误。 - 变量简化:去掉了复杂的递归通配符逻辑,改用
wildcard直接获取一级子目录,更简洁直观(如果你的子目录有更深层级,再考虑用递归通配符扩展)。
原来的Makefile为什么会全量编译?
你原来的规则/outDir/$(OUTPUT_FILES):$(FILES)相当于把所有输出文件的依赖都设为所有子目录的所有文件,所以只要任何一个.c或.h文件修改,Make就会判定所有输出文件都需要重新生成,自然就触发了全量编译。
内容的提问来源于stack exchange,提问作者Yudop
相关产品推荐
相关产品推荐

