多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

CMake安装避坑指南:Windows/Ubuntu/macOS配置与报错排查

CMake安装避坑指南:Windows/Ubuntu/macOS配置与报错排查 打开终端敲下cmake --version屏幕却回你一句“不是内部或外部命令”——这个画面我估计不少人都见过。网上讲 CMake 安装的中文教程不算少但很多教程只丢一个官网下载链接然后默认你已经知道装完要不要配环境变量、命令行里能不能直接敲、编译器又该怎么配对。结果就是教程看完了东西没装上或者装上了一编译就报错。这篇就专门解决“装 CMake”这件事把 Windows、Ubuntu、macOS 三条主流的安装路径全部走一遍再把装完之后最常见的验证方法、第一个小工程、以及CMakeDetermineCompilerId.cmake这类报错的完整排查思路一起讲清楚。内容定位是给零基础读者的但如果你已经在用 CMake只是换新机器时安装踩坑按 CtrlF 搜遇到的关键词也能直接找到答案。1. 装之前先弄明白三件事不然装完还是懵的1.1 CMake 不是编译器它是个“工程管家”这句话必须放在最前面因为九成新手障碍都来自概念混淆。CMake 本身不编译代码它做的事情是读取你的CMakeLists.txt配置文件根据当前的平台和编译器生成对应的构建文件比如 Makefile、Ninja 构建脚本、Visual Studio 工程文件然后由真正的编译器gcc、g、clang、MSVC 这些去做编译动作。用生活化的方式理解CMake 是餐厅前台的排号经理它根据你的口味平台和后厨资源编译器把一张菜单CMakeLists.txt转换成一张可执行的取餐单构建文件。真正炒菜的是后厨编译器但没有经理排号后厨根本不知道从哪道菜开始做。这个理解很重要因为后面排查问题时你会发现很多 CMake 报错并不是 CMake 本身坏了而是它找不到编译器、或者编译器环境有问题。你把 CMake 重装十遍也没用问题根本不在它身上。1.2 版本号没那么玄但也别见新就装CMake 的版本号一直在涨但实际使用中绝大多数场景只需要一个“够新且稳定”的版本。默认情况下我推荐这样判断只是跟着教程学语法、编自己的小项目用系统包管理器能装到的最新版本就行。要编译 OpenCV、Qt 这类大型项目或者有明确的最低版本要求查一下项目文档要求的最低 CMake 版本装一个比最低版本高一些的稳定版即可。开发库给老用户用cmake_minimum_required写低一点别让用户被迫升级 CMake。另外CMake 4.x 之后对某些旧特性的处理有变化老项目如果在 3.x 下编译正常、换到 4.x 却出问题可以把cmake_minimum_required指定为 3.16 或更低来触发兼容模式。这个细节等真的遇到再说安装阶段你只需要知道不是越新越好能稳定干活才是真好。1.3 二进制包和源码包多数人只用第一种官网下载页面提供两种主要形式一种是已经编译好的二进制发行包Windows 上是 .msi 或 .zipLinux 上有预编译的 .tar.gzmacOS 上是 .dmg另一种是源码包Source Distribution。对九成用户来说直接下载二进制包是最省事的路。源码包是为需要定制安装路径、或者系统架构特别的人准备的比如某些嵌入式交叉编译环境就得自己编。这篇主要讲二进制包的安装源码编译在 Ubuntu 那节也会提到因为那是不少服务器环境唯一可行的办法。这三件事想通了后面不管你用哪个系统装心里都有底。2. Windows 10/11 64 位环境下载、安装、配环境变量一条龙2.1 官网下载按钮到底点哪个Windows 用户直接从 CMake 官网的下载页找“Windows x86_64”那一栏。注意区分两类文件.msi安装包图形界面安装推荐绝大多数人用。.zip免安装包解压就能用适合不想装软件、或者绿色化部署的场景。64 位系统一定认准x86_64字样。搜索“cmake wind10 64位”很容易搜到一堆第三方下载站我的建议是一律不要碰。理由很简单第三方站点的文件可能版本旧、可能带捆绑安装而 CMake 官网下载本身通常也不慢没必要冒这个险。2.2 安装向导里那几个勾选别看都不看就点掉运行.msi后会进入安装向导。前面一路 Next 没问题但到了选择安装选项这一步有一个选项决定你后面会不会多吃半小时的苦Add CMake to the system PATH for all users有的版本写作Add CMake to the system PATH这个选项默认可能没勾必须手动勾上。它的作用是让系统在命令行里能找到cmake.exe。不勾的话安装完成后打开 CMD 或 PowerShell 输入cmake系统会直接告诉你“不是内部或外部命令”。另外安装路径我习惯改成C:\Program Files\CMake这类不含中文、不含空格的路径。虽然现代 CMake 对空格路径处理得还行但少给自己找麻烦总没错尤其是后面还要配合 Ninja、Visual Studio 一起用。2.3 装完怎么确认环境变量真正生效装完后不要立刻在当前窗口敲命令。如果你在安装之前就打开过 CMD 或 PowerShell这个窗口的环境变量还是旧的必须关掉重开一个新窗口。然后依次执行cmake --version如果输出类似cmake version 3.28.3这样的信息就说明成功。如果还是提示找不到命令按下面顺序排查打开“系统属性 - 环境变量”查看Path里面有没有C:\Program Files\CMake\bin这一项。如果没有手动添加然后重开命令行。如果有还是不行执行where cmake看看它实际从哪个路径加载可能是以前装的一个老版本抢占了 PATH。Windows 上还有一个高频坑以前装过 Visual Studio它的开发环境自带一份 CMake通常在 VS 安装目录里版本可能比较老。你在“Developer Command Prompt”里敲cmake时会优先用 VS 自带那个而不是你新装的。解决办法是用where cmake看清路径然后在 PATH 里把你新装的路径挪到前面或者就在普通 CMD 里测试不要混用窗口。2.4 zip 免安装方式的备选方案如果你选的是.zip版解压到一个目录后把解压目录\bin手动加到 PATH 即可。步骤一样系统属性 - 环境变量 - Path - 新建 - 填路径。这套方案的好处是卸载方便删目录就行适合不喜欢装软件的人。缺点是它不会自动更新以后要自己留意官网的新版本。提示改完 PATH 后所有已经打开的命令行窗口都不会自动刷新一定要重开。这是新手最容易反复踩的坑。3. Ubuntu/Linuxapt、源码编译、snap 三条路怎么选Linux 上装 CMake 的方法比较多样我按推荐程度和使用场景讲三条路。注意不要一上来就在论坛抄一个sudo apt install cmake完事——先想清楚你到底需要多新的版本。3.1 apt 安装省事但版本可能偏老Ubuntu 官方源里一直都有 CMake安装命令sudo apt update sudo apt install cmake这是最省心的方式依赖自动处理升级也方便。但它最大的问题是版本滞后。拿几个常见版本来举例Ubuntu 20.04 源里是 3.16.3Ubuntu 22.04 是 3.22.1Ubuntu 24.04 是 3.28.3。对大多数学习和小项目来说3.16 以上完全够用。但如果你的项目文档里写了cmake_minimum_required(VERSION 3.20)而系统源里只有 3.16那 apt 这条路就走不通。这时候你会需要下一种方式。3.2 源码编译安装指定版本以 3.16 为例很多老设备、嵌入式编译服务器都有“必须装某个特定版本 CMake”的需求。官网提供了源码包可以自己编译安装。下面以 Ubuntu 上装 3.16.9 为例把版本号换成你自己需要的即可先装编译依赖sudo apt update sudo apt install build-essential libssl-dev然后下载源码并编译wget https://cmake.org/files/v3.16/cmake-3.16.9.tar.gz tar -zxvf cmake-3.16.9.tar.gz cd cmake-3.16.9 ./bootstrap --prefix/usr/local make -j$(nproc) sudo make install./bootstrap是 CMake 源码包自带的初始化脚本它会检测系统环境并生成 Makefile。加--prefix/usr/local是明确安装位置别省。make -j$(nproc)里的$(nproc)会获取 CPU 核心数用来并行编译能快很多如果你机器内存小把它改成make -j2更稳不然编译器可能把内存吃爆。装完验证cmake --version如果系统里原来有旧版本新装的会在/usr/local/bin旧的在/usr/bin。输入which cmake看当前用的是哪个必要时把/usr/local/bin放到 PATH 前面。3.3 卸载和版本混乱怎么办apt 方式安装的可以直接sudo apt remove cmake源码方式安装的进到解压目录里执行sudo make uninstall也可以。但如果你当时没记录安装目录就得手动删/usr/local/bin/cmake、/usr/local/share/cmake-*等文件比较麻烦。所以我的建议是用源码方式装 CMake 之前先卸载掉 apt 的那个避免两个版本打架。判断是否冲突的办法which cmake cmake --version如果which cmake指向/usr/bin/cmake而你希望用/usr/local/bin/cmake可以通过修改 PATH 顺序解决或者干脆卸掉旧的。3.4 源码编译失败的常见原因源码编译 CMake 最常栽在两处一是缺libssl-dev。CMake 的源码包在编译过程中需要 OpenSSL 相关的头文件缺了会报找不到openssl/ssl.h一开始就装好依赖能省很多事。二是磁盘空间不足。编译 CMake 需要 1~2GB 左右的临时空间用df -h看一下/tmp和安装目录所在分区的余量再动手。另外如果你用的是 CentOS/RHEL 系的服务器依赖安装命令要换成yum install -y gcc gcc-c make openssl-devel其余步骤基本一致。3.5 snap 方式想要新版本又不想编译时的选择如果你的系统支持 snap可以sudo snap install cmake --classic--classic参数不能省因为 CMake 需要完全访问权限不加这个参数snap 的沙盒限制会干扰 CMake 正常工作。这种方式的好处是版本永远是官方的较新版本缺点是 snap 首次启动稍微慢一点而且在某些无头服务器上 snap 可能没启用。它算是一个不错的补充选项但不是我的首选推荐——优先级我给到apt够用的话 源码编译要特定版本 snap想省事要新版。4. macOSbrew 一条命令但背后还有两个细节4.1 Homebrew 方式干净利落macOS 上装 CMake 最主流的方式是 Homebrewbrew install cmake这个命令会自动装到较新的稳定版依赖也一并处理。装完直接验证cmake --version通常就能看到版本号。Homebrew 会把 CMake 装到/opt/homebrew/binApple Silicon或/usr/local/binIntel这两个目录一般都在 PATH 里所以不需要额外配置。这也是我推荐 brew 的原因省心。4.2 官网 dmg 安装别忘了装命令行链接没有 Homebrew 的可以去官网下载.dmg安装包拖拽安装路径默认是/Applications/CMake.app。但注意.dmg安装的 CMake其命令行工具可能不在默认 PATH 里需要在安装器里手动点一下“Install command line links”按钮。就算点了也建议在终端里执行一下/Applications/CMake.app/Contents/bin/cmake --version确认二进制真实存在。如果命令行还是找不到就把/Applications/CMake.app/Contents/bin加进~/.zshrc或~/.bash_profile的 PATH。4.3 Xcode 命令行工具macOS 上最容易被忽略的“编译器地基”macOS 上还有一个隐藏坑如果你只装了 Xcode 的命令行工具、没装完整版 Xcode用 CMake 生成构建文件时编译器链可能不完整。最简单的补救是执行一次xcode-select --install把命令行工具补上。这一步很多人容易忽略等 CMake 报找不到编译器时才反应过来。如果你执行后系统提示“already installed”那就没问题如果提示需要安装就按提示走完。补完之后再跑cmake编译器探测那一步就会顺畅很多。5. 装完别急着嗨验证安装和第一个 CMake 工程5.1 装好后应该看到的“健康指标”装完 CMake 后不只是看版本号我建议多确认两个信息cmake --version make --versionCMake 只是生成构建文件真正编译还离不开 make或者后面要说的 Ninja。Windows 上如果你想用 MinGW Makefiles 生成器还需要确保mingw32-make在 PATH 里如果你用 Visual Studio 生成器则要保证 Visual Studio 的生成工具已安装。macOS 和 Linux 上 make 通常已经预装但 Windows 原生环境里 make 往往是个缺口这也就是为什么很多人推荐 Windows 上直接配 Ninja。另外可以顺手看看 CMake 支持哪些生成器cmake --help输出列表里会列出当前环境下可用的生成器。如果你能看到Ninja、Visual Studio 17 2022或者Unix Makefiles说明对应工具链基本就绪。5.2 三步跑通第一个 CMake 工程学 CMake 安装最好顺手验证一下它真的能干活。准备一个文件夹放两个文件。main.cpp#include iostream int main() { std::cout Hello CMake std::endl; return 0; }CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(hello_cmake) add_executable(hello main.cpp)然后在终端进入这个目录依次执行mkdir build cd build cmake .. make如果cmake ..正常结束并生成 Makefilemake正常编译出hello可执行文件最后运行./helloWindows 上运行hello.exe能看到 “Hello CMake”那说明你从安装到最基本的构建链路全部通了。这一步别跳过很多人安装阶段过去了到编译时才发现编译器没配对后面排查更痛苦。6. 装完照样翻车CMakeDetermineCompilerId.cmake 这类报错的完整排查链路6.1 报错长什么样先还原一下现场。你在一个全新环境里执行cmake ..结果报出一长串其中一行可能是CMake Error at /usr/share/cmake-4.2/modules/CMakeDetermineCompilerId.cmake:9 (file): file STRINGS failed to read a string from [...]这类报错的一个关键特征路径里带着CMakeDetermineCompilerId.cmake。它其实是 CMake 在探测编译器时使用的一个模块文件。CMake 每到一个新项目第一件事不是编译你的代码而是先编译一个微型测试程序用来确认“当前环境里 C 和 C 编译器是谁、能不能正常工作”。这个微型测试程序的编译就是通过CMakeDetermineCompilerId.cmake模块来驱动的。所以报错往往意味着CMake 找不到编译器或者编译器存在但没法正常编译那个测试文件。注意不同系统、不同 CMake 版本这个文件的路径不一样。你的报错里路径可能是/usr/share/cmake-4.2/modules/...也可能是/usr/local/share/cmake-3.16/Modules/...或C:/Program Files/CMake/share/cmake-*/Modules/...。别纠结路径字样重点是这类报错都指向“编译器探测”这一步。6.2 排查链路先分清是“没找到”还是“不能用”遇到这种报错我建议按下面的顺序一步步走不要上来就重装 CMake很多人在这儿白折腾半天。第一步确认编译器本体在不在。Linux/macOS 上执行gcc --version g --versionWindows 上根据你计划用的工具链确认Visual Studio 的cl.exe、MinGW 的gcc.exe、或者 clang。如果编译器命令都不存在那问题根本不在 CMake先去装编译器。Linux 上执行sudo apt install build-essentialmacOS 上执行xcode-select --installWindows 上装 Visual Studio Build Tools 或完整的 MinGW-w64。第二步确认编译器能不能真的编译。自己写个hello.cpp手动执行g hello.cpp -o hello。如果这一步本身报错说明编译器环境有问题比如缺头文件、缺库、PATH 里的 gcc 是个残缺版本先把编译器修好再回 CMake。这一步能快速把问题范围缩小到“CMake 配置问题”还是“编译器环境问题”。第三步用 CMake 的命令行参数强制指定编译器试试cmake -DCMAKE_C_COMPILER/usr/bin/gcc -DCMAKE_CXX_COMPILER/usr/bin/g ..Windows 上用 MinGW 时生成器要选对cmake -G MinGW Makefiles -DCMAKE_C_COMPILERgcc -DCMAKE_CXX_COMPILERg ..如果显式指定编译器后能通过说明 CMake 的自动探测被什么因素干扰了比如 PATH 里同时存在多个编译器或者某个环境变量遮蔽了编译器路径。6.3 具体原因与对策根据我接触过的案例CMakeDetermineCompilerId.cmake相关报错主要有这么几个原因原因判断方法对策编译器未安装gcc --version提示命令不存在安装 build-essential / VS Build Tools / Xcode 命令行工具编译器装了但被 PATH 遮蔽which gcc指向奇怪路径如用户目录下的旧版本清理冲突版本或显式指定编译器路径编译器本身坏了手动g hello.cpp -o hello失败重装编译器检查缺的库和头文件32 位和 64 位不匹配报错里出现64和32字样统一安装 64 位工具链删除 32 位残留磁盘空间不足df -h发现空间已满清理空间CMake 探测也需要临时目录杀毒软件拦截Windows 常见报错随机、重跑有时能过把工作目录加入白名单或临时关掉再测生成器选错Windows用了 MinGW 生成器但实际没有 MinGW改用 VS 生成器或装 MinGW-w64 再重试逐一排查基本都能解决。记住一条这类报错的根因九成不在 CMake 本身而是它背后的编译器环境不健康。你重装十遍 CMake 都没用先把编译器收拾利索了CMake 自然就安静了。7. 装好 CMake 之后这些“下一步”才是重点7.1 为什么越来越多人推荐 Ninja如果你经常逛开源项目的构建文档会发现现在很多项目在 README 里写的是cmake -G Ninja而不是传统的cmake ..make。Ninja 是一个比 Make 更轻量、更快的构建工具定位就是“给大型项目的高效构建用的”。它对增量编译的处理更好多核并行调度更聪明编译大型项目时提速明显。而且它跨平台效果好Windows 上不需要模拟 Make 的那种别扭环境配好编译器后体验很顺。如果你要学习的项目推荐用 Ninja安装很简单。Ubuntu/Debiansudo apt install ninja-buildmacOSbrew install ninjaWindows 上可以用pip install ninja或者从 Ninja 的官方发布页下载把ninja.exe放进 PATH。装完后用 CMake 时指定生成器cmake -G Ninja .. ninja此时 CMake 生成的是build.ninja文件ninja命令执行真正的编译。第一次跑和make的感觉区别不大但项目大了之后差距就出来了。7.2 编译 OpenCV 这类大型项目时的注意事项网上关于“opencv cmake 编译步骤”的搜索热度一直很高。OpenCV 源码包下载下来后官方推荐的就是用 CMake 配置构建选项。典型命令大致是mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE -D CMAKE_INSTALL_PREFIX/usr/local .. make -j$(nproc) sudo make install这里面-D CMAKE_BUILD_TYPE和-D CMAKE_INSTALL_PREFIX都是 CMake 的通用变量前者决定优化级别后者决定安装路径。如果你要从零编译 OpenCV建议先查清楚依赖如 ffmpeg、Eigen 等装全了没有不然 CMake 配置阶段会跳过一些模块导致后面部分功能缺失。另外编译 OpenCV 是个体力活耗时可能以小时计内存小的机器注意控制并行度。7.3 Qt 项目转 CMake多模块结构从哪里入手现在 Qt 官方的新示例基本都用 CMake 而不是 qmake 了。Qt 项目的顶层CMakeLists.txt通常会这样组织cmake_minimum_required(VERSION 3.16) project(my_app) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) qt_standard_project_setup() add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)如果你看到的是一个大型 Qt 工程顶层CMakeLists.txt往往只负责find_package和add_subdirectory把每个模块的编译下放到子目录里各自的CMakeLists.txt。想看懂这类项目前提就是你先把 CMake 的基本语法和安装环境搞明白。所以把安装这关过了后面的学习曲线才能踩实。7.4 顺手聊一句Keil 工程怎么和 CMake 扯上关系嵌入式圈子里有人问“如何将 Keil 工程变成 cmake”。原理其实不复杂Keil 工程文件.uvprojx描述的是一堆源文件、头文件路径、编译选项而 CMake 同样能描述这些东西所以可以写一个CMakeLists.txt把 Keil 里的源文件列表、宏定义、include 路径平移到 CMake 的target_sources、add_definitions、target_include_directories中再用合适的交叉编译工具链如 arm-none-eabi-gcc去构建。这种迁移在自动化构建、脱离 Keil 做命令行编译时很有价值。不过这个话题展开讲能写两万字这里只提一句它和本节的 Ninja、OpenCV、Qt 一样都是“把 CMake 装好之后才有资格谈”的进阶能力。8. 写在最后的实际建议最后分享几点我这些年装 CMake 攒下的真实体会。第一安装过程中所有“临时性”的修改都要留记录。比如你改了 PATH、装了某个依赖我建议顺手写进一个备忘录或小脚本因为换新电脑时你会感激自己当初的记录。比如我自己的装机脚本里就固定了这么三行Windows 用 Chocolatey 装 CMake 并自动加 PATHmacOS 跑brew install cmakeUbuntu 则用源码编译装到固定版本。每台机器装出来都一样后面出问题也特别好沟通。第二碰到报错先读完整英文信息别急着复制粘贴去搜。CMake 的报错信息虽然长但关键行通常就在最上面或最下面比如 “could not find any instance of Visual Studio” 这种已经足够你定位方向了。把报错从头读到尾比你盲目搜一段碎片信息有用得多。第三很多人装完 CMake 就把它扔在一边遇到问题先怀疑是 CMake 的锅。我的经验是CMake 是一个异常稳定的工具绝大多数“CMake 报错”其实都是编译器、依赖库或环境变量的问题。下次再看到CMakeDetermineCompilerId.cmake这类报错先按第六节的顺序查编译器比重新装 CMake 高效得多。另外给初次接触的人一个建议不要一上来就追求“最新版”也不要一上来就学一大堆高级语法。先把安装和环境验证这关过了写一个能输出 “Hello CMake” 的小工程再慢慢接触add_library、target_link_libraries、find_package这些东西路径会顺畅很多。行了安装这件事聊到这也就够用了。打开终端试一下把第一条命令跑通剩下的都是水到渠成的事。
返回列表