如何在Makefile中不使用自动变量合并相似编译配方
解决Makefile重复配方合并问题
方案1:通过foreach+eval生成绑定专属依赖的规则
由于自动变量$@无法在依赖行提前展开,我们可以遍历API列表,为每个API生成对应专属依赖的规则,同时共享同一套配方逻辑。
实现代码
基于已定义的APIS = $(API1) $(API2) $(API3)和APIS_FILES = $(API1_FILES) $(API2_FILES) $(API3_FILES),替换原有重复规则为:
# 定义函数:获取API在APIS列表中的索引(适配GNU Make全版本) api-index = $(words $(subst $(1), ,$(APIS)))$(if $(findstring $(1),$(APIS)),1,0) # 遍历生成每个API的依赖规则 $(foreach api,$(APIS), \ $(eval $(api): $(OBJDIR)/$(api)/$(word $(call api-index,$(api)),$(APIS_FILES)).o) \ ) # 所有API共享的配方逻辑 $(APIS): @mkdir -p $(APISDIR) @$(CXX) $(CXXFLAGS) $(OBJDIR)/$@/*.o -o $(APISDIR)/$@ @printf "$(_SUCCESS) $(GREEN)- $@ maked!\n$(RESET)"
说明
api-index函数:计算当前API在APIS列表中的位置,以此匹配APIS_FILES中对应的依赖文件列表。foreach+eval循环:为每个API生成独立的依赖规则(例如API1: $(OBJDIR)/API1/$(API1_FILES).o),保证依赖关系准确。- 共享配方:所有API目标复用同一套编译指令,
$@在配方中可正常展开为当前目标名,避免代码重复。
方案2:利用命名规则绑定目标与依赖(更简洁)
如果你的依赖文件变量遵循$(API_NAME)_FILES的命名规律(比如API1_FILES、API2_FILES),可以省去APIS_FILES变量,直接通过变量名匹配:
# 先定义各API的依赖文件列表 API1_FILES := file1 file2 API2_FILES := file3 file4 API3_FILES := file5 file6 # 遍历生成依赖规则 $(foreach api,$(APIS), \ $(eval $(api): $(OBJDIR)/$(api)/$($(api)_FILES).o) \ ) # 共享配方逻辑 $(APIS): @mkdir -p $(APISDIR) @$(CXX) $(CXXFLAGS) $(OBJDIR)/$@/*.o -o $(APISDIR)/$@ @printf "$(_SUCCESS) $(GREEN)- $@ maked!\n$(RESET)"
这种方式更直观,无需额外维护索引匹配逻辑,适合变量命名规范的场景。
内容的提问来源于stack exchange,提问作者THE leo TV
相关产品推荐
相关产品推荐

