必须用CMAKE_CXX_COMPILER_LAUNCHER=ccache配置,而非改环境变量;需避免-fdebug-prefix-map等破坏哈希一致性的选项,并通过ccache -s验证命中率。

ccache 能让局部修改后的 C++ 二次构建快 2–5 倍,但必须正确配置才能命中缓存;默认安装后不生效,90% 的“没变快”问题出在编译器调用路径或选项干扰上。
怎么让 CMake 项目真正走 ccache
cmake 不会自动调用 ccache,它只认你告诉它的编译器路径或 launcher。靠改 CXX=ccache g++ 容易被生成器覆盖(尤其是 Ninja + 多配置场景),最稳的方式是用 CMAKE_CXX_COMPILER_LAUNCHER:
- 命令行配置(推荐):
cmake -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. - CMakeLists.txt 内配置(兼容旧版):
find_program(CCACHE_PROGRAM ccache); if(CCACHE_PROGRAM) set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) - 验证是否生效:编译时加
--trace,看日志里是否出现ccache g++;或者运行ccache -s,观察cache hit rate是否随构建上升
哪些编译选项会让 ccache 直接绕过缓存
ccache 对输出不可预测的选项主动降级为直通模式——不是 bug,是安全设计。常见触发项包括:
-
-fprofile-generate和-fprofile-use:涉及运行时采样,缓存结果无意义 -
-MP(Makefile 依赖生成):ccache 不解析依赖输出,直接透传 -
-fdebug-prefix-map或-frecord-gcc-switches:现代构建系统常默认开启,但会把绝对路径塞进哈希键,导致 CI 中 100% miss -
-gline-tables-only、-gz:旧版 ccache 不支持,会 fallback;新版(>=4.8)已支持,但需确认版本ccache --version
本地缓存目录和大小怎么管才不翻车
默认缓存放在 $HOME/.ccache,大项目几轮构建就占满磁盘。别手动 rm -rf,要用内置机制:
立即学习“C++免费学习笔记(深入)”;
- 换位置:
export CCACHE_DIR=/fast/ssd/ccache(写进~/.bashrc或 CI 脚本) - 限大小(关键):
ccache --max-size=20G,超过自动 LRU 清理;设太小(如1G)会导致频繁抖动、命中率暴跌 - 查状态:
ccache -s看files in cache和cache hit rate;若长期,大概率是编译选项不稳定(比如 debug/release 混用)、头文件路径含临时目录,或 <code>CCACHE_BASEDIR没对齐
为什么 CI 里 ccache 基本不 work
ccache 是纯本地缓存,CI 每次都在全新容器/VM 里跑,路径随机、环境隔离、选项带调试前缀——所有这些都会让哈希键失效。典型表现是 ccache -s 显示有 cache,但 cache hit rate 始终为 0。
- 根本原因:
/tmp/abc123/src/main.cpp和/tmp/def456/src/main.cpp算两个不同输入,哪怕内容一模一样 - 补救(有限):
export CCACHE_BASEDIR=/tmp/build并确保所有-I、-D路径都相对于它;但无法解决-fdebug-prefix-map等现代选项的干扰 - 真实解法:换
sccache,配 S3/GCS 远程后端,并在 CMake 中显式禁用非确定性选项,比如add_compile_options(-fdebug-prefix-map=${CMAKE_BINARY_DIR}=/build)
缓存加速不是装完就完事,核心在于“哈希键一致性”——源码、头文件、编译器、参数、路径,缺一不可。最容易被忽略的是 CI 中的路径随机性和调试选项,默认开着就等于主动关掉缓存。


















