尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

修复STM32CubeIDE报错:cube-cmake.exe找不到CMAKE_ROOT的解决方案

修复STM32CubeIDE报错:cube-cmake.exe找不到CMAKE_ROOT的解决方案 1. 现象确认cube-cmake.exe 在每次 configure 时报 “Could not find CMAKE_ROOT”1.1 触发环境与复现步骤先说结论这不是你的工程写错了也不是 STM32CubeMX 生成的代码有问题而是 STM32CubeIDE 自带的 CMake 工具链组件stm32cube-ide-build-cmake 1.46.0在 Windows 上翻车了。具体表现是每次 configure 阶段cube-cmake.exe都会启动失败错误信息只有短短一句Could not find CMAKE_ROOT。我差不多花了一整个晚上才确认这个结论期间甚至怀疑过系统 CMake 被污染、项目路径有空格、杀毒软件拦截结果全部排除。我的环境是 Windows 10 21H2IDE 版本 STM32CubeIDE 1.15.1安装目录是默认的C:\ST\STM32CubeIDE_1.15.1所有组件都通过 IDE 自带的更新功能升到了最新。报错组件在 About 里显示为stm32cube-ide-build-cmake 1.46.0内部工具是cube-cmake.exe。手头有三个不同系列的工程STM32G431、STM32F103、STM32H745都是 CubeMX 生成的 CMake 工程所以现象非常有代表性。复现步骤也很简单打开 IDE导入或者新建 CMake 工程右键工程执行 Build ProjectIDE 会先自动运行 configure。然后控制台就会输出类似下面的内容[console] Running C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800\tools\bin\cube-cmake.exe -GUnix Makefiles ... Could not find CMAKE_ROOT Error: Program cube-cmake.exe failed注意这个错误发生在配置阶段还没真正进入编译所以不会出现任何.o文件也不会产生build目录下的 Makefile。每次 configure 都是 100% 复现不是偶发。1.2 重装工程不能救影响范围集中在 CMake 工程按照惯性思维我一开始以为是用某个工程的问题于是把工程里的build目录删掉重新生成没用再复制一份工程到纯英文短路径下照样报错最后直接在 IDE 里新建一个空的 STM32 项目仍然在 configure 阶段报同一个错误。到这一步基本可以确定问题不在工程而在全局工具链组件。如果你也做到了“新建工程也报同样错误”这一步就别再折腾 C/C Build 配置了直接往工具链环境方面查。还有个细节值得注意同环境下老的 Makefile 工程完全正常因为 Makefile 构建走的是gmake和arm-none-eabi-gcc和cube-cmake.exe没有关系。这个对比很关键它说明编译器、链接器、调试器、硬件仿真驱动都没有问题出事的只是 IDE 中负责 CMake 的封装层。1.3 版本升级是最大嫌疑我专门去确认了stm32cube-ide-build-cmake的版本变化。在升级到 1.46.0 之前我的 IDE 是 1.14.x插件版本为 1.45.xCMake 工程一直很正常。升级到 1.15.1 之后插件被更新到 1.46.0问题随即出现。所有工程不论芯片型号、生成方式、工作区位置全部中招。因此可以断定这是一个典型的版本回归 bug而不是环境配置问题。2. CMAKE_ROOT 究竟是什么cube-cmake.exe 的查找逻辑拆解2.1 不只是路径而是 CMake 的运行数据目录很多嵌入式工程师平时只把 CMake 当成一个“能用就行”的工具很少深究它的目录结构。实际上CMake 不是只有一个cmake.exe。在安装目录下除了bin里的可执行文件还有一个share目录里面存放着大量.cmake模块文件、模板文件、帮助文件。比如Modules/CMakeCInformation.cmake、Modules/FindPackage.cmake、Templates/里的项目模板都在这棵目录树下。CMake 在解析project()命令时需要加载这些内建模块。它怎么知道去哪找靠的就是 CMAKE_ROOT。CMAKE_ROOT 指向的就是share下面带版本号的目录例如C:\Program Files\CMake\share\cmake-3.28.1。这个目录里应当有Modules、Templates、Help等子目录。在 Linux 下这个路径通常类似/usr/share/cmake-3.22Windows 下用安装包安装的 CMake会自动记录到注册表或者在运行时根据cmake.exe的自身路径推导。如果你在命令行执行cmake --system-information输出结果里会有CMAKE_ROOT这一项它表示当前这个cmake.exe实际使用的数据目录。可以自己验证一下cmake --system-information 2nul | findstr CMAKE_ROOT正常情况下会打印出一个路径。CubeIDE 内置的 CMake 也可以这样查只要把cmake换成插件目录里的完整路径即可。2.2 cube-cmake.exe 是如何拿到 CMAKE_ROOT 的cube-cmake.exe并不是完整版的cmake.exe它是一个启动器或者说包装器。IDE 通过它来解析工程配置、把 Eclipse CDT 的构建信息转成 CMake 参数然后再调用同一个工具包里的cmake.exe去生成构建系统。这就引出一个问题cube-cmake.exe自己必须知道 CMAKE_ROOT 在哪里才能确保启动的 CMake 实例能加载正确的模块。正常版本的做法通常包括两个途径一是根据可执行文件自身路径做相对路径推导比如拿到cube-cmake.exe所在的bin目录往上一级找share/cmake-x.y二是读环境变量CMAKE_ROOT。前者是默认路径后者用于覆盖默认值或调试。在 1.46.0 这个版本里第一种路径推导明显失效了。程序拿不到默认值也没有 fallback 到注册表或者系统 CMake 安装路径于是它只能去查环境变量发现环境变量里也没有CMAKE_ROOT就直接报错。这个过程非常像某些软件启动时找不到配置文件程序不告诉用户它想找哪个文件只告诉你“配置根目录未找到”。用一个不太精确但容易理解的类比CMAKE_ROOT相当于一个程序存放语言包和皮肤文件的“资源根目录”。以前启动器默认知道资源就在自己旁边的share目录但新版本启动器把这个默认路径弄丢了又没有在系统环境变量里找到于是一启动就罢工。2.3 1.46.0 版本为什么把环境变量搞丢了我没有 ST 内部代码只能根据现象推测几个可能的回归点。第一插件打包路径结构可能变了。比如工具链从tools/bin和tools/share的平级结构改成了其他层级但cube-cmake.exe里的相对路径没有同步更新导致它解析出来的CMAKE_ROOT指向了一个不存在的目录于是程序就认为“根目录没找到”。第二捆绑的 CMake 版本可能从 3.24 升级到了 3.28而cube-cmake.exe里预编译的默认根目录还停留在旧版本号两者拼接后路径不对干脆报错。第三开发者可能为了减少 Windows 上对注册表的依赖把 CMake 根目录的发现逻辑改成了只读环境变量但忽略了在正常环境中要给这个变量设置一个默认值。不管具体原因是什么有一个事实很明确设置环境变量CMAKE_ROOT确实能绕过这个 bug。这说明程序至少在报错前还是会读取这个变量的。知道了这一点修复思路就清晰了。3. 最快修复手动指定 CMAKE_ROOT3.1 找到 CubeIDE 内置 CMake 的实际安装位置要设置CMAKE_ROOT首先得知道内置 CMake 放在哪。CubeIDE 的插件目录是C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins里面有一大堆跟工具链相关的插件。我们需要找的是名字类似com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800的目录。后面的数字是构建号不同日期可能不一样但前缀一定包含cmake.tools。进入这个目录后继续进入tools子目录一般会看到这样的结构com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.buildid └── tools ├── bin │ ├── cmake.exe │ └── cube-cmake.exe └── share └── cmake-3.28.1 ├── Modules ├── Templates └── Help注意这个结构不是 100% 保证但八九不离十。我们需要设置的CMAKE_ROOT是share下带版本号的子目录也就是...\tools\share\cmake-3.28.1不是tools目录也不是bin目录。验证方法很简单在文件资源管理器里打开这个版本子目录看里面有没有Modules文件夹。如果能看到Modules和Templates说明路径正确。在命令行里可以用dir C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.buildid\tools\share\cmake-3.28.1\Modules能列出大量.cmake文件就好了。3.2 把 CMAKE_ROOT 写到用户环境变量里找到路径后设置环境变量。右键“此电脑” - 属性 - 高级系统设置或者直接按Win R输入sysdm.cpl切到“高级”选项卡点“环境变量”。在用户变量区域新建一个变量变量名CMAKE_ROOT变量值C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800\tools\share\cmake-3.28.1保存后一定要重启 STM32CubeIDE而且不是单纯关闭窗口。Eclipse 系 IDE 会缓存启动时的环境变量如果你先开 IDE 再改环境变量它不会自动刷新。最稳妥的流程是关闭所有 IDE 窗口打开任务管理器确认stm32cubeide.exe进程已经退出然后重新启动。重启后重新执行 configure理论上就能通过。为了确认cube-cmake.exe本身已经恢复正常可以先在命令行里手动验证。打开 CMD执行set CMAKE_ROOTC:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800\tools\share\cmake-3.28.1 cd /d C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800\tools\bin cube-cmake.exe --version如果输出类似cmake version 3.28.1的内容说明启动器已经能找到 CMAKE_ROOT问题基本解决。之后再回 IDE 里 configure 就顺畅了。3.3 不方便改环境变量用批处理启动 IDE 应急有些公司电脑不允许修改系统环境变量或者你只想临时验证不愿意给全局留一个变量。这种情况下可以写一个批处理启动脚本在启动 IDE 之前把变量设置到当前进程环境里然后启动 IDE。echo off set CMAKE_ROOTC:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cmake.tools_1.46.0.202401190800\tools\share\cmake-3.28.1 start C:\ST\STM32CubeIDE_1.15.1\STM32CubeIDE\stm32cubeide.exe这种方式的局限是不能双击桌面图标启动必须从批处理启动才能继承变量。如果你在 IDE 运行期间又改了 CMake 工具链或升级了插件路径可能变化需要同步修改批处理里的路径。它只能作为应急不能长期依赖。4. 绕行方案与版本回退4.1 直接用系统 CMake 在命令行构建如果你暂时不想碰 IDE 的 CMake 封装层也可以绕开cube-cmake.exe直接用系统安装的 CMake 来构建 CubeMX 生成的工程。这个方法对 CI 环境特别有用。先在机器上装一个独立 CMake版本 3.22 以上即可再装 Ninja 或者直接使用Unix Makefiles生成器。以 CubeMX 生成的 CMake 工程为例在工程根目录打开终端执行cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILEgcc-arm-none-eabi.cmake -DCMAKE_BUILD_TYPEDebug cmake --build build不同 CubeMX 版本生成的CMakeLists.txt细节有差异有些会在工程内部指定 toolchain 文件有些需要你在命令行传。如果gcc-arm-none-eabi.cmake路径不对可以先在工程目录里搜一下一般在cmake/或CMake/子目录下。要注意的是手动 CMake 构建出来的东西虽然能出固件但调试器、下载器和 CubeIDE 的图形化配置不会自动关联。如果只是应急编译或跑 CI完全没问题如果还是要用 IDE 调试建议后面再用环境变量的方案修复。4.2 回滚 IDE 或锁定组件版本如果不想折腾环境变量也不急着用新功能最省心的办法是回滚版本。ST 的组件和 IDE 主版本是绑定比较紧的stm32cube-ide-build-cmake 1.46.0随 IDE 1.15.1 分发。单独卸载插件不太现实所以最简单的做法是直接装回上一版 IDE。操作前先备份 workspace然后把当前 IDE 卸载从 ST 官网下载 1.14.0 或 1.15.0 的安装包重新安装。装好之后到Help About Installation Details Plug-ins里确认组件版本不要高于 1.45.x。安装完成后在Preferences Install/Update Automatic Updates里取消自动更新防止又被推到 1.46.0。等 ST 发布修复版本后再手动更新。回滚的代价是可能会失去新版本里其他组件的修复比如编译器、调试器、芯片支持包。如果项目里用了新出的 MCU可能需要单独安装对应的固件包问题不大。如果你对 IDE 版本没有特别要求这条方案其实比设置环境变量更干净。4.3 偏门方案替换 cube-cmake.exe 为 shim这个办法比较 hack适合喜欢研究内部原理的工程师。思路是把插件目录里原来的cube-cmake.exe改名再用一个自己写的小启动器顶替它这个小启动器负责设置CMAKE_ROOT环境变量然后调用真正的 CMake。比如用 C 写一个简单的 shimSetEnvironmentVariableA(CMAKE_ROOT, ...\\tools\\share\\cmake-3.28.1); // 然后用 CreateProcess 调用真正的 cmake.exe把命令行参数原样传过去实际操作时要把原cube-cmake.exe改名成cube-cmake.real.exeshim 编译成cube-cmake.exe放到同一目录。CubeIDE 启动时调用的是 shimshim 设置好变量后再把工作转交给cmake.exe。这样等于把环境变量的问题自己接住了。但这里有几个坑第一插件目录有时候受权限保护改文件名需要管理员权限第二IDE 有可能校验 exe 的数字签名如果校验严格shim 方案直接失败第三ST 后续更新插件时会把目录内容覆盖你的 shim 可能被冲掉。所以这个方案只建议用来做实验不适合生产环境。5. 排查实录几个容易误判的细节5.1 设了 CMAKE_ROOT 还是失败先查这三处我设置完环境变量后第一次测试IDE 依然报错差点以为掉进另一个坑。后来发现原因很简单IDE 没完全退出环境变量没有刷新。所以如果你也遇到“设置了还是没用”优先按顺序排查首先确认路径填到了版本目录而不是share父目录。如果CMAKE_ROOT填成...\tools\shareCMake 会去share\Modules找模块但实际模块在share\cmake-3.28.1\Modules下会报出“找不到某个 .cmake 文件”或者默认编译器探测失败。这个错误比较隐蔽容易让人觉得环境变量没生效。其次确认 IDE 是从新环境启动的。推荐打开任务管理器把stm32cubeide.exe以及cube-cmake.exe全部结束甚至注销系统再登录一次避免进程残留。最后检查是否有旧版本的系统级CMAKE_ROOT在捣乱。Windows 变量优先级里用户变量会覆盖系统变量但如果系统变量里的旧路径不存在某些工具会在诊断时打印旧路径容易造成误导。干脆把系统变量和用户变量里所有 CMAKE_ROOT 都变成当前路径省心。5.2 验证 cube-cmake.exe 是否正常工作的两种方式我习惯先用命令行做最小化验证再回 IDE 里跑完整流程这样能快速区分是启动器的问题还是 IDE 调用参数的问题。第一种方式就是在命令行里临时设置环境变量后运行cube-cmake.exe --version。如果输出正常说明启动器本身能工作。第二种方式是用 Process Explorer 或系统自带的任务管理器看进程树。当 IDE 执行 configure 时观察cube-cmake.exe进程的完整路径确认它确实是从我们设置的那个插件目录启动的。如果从另一份旧的插件目录启动说明 IDE 加载的是另一个 CMake 工具链环境变量设错了地方。这个排查过程能帮你确认很多隐藏问题比如安装过多个 ST 工具链或者 IDE 的插件目录被复制过。5.3 给官方反馈时尽量附带的信息如果你希望 ST 赶紧修这个 bug去官方社区或 issue 系统提交反馈时不用写太长的故事把关键信息列全就好。我建议至少包含操作系统版本和位宽STM32CubeIDE 完整版本号以及stm32cube-ide-build-cmake的版本号错误弹窗或控制台日志的截图是否设置过 CMAKE_ROOT设置后的结果是否尝试回滚回滚到哪个版本后正常。标题建议直接写成stm32cube-ide-build-cmake 1.46.0: cube-cmake.exe reports Could not find CMAKE_ROOT on every configure这样别人一搜就能搜到。提交后可以顺便在个人博客或社区帖子里记录一下临时解决方案帮后来人节省时间。最后说一点个人体会。类似cube-cmake.exe这种启动器找不到内部路径的 bug修起来通常很简单但对用户的干扰非常大因为它把问题伪装成工程配置错误让人不断去翻 C/C Build 设置。我这次就是靠“新建工程同样报错老 Makefile 工程正常”这条线索五分钟定位到插件版本二十分钟解决问题。如果你也中招优先信任环境变量方案或者回滚版本别去改工程的 CMake 参数。等 ST 更新后记得把测试用环境变量删掉别给后续调试留隐患。
返回列表