GNU Make问题:避免文件已存在时重复执行规则
Makefile 重复触发
bifi规则问题排查与解决 问题场景
你编写的Makefile代码片段如下:
DATA_DIR ?= cpp/gen_data_cpp/build TXT_FILES := $(wildcard ${DATA_DIR}/*.txt) BIFI_FILES := $(TXT_FILES:.txt=.txtbifikreversed) ${BIFI_FILES}: ${TXT_FILES} cpp/build/exe_convert_multicov2rivet bash $(S_process_pt_cloud) $< 3 bifi: $(BIFI_FILES) line: cpp/build/exe_project_bifi_along_path $(BIFI_FILES) bash script.sh file1 file2
每次执行make line时,都会触发耗时的bifi规则,而bifi生成的${BIFI_FILES}文件实际只需生成一次。
问题根源
- 依赖范围错误:
${BIFI_FILES}的依赖设置为${TXT_FILES}(所有txt文件),这意味着每一个.txtbifikreversed文件都会依赖目录下所有的txt文件。只要任意一个txt文件的修改时间晚于对应的bifi文件,所有bifi文件都会被重新生成。 - 目标与源文件不对应:规则中使用
$<引用第一个依赖,但当前依赖是所有txt文件,导致每个bifi文件都基于同一个txt文件(第一个)生成,逻辑本身就有问题,同时也让Make无法正确判断单个bifi文件是否需要更新。
修复方案
将${BIFI_FILES}的规则修改为模式规则,让每个bifi文件仅依赖对应的单个txt文件和转换工具:
DATA_DIR ?= cpp/gen_data_cpp/build TXT_FILES := $(wildcard ${DATA_DIR}/*.txt) BIFI_FILES := $(TXT_FILES:.txt=.txtbifikreversed) # 模式规则:单个txt文件对应生成单个bifi文件 ${DATA_DIR}/%.txtbifikreversed: ${DATA_DIR}/%.txt cpp/build/exe_convert_multicov2rivet bash $(S_process_pt_cloud) $< 3 bifi: $(BIFI_FILES) line: cpp/build/exe_project_bifi_along_path $(BIFI_FILES) bash script.sh file1 file2
修复说明
- 模式规则
${DATA_DIR}/%.txtbifikreversed: ${DATA_DIR}/%.txt会自动建立xxx.txt到xxx.txtbifikreversed的一对一映射,确保每个目标文件只依赖自身对应的源文件。 - Make会基于文件修改时间判断:只有当对应的txt文件、转换工具
cpp/build/exe_convert_multicov2rivet比bifi文件新时,才会重新生成该bifi文件,不会每次执行make line都重复触发整个bifi规则。
内容的提问来源于stack exchange,提问作者sunxd
相关产品推荐
相关产品推荐

