ccache 是编译器前端缓存代理,通过哈希源码、头文件、宏定义及编译选项实现缓存复用;中大型 c++ 项目局部构建可提速 2–5 倍,推荐用 cmake_cxx_compiler_launcher=ccache 启用,注意避开 -fprofile-generate 等不兼容选项。

ccache 是什么,为什么值得在 C++ 项目里立刻启用
ccache 不是编译器,而是编译器前端缓存代理——它把 g++ 或 clang++ 的输入(源码、头文件、宏定义、编译选项)哈希后查缓存;命中就直接返回目标文件,跳过实际编译。对中大型 C++ 项目,首次全量编译后,局部修改再构建常能快 2–5 倍。
关键点:它只缓存成功编译的结果,不缓存错误;且默认对 -g、-O2、-DFOO=bar 等所有影响输出的参数敏感,所以不用手动管理“缓存键”。
怎么让 cmake 项目自动走 ccache(最常用场景)
cmake 本身不调用 ccache,但可以通过设置编译器路径或环境变量触发。推荐用 CMAKE_CXX_COMPILER_LAUNCHER,它比改 CXX 环境变量更可靠,尤其在交叉编译或多配置生成器(如 Ninja + VS)下不会漏掉。
- 命令行启用:
cmake -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. - 如果用的是 Ninja,确保
ccache在$PATH中且可执行(运行ccache --version验证) - 避免同时设
CXX=ccache g++和CMAKE_CXX_COMPILER_LAUNCHER,后者会覆盖前者,容易误以为没生效 - 检查是否真在用 ccache:编译时加
--trace或看ccache -s输出的cache hit rate,不是看有没有报错
哪些编译选项会让 ccache 失效或降级为直通
ccache 对某些选项天然不兼容,遇到就会绕过缓存、直接调用真实编译器。这不是 bug,是设计使然——因为这些选项让输出不可预测或依赖运行时状态。
-
-fprofile-generate/-fprofile-use:涉及运行时采样数据,ccache 拒绝缓存 -
-MP(Makefile 依赖生成):ccache 不解析依赖输出,直接透传 -
-MD/-MMD:虽然支持,但要求所有头文件路径必须可被 ccache 完整捕获;若用了-I/tmp/build/xxx这类临时路径,且该路径在后续构建中不存在,缓存会失效 -
-g本身没问题,但-gline-tables-only和-gz(压缩调试段)在旧版 ccache(
缓存目录、大小和清理的实际控制方式
ccache 默认用 $HOME/.ccache,但大项目容易撑爆磁盘。别靠手动 rm -rf,要用内置机制。
- 改缓存位置:
export CCACHE_DIR=/fast/ssd/ccache(写进 shell profile 或 CI 脚本) - 限制大小(推荐):
ccache --max-size=20G,超过时自动 LRU 清理;别设太小(如 1G),否则频繁抖动 - 查看状态:
ccache -s,重点关注cache hit rate和files in cache;若cache hit rate长期低于 30%,大概率是编译选项不稳定或头文件路径含时间戳/随机值 - 强制清空:
ccache -C(慎用),日常用ccache -c(清理过期项)更安全
一个容易被忽略的点:ccache 不感知 git 分支切换,但不同分支的头文件内容变了,哈希自然不同——所以不要指望“一次缓存永久受益”,它只对重复构建同一代码树有效。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











