当前位置: 首页 > news >正文

CMake 项目切换 Ninja 构建问题排查记录

CMake 项目切换 Ninja 构建问题排查记录

1. 背景

在 CMake 项目编译时,原先经常需要手动使用:

make-j

来启用并行编译。后来希望通过配置CMakePresets.json,改用 Ninja 构建系统,从而避免每次手动指定make -j

需要注意的是,这里应当是Ninja,不是Jinja

  • Ninja:C/C++ 项目常用的构建工具,CMake 可以生成 Ninja 构建文件。
  • Jinja:Python 模板引擎,和 CMake 并行构建无直接关系。

2. 目标

希望通过CMakePresets.json固定使用 Ninja:

{"version":8,"configurePresets":[{"name":"x64","displayName":"GCC 13.3.0 x86_64-linux-gnu","description":"正在使用编译器: C = /usr/bin/gcc, CXX = /usr/bin/g++","binaryDir":"${sourceDir}/out/build/${presetName}","generator":"Ninja","cacheVariables":{"CMAKE_INSTALL_PREFIX":"${sourceDir}/out/install/${presetName}","CMAKE_C_COMPILER":"/usr/bin/gcc","CMAKE_CXX_COMPILER":"/usr/bin/g++","CMAKE_BUILD_TYPE":"Debug","FETCHCONTENT_BASE_DIR":"${sourceDir}/.deps"}}]}

核心配置是:

"generator":"Ninja"

这样 CMake 会生成 Ninja 构建文件,而不是 Unix Makefiles。


3. 出现的问题

配置项目时报错:

CMake Error: Error: generator : Ninja Does not match the generator used previously: Unix Makefiles Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.

同时日志中还出现:

CMake Error at /usr/share/cmake-4.2/Modules/FetchContent.cmake:1916 (message): CMake step for libhv failed: 1

这说明不仅主项目可能存在旧缓存,FetchContent下载和构建的依赖项目也可能存在旧缓存。


4. 根因分析

CMake 的构建目录中会保存生成器信息。

如果某个目录之前用:

Unix Makefiles

配置过,之后又在同一个目录里改成:

Ninja

CMake 会拒绝继续配置,因为同一个构建目录不能混用不同 generator。

本次问题的关键点在于:

"FETCHCONTENT_BASE_DIR":"${sourceDir}/.deps"

项目把FetchContent的依赖缓存目录指定到了:

.deps

因此,虽然主构建目录可能已经清理过,但.deps里面的libhv子项目构建缓存仍然记录着旧的:

Unix Makefiles

当主项目切换到 Ninja 后,FetchContent重新配置libhv时就发生 generator 冲突。


5. 最终解决方法

删除.deps后重新生成即可:

rm-rf.deps cmake--presetx64

如果希望彻底清理,也可以同时删除主构建目录:

rm-rfout/build/x64rm-rf.deps cmake--presetx64

然后编译:

cmake--buildout/build/x64

如果配置了buildPresets,则可以使用:

cmake--build--presetx64

6. 推荐补充 buildPresets

原来的配置只包含configurePresets,这是可以正常使用的。

但为了让命令更统一,推荐补充buildPresets

{"version":8,"configurePresets":[{"name":"x64","displayName":"GCC 13.3.0 x86_64-linux-gnu","description":"正在使用编译器: C = /usr/bin/gcc, CXX = /usr/bin/g++","binaryDir":"${sourceDir}/out/build/${presetName}","generator":"Ninja","cacheVariables":{"CMAKE_INSTALL_PREFIX":"${sourceDir}/out/install/${presetName}","CMAKE_C_COMPILER":"/usr/bin/gcc","CMAKE_CXX_COMPILER":"/usr/bin/g++","CMAKE_BUILD_TYPE":"Debug","FETCHCONTENT_BASE_DIR":"${sourceDir}/.deps"}}],"buildPresets":[{"name":"x64","configurePreset":"x64"}]}

这样后续构建流程可以统一为:

cmake--presetx64 cmake--build--presetx64

7. 是否还需要 make -j

如果使用的是:

"generator":"Ninja"

通常不需要再手动写:

make-j

因为 Ninja 默认会自动并行构建。

如果仍然使用默认的 Unix Makefiles,则通常需要:

cmake--buildbuild-j

或者:

make-j$(nproc)

也可以使用 CMake 的通用并行参数:

cmake--buildbuild--parallel

或者设置环境变量:

exportCMAKE_BUILD_PARALLEL_LEVEL=$(nproc)

8. 后续排查建议

以后遇到类似错误:

Does not match the generator used previously

优先检查并清理以下目录:

rm-rfout/build/x64rm-rf.deps

如果明确只是FetchContent子项目出问题,通常只清理:

rm-rf.deps

即可。


9. 本次结论

本次问题不是CMakePresets.json配置错误,而是.deps中的FetchContent子项目缓存仍然保留了旧的Unix Makefilesgenerator 信息。

删除.deps后,CMake 重新下载并配置依赖,所有子项目都统一使用 Ninja,问题解决。

最终推荐使用:

cmake--presetx64 cmake--build--presetx64

并在项目中固定:

"generator":"Ninja"

这样后续不需要再手动执行make -j

10. 致谢

致谢土区GPT5.5: )

http://www.jsqmd.com/news/734647/

相关文章:

  • Admin.NET框架资料
  • AppImageLauncher完全指南:如何在Linux桌面上轻松管理AppImage应用
  • 告别第三方工具!手把手教你用vlmcsd在Windows Server上搭建私有KMS服务器,安全激活Office 2010 VOL版
  • MCP 2026量子环境适配避坑清单:从Linux内核4.19到5.15的cgroup v2调度缺陷、CUDA-Q驱动冲突、以及Rust 1.82+ ABI断裂点
  • Clawrma:为AI Agent设计的P2P任务网络,实现去中心化网页抓取与推理
  • 3个简单步骤:免费将VR视频转为普通设备可播放的2D格式
  • Laravel 12+ AI服务部署全链路:Docker多阶段构建、Swoole协程推理加速、GPU资源隔离(NVIDIA Triton实战手记)
  • Java常用工具类总结
  • 何意味
  • Git老手也容易迷糊?用Fork图解Rebase、Cherry-pick和Squash合并(含避坑指南)
  • K8S实战总结
  • 钉钉推DingTalk A1 Pro:充电宝版AI录音卡片,为商务人士解决录音与续航难题!
  • 原生闪退问题
  • 保姆级教程:用WTG在MacBook Pro上装Win11,解决驱动和卡顿的完整流程
  • 从 Ring Attention 到 DeepSpeed Ulysses,再到 USP 统一框架
  • 互联网大厂Java面试必问:Spring Boot、Spring MVC、WebFlux等主流Web框架深度解析
  • 北京市 CPPM 报名(美国采购协会)SCMP 报名(中物联)授权招生报名中心及联系方式 - 众智商学院课程中心
  • 抖音内容管理革命:如何用开源工具实现高效批量下载与智能归档?
  • 蓝桥杯选手如何用 Taotoken 快速接入大模型 API 辅助备赛
  • 别再死记硬背了!用STEP 7-MicroWIN SMART搞懂PLC定时器/计数器,看完这篇就够了
  • Android模块化开发避坑指南:我用ARouter踩过的那些‘雷’和填坑方案
  • 从零构建车载TSN协议栈:用ANSI C(无RTOS依赖)实现IEEE 802.1Qbv门控列表+802.1Qci流过滤器,附ASAM MCD-2MC兼容性测试套件
  • ok-ww:基于YOLOv8与ONNX Runtime的鸣潮游戏自动化工具架构解析与实战指南
  • 通过Taotoken CLI工具一键生成多款AI开发工具的配置文件
  • RK3568视频开发系列——rockit venc(2)
  • 2026年PMP报考条件与费用深度对比榜单TOP 5 - 众智商学院课程中心
  • Jeandle项目解析:基于LLVM的Java JIT编译器架构与实战
  • CVE-2026-31431:Linux 本地权限提升漏洞的受影响版本与修复情况
  • pymol作图,蛋白surface
  • Qt+VS2019编译报‘无法定位程序输入点’?别慌,这3个坑我帮你踩过了