在我的构建系统中,如果子文件没有任何更改,我希望避免重建子项目。基本思路是这样的:
make all
之后,我对目录的内容进行哈希处理并保存。我正在尝试使用名为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_hash
和post_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
总是比子项目中的所有文件都新,但是如果以后有任何文件更改,则会触发重新生成。谢谢!