如果目标超过X小时,告诉make重新运行目标?

时间:2016-03-20 10:18:39

标签: makefile

我有一个简单的Makefile来处理一些数据以产生一些其他数据。有许多步骤,这可能是耗时的,因此我使用make。其中一个初始步骤(即目标)是从网站下载输入数据文件。但该网站每天只更新。在处理过程中,我不想每次都要下载文件(因此要做所有的中间处理步骤),但是第二天,当有新的输入文件时,我就不知道了。比如make下载并使用它。

无论如何要告诉make"如果这个文件超过X小时/等旧,那么'重建'它"

2 个答案:

答案 0 :(得分:1)

让自己不支持,所以让它执行一个检查下载日期的目标,并且只在文件旧时才执行下载。

我假设您有可用的标准Unix实用程序。如果在Windows上需要这个,可以使用Linux / POSIX实用程序的许多端口之一到Windows。

如果您不想让本地文件的日期与服务器上的日期匹配,则可以使用文件的修改时间。

data-file:
        test -n "$$(find $@ -mtime -1)" || \
        rm $@ && \
        wget --no-use-server-timestamps http://example.com/data-file

如果希望本地副本与服务器日期匹配,则可以测试文件的ctime。由于其他原因(例如,如果您移动文件),这可能会发生变化,但对于此用例可能已经足够了。

data-file:
        test -n "$$(find $@ -ctime -1)" || \
        rm $@ && \
        wget -N http://example.com/data-file

如果您不能依赖文件本身的时间戳,另一种方法是创建时间戳文件。在依赖项中,依赖于data-file.stamp取决于下载日期。

data-file:
        test -n "$$(find $@ -mtime -1)" || \
        rm $@ && \
        wget -N http://example.com/data-file
data-file.stamp: data-file
        touch data-file.stamp

此外,如果服务器支持它,您可以告诉它仅在其副本比您的副本更新时才为您提供文件。

data-file:
        test -n "$$(find $@ -mtime -1)" || \
        curl --remote-time --time-cond http://example.com/data-file

或者,如果服务器副本没有更改,您可以安排不更改本地文件。

data-file:
        cd tmp && wget http://example.com/data-file
        if cmp -s tmp/data-file $@; then rm tmp/data-file; else mv tmp/data-file $@; fi

其中一些方法可以合并。

答案 1 :(得分:1)

我的策略是编写一个始终触发的规则,如果目标足够年轻,则在规则的命令中跳过重新生成。为读者练习以及所有这些: - )

这是有效的,因为如果执行了匹配规则,make会认为目标是最新的,即使时间戳没有改变。