如何在Makefile中为多组目标依赖对编写通用规则
解决Makefile批量生成对应目标与依赖的规则问题
问题根源
你当前的Makefile规则$(TARGETS): $(DEPS)会被展开为:
a: aa bb cc b: aa bb cc c: aa bb cc
这意味着每个目标都依赖所有源文件,而且make默认只会执行第一个目标(a),所以只输出a aa($<代表第一个依赖)。
解决方案
方案1:模式规则(推荐,适用于目标与依赖有统一命名规律的场景)
如果目标和对应依赖的文件名有固定规律(比如测试场景中a对应aa,实际项目中a对应a.cpp),用模式规则最简洁:
测试场景的Makefile:
TARGETS = a b c # 设置默认目标为all,确保构建所有TARGETS all: $(TARGETS) # 模式规则:匹配任意目标%,对应依赖为%%(比如a对应aa,b对应bb) %: %% @echo $@ $<
实际C++项目的Makefile(目标对应同名cpp文件):
TARGETS = a b c all: $(TARGETS) # 模式规则:目标%依赖%.cpp,编译生成可执行文件 %: %.cpp g++ -o $@ $<
执行make后,会依次构建a、b、c三个目标,输出符合预期。
方案2:foreach循环生成规则(适用于目标与依赖无统一规律的场景)
如果目标和依赖的对应关系没有固定模式,但你能保证TARGETS和DEPS的顺序一一对应(a对应aa,b对应bb等),可以用foreach+eval批量生成规则:
TARGETS = a b c DEPS = aa bb cc all: $(TARGETS) # 遍历TARGETS和DEPS的配对,为每个目标生成单独规则 $(foreach target,$(TARGETS), \ $(eval $(target): $(word $(index $(TARGETS),$(target)),$(DEPS)) ; @echo $$@ $$<) \ )
关键注意事项
- 必须设置
all: $(TARGETS)作为默认目标,否则make只会构建TARGETS中的第一个目标。 - 两种方案都只会构建
TARGETS变量中指定的目标,不会处理目录中的其他文件(比如测试场景外的d.cpp)。
内容的提问来源于stack exchange,提问作者Setu
相关产品推荐
相关产品推荐

