如何加快CMake缓存生成速度?常见优化方案与性能排查方法
CMake缓存生成耗时问题排查与优化方案
一、CMake缓存生成耗时的基准测试方法
- 使用CMake内置性能分析工具:CMake 3.18及以上版本提供原生profiling支持,执行配置命令时添加参数
--profiling-format=json --profiling-output=cmake_profile.json,生成的JSON文件会记录每个CMake函数、模块、宏的执行耗时,可直接定位到耗时最高的环节,比如某个find_package调用、自定义宏的执行等。 - 带时间戳的verbose输出:执行配置命令时添加
-DCMAKE_VERBOSE_MAKEFILE=ON参数开启详细输出,配合系统工具给每行输出加时间戳即可直观看到卡顿环节:Unix类系统可以用管道加ts命令(cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON | ts),Windows系统可以用PowerShell的Measure-Command结合输出来统计。 - 系统级耗时统计:仅需简单统计整体配置耗时的话,Unix类系统直接用
time cmake ..命令,Windows系统用PowerShell的Measure-Command { cmake .. }即可得到总耗时。
二、CMake缓存生成时间的常见优化点
- 升级CMake版本:高版本CMake对配置阶段的搜索逻辑、文件操作、内置函数做了大量性能优化,很多场景下仅升级CMake就能获得30%以上的配置速度提升。
- 优化
find_package搜索逻辑:这是绝大多数大型项目配置耗时的核心来源:- 精准指定依赖搜索路径,设置
CMAKE_PREFIX_PATH或者单个依赖的<PackageName>_DIR缓存变量,直接指向依赖的配置文件所在路径,避免CMake全局遍历磁盘搜索依赖。 - 避免重复搜索相同依赖,公共依赖的查找逻辑统一放到顶层CMakeLists中执行,不要在每个子项目里重复调用
find_package查找同一个依赖。
- 精准指定依赖搜索路径,设置
- 减少配置阶段的文件系统操作:
- 尽量避免用
file(GLOB_RECURSE)递归遍历大尺寸的源码目录、第三方依赖目录,优先显式声明源文件,确实需要用glob的话尽量缩小搜索范围。 - 非必要不要在配置阶段执行大量
file(READ)、file(WRITE)、execute_process调用,能放到构建阶段执行的逻辑就延后到构建阶段。
- 尽量避免用
- 复用缓存结果:
- 自定义的系统特性检查、编译特性检查、变量计算结果,用
set(变量名 变量值 CACHE INTERNAL "描述")缓存到CMake缓存中,避免每次配置都重复执行相同的计算。 - 开启编译器缓存工具(ccache、sccache),可以自动缓存CMake对编译器特性的检查结果,减少重复检查的耗时。
- 自定义的系统特性检查、编译特性检查、变量计算结果,用
- 关闭不必要的配置选项:开发阶段如果不需要编译测试、示例、文档、静态检查等功能,直接关闭对应的开关,比如
-DBUILD_TESTING=OFF、-DBUILD_EXAMPLES=OFF,大部分项目这些开关开启时会引入大量额外的配置逻辑。 - 优化子项目结构:避免过多层级的
add_subdirectory嵌套,不需要默认构建的子项目添加EXCLUDE_FROM_ALL参数,合并重复的公共配置逻辑到顶层CMakeLists,减少重复执行的冗余代码。
内容的提问来源于stack exchange,提问作者Zantox
相关产品推荐
相关产品推荐

