如何为dmake定义支持批量与单独转换DOCX到HTML的Makefile规则?
实现dmake下的批量DOCX转HTML规则(保留单独转换功能)
问题背景
当前基于dmake v4.1的Makefile通过以下规则实现单个DOCX到HTML的转换:
%.html : %.docx <recipe lines>
由于基础设施限制,逐个转换多文件速度极慢,但转换脚本支持批量处理(单次启动MS Word完成所有文档转换)。需要在保留单独转换规则的前提下,实现批量转换规则,且尽量避免修改构建/转换脚本预先启动MS Word。
现有规则示例:
FILE_LIST = a.html b.html c.html all .PHONY : $(FILE_LIST) %.html : %.docx $(CONVERT_DOC) $<
尝试过的批量规则(DOCX_FILE_LIST为FILE_LIST替换扩展名后的列表):
group_convert .PHONY : $(DOCX_FILE_LIST) $(CONVERT_DOC) $^
但$^始终返回完整文件列表而非过期依赖列表,原因是group_convert被标记为.PHONY,导致该目标被视为永远过期,所有依赖都会被传入。
解决方案
核心思路
不能将批量目标标记为.PHONY,需创建一个伪状态文件跟踪批量转换的时间戳,让dmake仅处理真正过期的DOCX文件。
具体实现
- 定义批量转换所需的变量:
FILE_LIST = a.html b.html c.html DOCX_FILE_LIST := $(FILE_LIST:.html=.docx) # 用于记录批量转换时间的状态文件 BATCH_MARKER := .docx_batch_converted
- 编写批量转换规则:
$(BATCH_MARKER): $(DOCX_FILE_LIST) # 筛选出需要转换的DOCX文件(对应HTML不存在或DOCX更新时间更晚) @echo "Checking outdated DOCX files..." @for docx in $^; do \ html=$${docx%.docx}.html; \ if [ ! -f $$html ] || [ $$docx -nt $$html ]; then \ echo $$docx; \ fi; \ done > .need_convert.tmp # 存在待转换文件时执行批量转换 @if [ -s .need_convert.tmp ]; then \ $(CONVERT_DOC) `cat .need_convert.tmp`; \ fi # 更新状态文件时间戳,标记本次批量转换完成 @touch $(BATCH_MARKER)
- 修改
all目标,同时支持批量转换和单独转换触发:
all .PHONY : $(BATCH_MARKER) $(FILE_LIST)
- 保留原有的单独转换规则:
%.html : %.docx $(CONVERT_DOC) $<
效果说明
- 执行
make all时,会自动筛选所有过期的DOCX文件进行批量转换,避免重复处理已完成转换的文件。 - 执行
make a.html时,依然会触发单独转换规则,仅处理a.docx。 - 状态文件
.docx_batch_converted仅用于记录批量转换的时间节点,不会干扰单独转换的逻辑。
内容的提问来源于stack exchange,提问作者Robert Bartlett-Schneider
相关产品推荐
相关产品推荐

