我有一个简单的Makefile来处理一些数据以产生一些其他数据。有许多步骤,这可能是耗时的,因此我使用make。其中一个初始步骤(即目标)是从网站下载输入数据文件。但该网站每天只更新。在处理过程中,我不想每次都要下载文件(因此要做所有的中间处理步骤),但是第二天,当有新的输入文件时,我就不知道了。比如make下载并使用它。
无论如何要告诉make"如果这个文件超过X小时/等旧,那么'重建'它"
答案 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
会认为目标是最新的,即使时间戳没有改变。