CMake --build --preset与直接指定构建目录的性能差异问题
问题结论
两种构建方式本应性能一致,你遇到的耗时差异不是配置错误,是CMake 3.20~3.22版本针对Visual Studio生成器的已知实现bug。
差异产生原因
两种构建命令最终都会调用MSBuild执行构建,但你使用的CMake 3.21.2版本对build preset的参数处理存在冗余逻辑:
- 经典目录指定方式:
cmake --build G:\.bld -j会直接透传参数给MSBuild,仅指定构建目录和并行数,无额外前置逻辑。 - build preset方式:当preset配置了
cleanFirst: true且使用VS生成器时,低版本CMake会在正式构建前额外触发一次全量项目依赖拓扑扫描,需要遍历你所有1500个子项目的依赖关系、校验每个项目的配置有效性,这个过程完全在MSBuild内部执行,所以表现为无输出但CPU高负载,就是你遇到的5~6分钟延迟。
另外你在preset中配置的jobs: 0和命令行传递的-j参数存在冲突处理逻辑,低版本CMake会重复计算并行数并给MSBuild传递重复的调度参数,进一步放大了额外开销。
修复方案
- 优先方案:升级CMake到3.23.0及以上版本,该bug已经在该版本被官方修复,冗余的拓扑扫描逻辑被移除,两种构建方式的性能基本一致。
- 若无法升级CMake,可任选以下临时方案:
- 移除build preset中的
jobs: 0配置项,并行数完全由命令行-j参数传递,可减少40%左右的额外扫描开销 - 在build preset中显式添加
"targets": ["ALL_BUILD"]配置,强制CMake直接指定构建目标,跳过全量项目遍历步骤 - 继续使用经典的指定构建目录的构建方式
- 移除build preset中的
内容的提问来源于stack exchange,提问作者Solo
相关产品推荐
相关产品推荐

