GNU make:删除生成的文件时如何重建哨兵目标?
Posted
技术标签:
【中文标题】GNU make:删除生成的文件时如何重建哨兵目标?【英文标题】:GNU make: how to rebuild sentinel targets when a generated file is deleted? 【发布时间】:2021-12-25 10:28:09 【问题描述】:从 GNU make 执行代码生成器。生成器生成多个文件(取决于输入),并且仅在文件内容发生变化时才触及这些文件。因此需要使用哨兵目标来记录生成器的执行时间:
GEN_READY : $(gen_input_files)
gen.exe $(gen_input_files)
touch GEN_READY
$(gen_output_files): GEN_READY
它工作得很好,除非生成的文件被删除,但哨兵文件留在原地。由于哨兵在那里,并且它是最新的,因此不会再次执行生成器。 在这种情况下,强制 make 重新运行生成器的正确解决方案是什么?
【问题讨论】:
如果您有 Make 4.3,您可以尝试分组目标。如果不是,您可以考虑按档案对它们进行分组,并声明诸如 target.tar:prerequisite.tar 之类的规则。从输入文件哈希生成哨兵文件名是一种效果很好的技术,但可能需要比注释更长的时间来解释......有任何偏好吗? 感谢您的想法。我现在正在尝试分组目标。除了 4.3+ 之外,这可能是一个问题,我在链接规则时遇到了另一个问题。虽然可能可以修复。档案听起来很有趣,我从未尝试过的功能,看着它。哈希在这里肯定太复杂了。 Automake 手册对handling tools that produce multiple outputs 进行了相对冗长的讨论,包括使用标记文件。尽管有其来源,但讨论对于各种make
实现是通用的,而不是特定于 Automake。我想你会觉得它值得一读。
这绝对是有趣且有用的信息,非常感谢。最终的解决方案可能不适用于 GNU make。它非常复杂,使用递归 make 调用,并且不确定如何测试许多生成的文件。
从 2007 年开始,有一个 Ask Mr. Make article 关于在 GNU Make 中使用原子规则和哨兵文件。
【参考方案1】:
这是使用存档对它们进行分组的一种方法:
# create archive of output files from input files passed through gen.exe
GEN_READY.tar: $(gen_input_files)
@echo Generate the files
gen.exe $^
@echo Put generated files in archive
tar -c -f $@ $(gen_output_files)
@echo Remove intermediate files (recreated by next recipe)
rm $(gen_output_files)
# Extracting individual files for use as prerequisite or restoration
$(gen_output_files): GEN_READY.tar
@echo Extract one member
tar -x -f $< $@
由于 tar(和 zip 就这一点而言)允许重复条目,因此如果输入-输出关系允许,则可能有机会更新或附加存档中的文件,而不是重写。
编辑:简化的解决方案。
【讨论】:
我意识到这个答案实际上并不适用于这个问题,因为哨兵文件被删除了。哦,好吧,无论如何,有人可能会觉得它很有用。 这当然很有用,因为我从来没有在 make 中使用过存档并且不熟悉语法。我想知道这是否可以在不实际创建档案的情况下使用,只是为了对目标进行分组...... 已编辑以涵盖删除一个文件的情况,在这种情况下,当前答案将从半中间存档中恢复该文件。以上是关于GNU make:删除生成的文件时如何重建哨兵目标?的主要内容,如果未能解决你的问题,请参考以下文章