如何在Makefile规则中正确为依赖列表添加路径前缀?
适用于多子目录的Makefile规则优化方案
问题描述
我想在Makefile中编写适用于所有子目录的规则,当这类规则存在依赖时,要求依赖满足以下两点:
- 在依赖项中被引用时,需与目标文件绑定相同路径;
- 在规则中被引用时,需使用与目标相同的路径。
我目前想到的最佳实现如下例所示,它可以正常工作,但写法冗长且可读性差。是否存在更程序化的实现方式?
BUILDDIR = build BCFILES = file1.bc file2.bc file3.bc ... BCFILES_STARED = $(patsubst %, */$(BUILDDIR)/%, $(BCFILES)) */$(BUILDDIR)/my_program.bc: $(BCFILES_STARED) */build llvm-link $(patsubst %, $(@D)/%, $(BCFILES)) -o $@
优化实现
你可以利用Make的模式规则和自动变量来简化代码,同时保证逻辑清晰:
BUILDDIR = build BCFILES = file1.bc file2.bc file3.bc # 模式规则:匹配任意子目录下的my_program.bc目标 %/$(BUILDDIR)/my_program.bc: $(addprefix %/$(BUILDDIR)/, $(BCFILES)) %/$(BUILDDIR) llvm-link $(addprefix $(@D)/, $(BCFILES)) -o $@ # 确保子目录下的build目录存在 %/$(BUILDDIR): mkdir -p $@
优化说明
- 用标准的
%模式通配符替代*,Make对%的处理更稳定,能精准匹配任意子目录路径 - 用
$(addprefix)替代$(patsubst),语法更直观,直接给每个依赖文件加上目标所在的路径前缀 - 自动变量
$(@D)直接获取目标文件的所在目录,避免手动拼接路径的重复代码 - 将build目录的创建单独拆分为规则,逻辑更清晰,确保每个子目录的build目录都能被正确创建
这个实现完全满足你的依赖要求:依赖项会自动绑定到目标所在的子目录路径,规则中也直接复用目标的路径,同时代码更简洁易读。
内容的提问来源于stack exchange,提问作者Santiago Cuellar
相关产品推荐
相关产品推荐

