You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNU make如何在单个模式规则中定义多个目标以避免重复代码?

可以实现,以下是两种无重复代码的实现方案:

方案1:静态模式规则(推荐,兼容性最好)

静态模式规则可以批量匹配目标集,复用同一套构建逻辑,完美适配需求:

GROFF := groff
DOCS := man README
# 可灵活扩展输出格式,新增格式只需在此处添加
OUT_FORMATS := html ascii

# 生成所有待生成的目标文件列表
DOC_FILES := $(foreach doc,$(DOCS),$(addprefix $(doc)., $(OUT_FORMATS)))

# 单条静态模式规则覆盖所有构建场景
$(DOC_FILES): %: $(basename %).doc
	$(GROFF) -T$(patsubst .%,%,$(suffix $@)) -mman $< > $@

.DEFAULT: all
all: $(DOC_FILES)

.PHONY: clean
clean:
	rm -f $(DOC_FILES)

规则逻辑说明:

  • 每个目标匹配%占位符,通过$(basename %)去掉目标后缀得到源文件前缀,依赖对应.doc源文件
  • 通过$(suffix $@)取目标文件的后缀,去除点号后作为groff的输出格式参数
  • 每个目标会单独执行一次构建命令,不会出现多目标规则一次生成所有文件的问题

方案2:动态生成模式规则(适合多格式扩展场景)

如果后续需要频繁新增输出格式,可以通过foreach+eval动态生成对应模式规则,无需手动新增规则条目:

GROFF := groff
DOCS := man README
OUT_FORMATS := html ascii

DOC_FILES := $(foreach doc,$(DOCS),$(addprefix $(doc)., $(OUT_FORMATS)))
CALL_GROFF = $(GROFF) -T$* -mman $< > $@

# 遍历输出格式列表,动态生成对应模式规则
$(foreach fmt,$(OUT_FORMATS),$(eval %.$(fmt): %.doc ; $(CALL_GROFF)))

.DEFAULT: all
all: $(DOC_FILES)

.PHONY: clean
clean:
	rm -f $(DOC_FILES)

规则逻辑说明:

  • foreach遍历所有定义的输出格式,eval会将生成的规则字符串解析为实际的Makefile规则
  • 等价于自动生成了所有输出格式对应的独立模式规则,完全避免手写重复代码
  • 新增输出格式只需在OUT_FORMATS中添加对应后缀即可,无需修改构建逻辑

内容的提问来源于stack exchange,提问作者user996142

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:57:03