这个makefile缓存技巧安全吗?

这个makefile缓存技巧安全吗?,makefile,build,gnu-make,Makefile,Build,Gnu Make,在我的构建系统中,如果子项目的文件没有更改,我希望避免重建子项目。其基本思想是: 在执行make all之后,我散列目录的内容并保存它 下次我要构建项目时,再次散列目录的内容 如果散列相等,我们就完成了。否则,请转到1 我试图在GNU Make中实现这一点,使用名为updatehash的助手脚本: #/bin/bash HASH_文件=$1 SRC_DIR=$2 回声散列源 更新的_HASH=$(tarc$SRC_DIR | sha256sum | cut-c-64) 已保存的\u哈希=$($H

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

  • 在执行
    make all
    之后,我散列目录的内容并保存它
  • 下次我要构建项目时,再次散列目录的内容
  • 如果散列相等,我们就完成了。否则,请转到1
  • 我试图在GNU Make中实现这一点,使用名为
    updatehash
    的助手脚本:

    #/bin/bash
    HASH_文件=$1
    SRC_DIR=$2
    回声散列源
    更新的_HASH=$(tarc$SRC_DIR | sha256sum | cut-c-64)
    已保存的\u哈希=$($HASH\u文件
    其他的
    echo“$HASH_文件是最新的。未接触它。”
    fi
    
    这里有一个棘手的部分:因为Make依赖于文件修改时间来决定构建什么,所以我使用了两个文件,
    pre\u hash
    post\u hash
    ,并且利用了这样一个事实,即如果hash匹配,我的
    updatehash
    脚本不会更新文件

    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
    
    其工作方式如下:

    last_update: $(shell find subproject -type f)
            make -C subproject clean all
            touch last_update
    
    • 在第一次运行
      make subject
      时,更新
      pre\u hash
      文件,从而生成
      post\u hash
      规则,以生成的子项目和比
      pre\u hash
      新的
      post\u hash
      文件结束
    • 在后续运行中,
      update\u pre\u hash
      始终被调用,但不会更新
      pre\u hash
      文件,因此不会调用
      post\u hash
      规则
    • 如果子项目中的任何文件发生更改,则更新
      pre\u hash
      文件,从而调用
      post\u hash
      ,从而生成完整的生成和新的hash文件
    我的问题是:这真的会起作用吗?一些基本测试没有发现任何明显的问题,但它似乎有点不稳定。我特别担心依赖
    子项目
    的依赖关系来获得有序的评估,我知道这对于
    make-j
    是一个无效的假设,但也许有办法解决这个问题

    • 您认为这个实现有问题吗
    • 如果你这样做了,你能建议一些修复方法吗
    • 你知道实现同样效果的另一种(也许更好)方法吗?(除了明显的“如果没有更改,将子项目修复为无操作”之外-我不想维护子项目的构建过程)

    更新:@dash-o提出了一种更简单的方法,使用如下生成文件:

    last_update: $(shell find subproject -type f)
            make -C subproject clean all
            touch last_update
    

    这样,
    last\u update
    总是比子项目中的所有文件都要新,但是如果以后有任何文件更改,就会触发重新编译。谢谢!

    您第一次运行它时,它不会抱怨它不知道如何构建
    pre\u hash
    ?我一直在使用类似的方法跳过大型构建,没有遇到过这个问题作为一种选择,考虑创建一个“最后更新”文件,它将依赖于所有文件(使用代码<触摸$@ @ /代码>的规则)。。您可以检查“上次更新”的时间戳作为代理。文件时间戳是否会自动更新?您的根本问题是递归生成。如果您可以将其设置为非递归生成,这将是最理想的。有关详细信息,请参阅legendary。提醒您:永远不要使用原始
    make
    来调用sub-MAKE。始终,始终使用
    $(MAKE)
    (或
    ${MAKE}
    ,如果这是您的问题)。