代码之家  ›  专栏  ›  技术社区  ›  Amandasaurus

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

  •  1
  • Amandasaurus  · 技术社区  · 10 年前

    我有一个简单的Makefile,它处理一些数据以生成一些其他数据。有很多步骤,可能很耗时,因此我使用make。初始步骤(即目标)之一是从网站下载输入数据文件。然而,该网站仅每天更新。在处理过程中,我不想每次都下载文件(并因此执行所有中间处理步骤),但是第二天,当有一个新的输入文件时,我想让它下载并使用它。

    有没有什么可以告诉make“如果这个文件超过X小时/等,那么'重建'它?”

    2 回复  |  直到 10 年前
        1
  •  2
  •   Gilles 'SO- stop being evil'    10 年前

    Make本身不支持这一点,所以让它执行一个检查下载日期的目标,并且只在文件过时时执行下载。

    我假设您有可用的标准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
    

    其中一些方法可以结合使用。

        2
  •  1
  •   Jens    10 年前

    我的策略是编写一个总是被触发的规则,如果目标足够年轻,则在规则的命令中跳过重新生成。针对读者的练习:-)

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