让 cmake 使用自己的构建缓存
Posted
技术标签:
【中文标题】让 cmake 使用自己的构建缓存【英文标题】:Make cmake use its own build cache 【发布时间】: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 文件来检索文件。 【参考方案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...以上是关于让 cmake 使用自己的构建缓存的主要内容,如果未能解决你的问题,请参考以下文章