我有一个使用 dmake v4.1 作为现有工具的 makefile。有一条规则可以使用 % 规则从另一种文件类型构建一种文件类型,如下所示:
%.html : %.docx
<recipe lines>
此规则采用 Word 文档并运行脚本将其转换为 HTML。但是,由于许多 IS 基础设施规则超出了我的控制范围,因此单独对多个文件运行此规则要慢得多。处理转换的脚本能够处理多个文件,并使用一次 MS Word 启动来处理所有文档。我想尝试找到一种方法来创建支持此功能的 makefile 规则,同时保留单独转换文件的规则。
我曾考虑过修改构建脚本和转换脚本以预先启动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
)。有可能实现我想要做的事情吗?
我尝试过为批量转换制定单独的规则,如下所示(其中 DOCX_FILE_LIST 只是 FILE_LIST 更改了扩展名):
group_convert .PHONY : $(DOCX_FILE_LIST) $(CONVERT_DOC) $^
然而,似乎应该评估过时先决条件列表 > 的
宏始终评估为完整文件列表(可能 > 因为$^
标有group_convert
)。.PHONY
我假设
.PHONY
对 dmake
具有与 GNU make
相同的意义。 然而,如果它对 dmake
没有特殊意义的话,最终不会有太大变化。
在这种情况下,
group_convert
是 而不是 ,在该示例中标有
.PHONY
。 相反,
$(DOCX_FILE_LIST)
扩展中的每个文件都标记为
.PHONY
。 无论哪种方式的重要性在于,虚假目标始终被认为就其先决条件而言已经过时,无论该名称的文件是否存在或其时间戳是什么。
但是,这可能与您的问题没有多大关系。 由于您似乎打算将
group_convert
标记为虚假文件,因此我认为实际上不存在这样的文件,并且构建系统也不会创建这样的文件。 这就是为什么它的所有先决条件总是被认为比它更新。 永远记住
make
本身不保留任何状态。 它对于自上次运行以来文件是否已更改没有绝对的意义。 它对目标相对于其先决条件是否过时的分析始终是相对的。有可能实现我想要做的事情吗?
是的。 您可以让
make
创建一个标记文件,其目的只是为了记住上次文档转换的时间戳。 您可以使用类似于您已有的规则来做到这一点:group_convert.timestamp: $(DOCX_FILE_LIST)
$(CONVERT_DOC) $^
touch $@
请注意,目标
group_convert.timestamp
不得标记为虚假。 该文件实际上是由构建创建的,它的时间戳用于判断哪些文档需要转换。但是,有一些警告:
用于判断文件陈旧性的时间戳与辅助文件相关联,而不是与实际的输出文件相关联。 因此,其中一个 .docx 文件有可能在运行该配方期间被修改,在这种情况下,它不会被拾取为要转换的文件,但它的时间戳太旧而无法拾取它用于后续运行的转换。
make
的正常操作模式,但可以使其工作)。 然后要有一个 .PHONY
group_convert
目标。 让它使用先前创建的文件的内容来控制哪些文档需要转换。 这可能看起来像这样:
CONVERT_FILE = newer_docx_files
FILE_LIST = a.html b.html c.html
.PHONY: $(CONVERT_FILE) group_convert
# This target is phony, so it is always out of date:
$(CONVERT_FILE):
echo -n > $(CONVERT_FILE)
$(MAKE) $(MAKEFLAGS) $(FILE_LIST)
# This target is phony, so it is always out of date:
group_convert: $(CONVERT_FILE)
to_convert=$$(<$<); \
test -n "$${to_convert}" && $(CONVERT_DOC) $${to_convert}
# This rule is a lie. It does not actually create .html files from corresponding
# .docx files, but it *does* capture the result of the staleness analysis to control
# whether the .html file is built later.
%.html : %.docx
echo '$<' >> $(CONVERT_FILE)