这个Makefile缓存技巧安全吗?

时间:2019-10-15 20:59:42

标签: makefile build gnu-make

在我的构建系统中,如果子文件没有任何更改,我希望避免重建子项目。基本思路是这样的:

  1. 完成make all之后,我对目录的内容进行哈希处理并保存。
  2. 下次我要构建项目时,请再次对目录的内容进行哈希处理。
  3. 如果哈希值相等,就完成了。否则,请转到1。

我正在尝试使用名为update-hash的帮助程序脚本在GNU Make中实现这一点:

#!/bin/bash
HASH_FILE=$1
SRC_DIR=$2

echo Hashing sources
UPDATED_HASH=$(tar c $SRC_DIR | sha256sum | cut -c-64)
SAVED_HASH=$(<$HASH_FILE)
if [[ $SAVED_HASH != $UPDATED_HASH ]]; then
    echo "Updating hash"
    echo $UPDATED_HASH > $HASH_FILE
else
    echo "$HASH_FILE is up to date. Not touching it."
fi

这是棘手的部分:由于Make依靠文件修改时间来决定要构建的内容,因此我使用了两个文件pre_hashpost_hash,并利用了我的{{1} }脚本如果哈希匹配则不会更新文件。

update-hash

工作方式如下:

  • 在第一次运行subproject: update_pre_hash post_hash post_hash: pre_hash make -C subproject clean all update-hash pre_hash subproject cp pre_hash post_hash update_pre_hash: update-hash pre_hash subproject 时,会更新make subproject文件,因此会构建pre_hash规则,并以已构建的子项目和一个post_hash文件结尾比post_hash更新。
  • 在随后的运行中,始终会调用pre_hash,但不会更新update_pre_hash文件,因此不会调用pre_hash规则。
  • 如果子项目中的任何文件发生更改,post_hash文件将被更新,因此pre_hash被调用,从而导致完整版本和新的哈希文件。

我的问题是:这真的有效吗?一些基本测试没有发现任何明显的问题,但似乎有些不稳定。我特别担心依靠post_hash的依存关系进行顺序评估,我知道subproject的假设是无效的,但是也许有一种方法可以解决此问题。

  • 您看到此实现有问题吗?
  • 如果您这样做,可以提出任何建议吗?
  • 您知道实现相同效果的另一种(可能更好)的方法吗? (除了显而易见的“如果没有更改,将子项目固定为无操作”,我不想维护子项目的构建过程)

更新:@ dash-o建议使用一种更简单的方法,使用这样的Makefile:

make -j

这样,last_update: $(shell find subproject -type f) make -C subproject clean all touch last_update 总是比子项目中的所有文件都新,但是如果以后有任何文件更改,则会触发重新生成。谢谢!

0 个答案:

没有答案