如何在Makefile中实现单脚本仅运行一次并完成多文件分目录复制?
解决Makefile中Python脚本重复执行的问题
核心思路
通过引入单一触发标记,让所有最终生成文件都依赖这个标记,确保Python脚本仅执行一次,再批量完成文件复制。
最终Makefile实现
MAIN_4_CSV_FILES = A.CSV B.CSV C.CSV D.CSV E.CSV F.CSV G.CSV H.CSV I.CSV J.CSV K.CSV L.CSV M.CSV N.CSV O.CSV P.CSV Q.CSV R.CSV S.CSV T.CSV U.CSV V.CSV W.CSV X.CSV Y.CSV Z.CSV # 定义所有最终目标文件的完整路径 C_AUTOGEN_FILES = $(patsubst %.CSV,$(C_AUTOGEN)/%Enum.inc,$(MAIN_4_CSV_FILES)) \ $(patsubst %.CSV,$(C_AUTOGEN)/%Table.inc,$(MAIN_4_CSV_FILES)) JAVA_ENUM_FILES = $(patsubst %.CSV,$(JAVA_ENUM)/%Enum.java,$(MAIN_4_CSV_FILES)) JAVA_TABLE_FILES = $(patsubst %.CSV,$(JAVA_TABLE)/%Table.java,$(MAIN_4_CSV_FILES)) # 总目标,涵盖所有需要生成的文件 .PHONY: all all: $(C_AUTOGEN_FILES) $(JAVA_ENUM_FILES) $(JAVA_TABLE_FILES) # 用标记文件记录脚本执行状态,避免重复运行 AUTOGEN_MARKER = .autogen_done # 仅当CSV文件更新时,执行一次脚本并生成标记 $(AUTOGEN_MARKER): $(MAIN_4_CSV_FILES) $(call run_autogen_all,$^) touch $@ # 通用复制规则:所有最终文件依赖标记,完成复制 $(C_AUTOGEN)/%.inc: $(AUTOGEN_MARKER) $(COPYF) $(notdir $@) $@ $(JAVA_ENUM)/%.java: $(AUTOGEN_MARKER) $(COPYF) $(notdir $@) $@ $(JAVA_TABLE)/%.java: $(AUTOGEN_MARKER) $(COPYF) $(notdir $@) $@ # 可选:自动清理临时生成的.inc/.java文件 .INTERMEDIATE: $(patsubst %.CSV,%Enum.inc,$(MAIN_4_CSV_FILES)) \ $(patsubst %.CSV,%Table.inc,$(MAIN_4_CSV_FILES)) \ $(patsubst %.CSV,%Enum.java,$(MAIN_4_CSV_FILES)) \ $(patsubst %.CSV,%Table.java,$(MAIN_4_CSV_FILES)) # 清理标记和临时文件 .PHONY: clean_autogen clean_autogen: rm -f $(AUTOGEN_MARKER) *.inc *.java
为什么原方案会重复执行
原方案中,*.java和*.inc各自依赖CSV文件,当同时构建JavaFiles和CFiles时,Make会分别触发两个独立的规则,导致脚本被调用两次,复制操作也重复执行。
方案优势
- 脚本仅执行一次:所有最终文件依赖同一个标记文件,只有当CSV更新时才会触发一次脚本运行。
- 复制逻辑解耦:生成和复制操作分离,维护更清晰。
- 自动清理临时文件:通过
.INTERMEDIATE标记临时文件,Make会在构建完成后自动删除,避免当前目录杂乱。
内容的提问来源于Stack Exchange,提问作者Elec0
相关产品推荐
相关产品推荐

