【问题标题】:Make cmake use its own build cache让 cmake 使用自己的构建缓存
【发布时间】:2021-11-16 04:39:39
【问题描述】:

我正在使用 Google Cloud Build 构建 CI/CD 管道(整个构建过程在 Docker 容器中进行)。在某些时候,我从build 目录中像这样调用cmake

cmake -DCMAKE_BUILD_TYPE=Release ../ && \
cmake --build . --target all --config Release -- -j 25

项目结构(如果简化)如下所示:

> build/
> src/
> CMakeLists.txt

问题是每次新构建开始时,无论源代码是否更改,整个项目都会重新编译。为了避免这种情况,我使用gsutil 将整个build 目录保存到云存储,然后在每个构建开始时使用相同的gsutil 将缓存检索回build。但是,当上面的cmake 命令启动时,项目仍在完全重新编译。

据我所知cmake(或底层make)使用愚蠢的“最后修改”时间戳来确定是否重新编译任何东西。问题是 gsutil 完全删除了这些时间戳(除了 Cloud Storage,我不会使用其他任何东西)。

那么,问题是如何让cmake 正确处理构建缓存?

【问题讨论】:

  • 这种方式破坏了 CI 的全部意义,不是吗?
  • @arrowd 哦,请让我们跳过这些“我该怎么做 X?” - “你不需要做 X”
  • 当然。我只是说任何非常不寻常的事情通常很难实现/实现。
  • @arrowd 实际上它不是 true CI/CD(你知道,当你提交更改然后它被部署到 prod 时的那个)而是一堆脚本自动化一些事情,例如:更新版本-> lint-> 构建-> 测试-> 推送版本-> 推送结果图像。而且由于项目将变得越来越大,我真的需要能够只构建最后的更改,而不是重建所有内容。但我有一个想法要检查..
  • 完成这项工作的唯一可能方法是保留时间戳。如果您的文件系统不保留每个文件的时间戳,解决此问题的一种方法是不在远程文件系统中存储单个文件;相反,您可以创建包含文件的 tar 文件或 zip 文件,这两个文件都保留时间戳,并将 tar/zip 文件存储在远程文件系统中。然后通过解压缩 tar/zip 文件来检索文件。

标签: makefile cmake gnu-make gsutil


【解决方案1】:

使用<LANG>_COMPILER_LAUNCHER 来使用 ccache 并复制 ccache 缓存而不是构建目录(IIRC ccache 使用哈希而不是时间戳...)?

参考:https://cmake.org/cmake/help/latest/prop_tgt/LANG_COMPILER_LAUNCHER.html

【讨论】:

  • 我已经这样做了,但有两个小区别:1)我保存的不是缓存本身,而是整个 docker 阶段(我想这样做更可靠),2)我肯定反对更改 CMakeFiles 以使它们符合不同的工具,所以我没有使用 <LANG>_COMPILER_LAUNCHER,而是更新了 PATH,因此对 g++/gcc 的任何调用都被重定向到 ccache
  • 我正在考虑在配置 cmd 行上使用-DCXX_COMPILER_LAUNCHER=ccache,而不是直接破解 CMakeLists.txt...
猜你喜欢
  • 2015-07-20
  • 2011-08-23
  • 2021-03-28
  • 1970-01-01
  • 2020-07-05
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
相关资源
最近更新 更多