如何排查ccache中哪些调用被判定为不可缓存?
排查ccache不可缓存调用的步骤与优化方案
1. 生成并分析ccache详细日志
先通过环境变量开启ccache日志,记录所有编译调用的缓存判定原因:
export CCACHE_LOGFILE=ccache_build.log # 清理之前的构建产物,重新触发完整构建 rm -rf build && mkdir build && cd build cmake .. -GNinja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ninja
构建完成后,过滤日志中的NOT CACHED条目,查看具体原因:
grep "NOT CACHED" ../ccache_build.log
常见的不可缓存原因包括:
preprocessor output differs:预处理后的代码内容变化(比如头文件内容、宏定义变化)compiler option differs:编译命令行参数不一致file changed:源文件或依赖的头文件被修改absolute path in preprocessed file:预处理输出包含绝对路径,导致不同构建目录缓存失效cache disabled:ccache被临时禁用
2. 检查Qt自动生成文件的编译逻辑
Qt项目中的moc、uic、qrc生成的文件容易导致缓存失效,需重点排查:
- moc文件:moc生成的代码可能包含绝对路径的
#include或生成时间戳注释,可通过CMake设置QT_MOC_OPTIONS强制使用相对路径:set(QT_MOC_OPTIONS "-i") # 强制moc生成相对路径的包含语句 - uic/qrc生成文件:这些文件的内容可能包含资源文件的绝对路径,确保CMake中使用
CMAKE_CURRENT_SOURCE_DIR而非绝对路径引用资源,或设置CCACHE_BASE_DIR统一路径基准。
3. 核对CMake编译配置细节
- 检查是否有编译选项包含动态变化的内容:比如
-D宏中嵌入时间戳、随机值或当前构建目录的绝对路径。用ninja -v查看具体编译命令,对比两次构建的命令行是否存在差异。 - 确保
CMAKE_CXX_COMPILER_LAUNCHER=ccache作用于所有编译目标:Qt自动生成的目标(如moc_xxx.cpp的编译)可能未继承该设置,可在CMake全局设置:set(CMAKE_CXX_COMPILER_LAUNCHER ccache) set(CMAKE_C_COMPILER_LAUNCHER ccache) # 如果项目包含C代码 - 避免在编译选项中使用绝对路径:将
-I包含路径改为相对路径(基于CMAKE_CURRENT_SOURCE_DIR)。
4. 调整ccache全局配置
- 设置
CCACHE_BASE_DIR统一路径基准,消除绝对路径对缓存键的影响:export CCACHE_BASE_DIR=$(pwd) # 在构建前设置,或写入~/.ccache/ccache.conf - 检查ccache配置是否禁用了缓存:执行
ccache -s查看配置,确保cache_dir存在且有读写权限,max_size足够容纳缓存文件。 - 忽略非关键的编译选项差异:如果某些选项不影响编译结果(如
-Wno-unused-parameter的开关),可通过ccache --set-config=ignore_options=-Wno-unused-parameter添加到忽略列表,但需确保不会破坏编译正确性。
5. 验证缓存效果
调整配置后,清理缓存并重新构建:
ccache -C # 清空现有缓存 rm -rf build && mkdir build && cd build cmake .. -GNinja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ninja
再次查看ccache统计:
ccache -s
对比可缓存调用比例是否提升,同时结合日志确认之前的不可缓存原因已解决。
内容的提问来源于stack exchange,提问作者RAM
相关产品推荐
相关产品推荐

