Makefile规则取决于文件数量/标题的更改,而不是文件内容的更改

时间:2010-03-16 07:11:06

标签: makefile

我正在使用makefile来自动生成一些文档。我在一个目录中有几个文件,我的一个makefile规则将生成这些文件的索引页面。文件列表本身使用list := $(shell ls documents/*.txt)即时加载,因此每次添加,删除或重命名文档时,我都不必费心手动编辑makefile。当然,我希望索引生成规则在文档目录中文件的数量/标题发生变化时触发,但我不知道如何设置先决条件以这种方式工作。

我可以使用.PHONY或类似的东西来强制索引生成一直运行,但我宁愿不浪费周期。我尝试将ls管道传输到文件list.txt并使用 作为我的索引生成规则的先决条件,但这需要手动编辑list.txt(尝试为了避免它,或者在makefile中自动生成它(这会改变创建时间,因此我不能在先决条件中使用list.txt,因为它会每次触发规则)。

3 个答案:

答案 0 :(得分:6)

如果您需要依赖文件数量,那么......为什么不依靠数字本身?该数字将表示为当指定的文件的nubmer位于documents目录中时创建的虚拟文件。

NUMBER=$(shell ls documents/*.txt | wc -l).files
# This yields name like 2.files, 3.files, etc...
# .PHONY $(NUMBER) -- NOT a phony target!

$(NUMBER):
        rm *.files    # Remove previous trigger
        touch $(NUMBER)

index.txt: $(NUMBER)
        ...generate index.txt...

虽然文件数是一个要跟踪的属性,但您可能依赖于目录列表的哈希。对于工作流程中出现的两个列表,哈希函数不太可能相同。这是一个例子:

NUMBER=$(shell ls -l documents/*.txt | md5sum | sed 's/[[:space:]].*//').files

请注意使用-l - 这样您将依赖于完整的文件列表,其中包括修改时间,大小和文件名。如果你不需要它,你可以放弃选项。

注意:需要sed,因为在我的系统md5sum之后会产生一些哈希值本身之后的东西。

答案 1 :(得分:2)

您可以依赖列表文件的目录本身,例如

list.txt: documents
        ls documents/*.txt 2>/dev/null > $@ || true

每次在文档目录中添加或删除文件时,目录的时间戳都会被更改,make将做正确的事。

答案 2 :(得分:0)

当且仅当文件集发生变化时,这是一个更新索引的解决方案:

list.txt.tmp: documents
    ls $</*.txt > $@

list.txt: list.txt.tmp
    cmp -s $< $@ || cp $< $@

index.txt: list.txt
    ...generate index.txt...

感谢“cmp || cp”,除非“ls”的输出发生变化,否则“list.txt”的ctime不会改变。