如何使用Ccache加速c++项目的重复编译? (编译缓存工具)
技术百科
裘德小鎮的故事
发布时间:2026-01-15
浏览: 次 ccache 能显著加速 C++ 项目重复编译,但需正确配置编译器路径、缓存目录、预处理器行为及 CMAKE_CXX_COMPILER_LAUNCHER 等关键项,否则可能失效或引发链接错误。
ccache 能显著加速 C++ 项目的重复编译,前提是正确配置编译器路径、缓存目录和预处理器行为;否则它可能完全不生效,甚至导致链接错误或缓存污染。
确认 ccache 是否真正介入编译过程
很多项目看似用了 ccache,实际编译命令绕过了它。关键看 g++ 或 clang++ 是否被 ccache 包装——不是靠 alias,而是靠 PATH 优先级或显式前缀。
- 运行
which g++,输出应为类似/usr/lib/ccache/g++(Debian/Ubuntu)或/usr/local/bin/g++(若你软链了 ccache) - 检查编译日志中实际执行的命令:如果看到
ccache g++ -c ...或/usr/lib/ccache/g++ -c ...,说明生效;若只有裸g++,ccache 没起作用 - CMake 项目需显式设置:
cmake -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ...;仅设CMAKE_CXX_COMPILER为ccache是错的
避免因预处理差异导致缓存未命中
ccache 对输入源做哈希,任何影响预处理结果的变量(如绝对路径、时间宏、随机 salt)都会让哈希值变化,强制重编译。
- 禁用
__DATE__/__TIME__:在编译选项中加-frecord-gcc-switches无用,应统一用-D__DATE__=\"redacted\" -D__TIME__=\"redacted\" - 避免绝对路径泄露:CMake 中用
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)生成的compile_c含绝对路径,但 ccache 不读它;真正要管的是
ommands.json
-I/path/to/include—— 若路径随 workspace 变化,考虑用符号链接固定位置 - 禁止
-fdebug-prefix-map或-frecord-gcc-switches等引入非确定性信息的 flag(除非你明确需要调试信息且接受缓存失效)
合理配置缓存大小与位置
默认缓存位置(~/.ccache)可能空间不足或 I/O 慢;缓存满时 ccache 会自动清理,但策略偏保守,容易卡在 5GB 上限不动。
- 用
ccache -s查看当前状态,重点关注cache size和max cache size - 增大上限:
ccache -M 20G(注意是大写M);清空缓存:ccache -C - 把缓存放 SSD 或内存盘:
export CCACHE_DIR="/fast/ssd/ccache-$(whoami)",并确保该路径有读写权限 - 启用压缩节省空间(小幅增加 CPU 开销):
ccache -o compression=true -o compression_level=6
识别并修复“假命中”和静默失败
ccache 有时会返回旧缓存对象而不报错,尤其在头文件变更但未被依赖分析捕获时——这会导致奇怪的运行时错误。
- 开启严格模式验证:设
export CCACHE_SLOPPINESS="pch_defines,time_macros,include_file_mtime,include_file_ctime,env_vars"(慎用,会降低命中率) - 临时禁用缓存调试问题:
CCACHE_DISABLE=1 make,对比产物是否一致 - 检查 ccache 日志:
export CCACHE_LOGFILE="/tmp/ccache.log"; export CCACHE_DEBUG=1,然后复现一次编译,查看日志里是否有hash mismatch或preprocessing failed
export CCACHE_DIR="$HOME/.ccache" export CCACHE_BASEDIR="$PWD" export CCACHE_SLOPPINESS="file_stat_matches" alias g++='ccache g++' alias clang++='ccache clang++'
最易被忽略的是 CCACHE_BASEDIR:它让 ccache 归一化源文件路径哈希,否则同一份代码在不同路径下编译,缓存完全不共享。还有就是 CMake 的 CMAKE_CXX_COMPILER_LAUNCHER 必须设对,不是所有构建系统都认 CC/CXX 环境变量里的 ccache。这些点没踩准,ccache 就只是个摆设。
# ai
# 的是
# 是个
# 用了
# 而不
# 会让
# 未被
# 这会
# mac
# 有时会
# 工具
# ubuntu
# debian
# js
# json
# 环境变量
# 对象
# c++
# 报错
# red
# map
# switch
# 处理器
# include
# 严格模式
# 不动
# 预处理器
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- mac怎么打开终端_MAC终端Terminal使用
- Win11怎么关闭系统透明度_Windows11个
- Win10怎么卸载鲁大师_Win10彻底卸载鲁大师
- 如何使用Golang安装依赖库_管理模块和第三方包
- 如何在 Go 中正确测试带 Cookie 的 HT
- Win11怎么打开旧版计算器_Win11恢复传统计
- 当网站SEO排名下降时,如何应对?
- Win11怎么设置右键刷新选项_Windows11
- Windows笔记本无法进入睡眠模式怎么办?(电源
- c# 如何深拷贝和浅拷贝
- php本地部署支持nodejs吗_php与node
- 如何使用Golang实现基本类型比较_Golang
- c++中如何求一个数的平方根_c++ sqrt函数
- 如何使用Golang管理跨项目依赖_Golang多
- Python异步编程高级项目教程_asyncio协
- 如何在 Go 中比较自定义的数组类型(如 [20]
- c++中的可变参数模板(variadic temp
- Win11怎么设置默认邮件客户端 Win11修改M
- MAC如何安装Git版本控制工具_MAC开发环境配
- C++ STL算法库怎么用?C++常用算法函数(s
- php8.4如何配置ssl证书_php8.4htt
- c++ nullptr与NULL区别_c++11空
- PHP 中如何在函数内持久修改引用变量所指向的目标
- c++怎么处理多线程死锁_c++ lock_gua
- 电脑的“网络和共享中心”去哪了_Windows 1
- Win10如何更改电脑休眠时间_Windows10
- Mac的“调度中心”与“空间”怎么用_Mac多桌面
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- Windows10怎样设置家长控制_Windows
- Windows服务启动类型恢复方法_错误修改导致的
- php转mp4怎么设置帧率_调整php生成mp4视
- Win11怎样激活系统密钥_Win11系统密钥激活
- windows 10应用商店区域怎么改_windo
- 如何在Golang中实现自定义Benchmark_
- Win11怎么退出微软账户_切换Win11为本地账
- 如何使用Golang table-driven f
- 如何在Golang中验证模块完整性_Golangg
- 网站内页做seo排名怎么做?
- Go 语言标准库为何不提供泛型 Contains
- PHP怎么接收前端传的时间戳_处理时间戳参数转换技
- Win11怎么更改电脑密码_Windows 11修
- Go 语言标准库为何不提供泛型切片的 Contai
- c# 如何用c#实现一个支持优先级的任务队列
- PHP的FastAdmin架构适合二次开发吗_特点
- Win11怎么调整屏幕亮度_Windows 11调
- C++如何使用std::optional?(处理可
- Python包结构设计_大型项目组织解析【指导】
- 手机php怎么转mp4_手机端php文件转mp4a
- Win10如何卸载微软拼音输入法 Win10只保留
- Python项目回滚策略_发布安全说明【指导】


QQ客服