如何编写带有重复模式的Makefile目标规则?
正确的Makefile编写方案
你的问题在于原规则只针对单个输出文件(.rpt),且未提前创建输出目录,同时未覆盖所有生成的文件类型。以下是可行的解决方案:
1. 基础规则:覆盖所有输出文件并确保目录存在
使用多目标模式规则,让Makefile明确运行一次Python脚本会生成三个输出文件,同时提前创建所需的子目录:
# 匹配所有三个输出文件,依赖对应的Python脚本 outputs/%/%.rpt outputs/%/%.html outputs/%/%.txt: inputs/%.py # 先创建输出目录(-p确保目录不存在时创建,存在时不报错) mkdir -p outputs/$* # 执行Python脚本生成文件 python $<
2. 批量处理所有配置文件(可选)
如果需要一键生成所有配置对应的输出,可以添加默认目标和配置列表:
# 获取所有inputs目录下的Python配置文件,提取出pattern部分 CFGS := $(patsubst inputs/%.py,%,$(wildcard inputs/*.py)) # 定义所有需要生成的输出文件 ALL_OUTPUTS := $(foreach cfg,$(CFGS),outputs/$(cfg)/$(cfg).rpt outputs/$(cfg)/$(cfg).html outputs/$(cfg)/$(cfg).txt) # 默认目标:生成所有输出 .PHONY: all all: $(ALL_OUTPUTS) # 单配置快捷目标(比如执行make cfg1即可生成cfg1的所有文件) .PHONY: $(CFGS) $(CFGS): %: outputs/%/%.rpt outputs/%/%.html outputs/%/%.txt
原规则失效的原因
- 未创建输出目录:如果
outputs/<pattern>目录不存在,Python脚本可能无法写入文件,导致Makefile认为目标未生成,会重复执行脚本。 - 仅匹配单个输出文件:原规则只针对
.rpt文件,当你需要生成.html或.txt时,Makefile找不到对应的规则,不会触发脚本执行。 - 多文件生成未关联:单个脚本生成三个文件,但原规则只标记其中一个为目标,Makefile无法感知它们是同一脚本的产物,可能导致重复执行。
内容的提问来源于stack exchange,提问作者Max Bjurling
相关产品推荐
相关产品推荐

