Linux下安装CMake全指南:包管理器、二进制包与源码编译实操详解

发布时间:2026/9/16 22:07:12
Linux下安装CMake全指南:包管理器、二进制包与源码编译实操详解 本来不觉得这是个值得单独写一篇的东西但最近连续碰到好几个同事和网友在 Linux 上装 CMake 时踩坑有人卡在“cmake: command not found”有人装完了发现版本太旧还有人源码编译的时候被依赖折腾到怀疑人生。想想还是把这几年在不同 Linux 环境下折腾 CMake 的经验整理一下按不同场景给出不同的安装方式顺便把版本选择、环境变量、卸载重装这些容易忽略的细节也讲清楚。这篇内容不挑发行版Debian/Ubuntu、CentOS/RHEL、Arch 系都能用从一条命令装的懒人方案到源码编译的老实人方案全覆盖。无论你是刚接触 Linux 的新手还是在配 CI 服务器、搞嵌入式交叉编译的老手应该都能在里面找到自己需要的那一节。1. 装之前先想明白的几件事1.1 CMake 到底是个什么角色先给刚入门的朋友垫个底。CMake 本身不是编译器它是一个跨平台的构建系统生成器。你写的是 CMakeLists.txt描述“这个项目有哪些源文件、要链接哪些库、要不要开某个宏”CMake 根据这套描述生成对应平台的构建文件——在 Linux 上默认是 Makefile也可以生成 Ninja 文件在 Windows 上可以生成 Visual Studio 工程在 macOS 上生成 Xcode 工程。换句话说CMake 解决的是“同一套代码在不同平台上怎么编译”的问题。理解了这一层你就能明白为什么举着源码包到处编译的人那么多也就能理解为什么版本问题这么敏感CMakeLists.txt 里写的某些语法、某些函数老版本根本不认识。我见过最典型的情况是项目写了个target_link_directories然后 expect 结果在 CMake 3.13 以下直接报“Unknown CMake command”排查到最后发现就是系统自带版本太老。1.2 不同发行版自带包的差异Linux 发行版基本都自带 CMake 包但版本新旧天差地别。Ubuntu 18.04 自带的是 3.10.2Ubuntu 20.04 自带 3.16.3Ubuntu 22.04 自带 3.22.1。Debian stable 系通常更加保守CentOS 7 自带的 2.8.12 更是老古董级别。CentOS 8 / Rocky Linux 8 稍微好点但也只有 3.20 左右。这直接决定了你需要用哪种安装方式。如果你的项目对 CMake 最低版本要求是 3.16Ubuntu 20.04 上直接 apt 装就行但 Ubuntu 18.04 上就得另想办法。所以在动手之前先确认两件事你的 Linux 发行版是什么你的项目要求 CMake 最低版本是多少。先跑一句cat /etc/os-release看系统再去项目文档里找cmake_minimum_required那一行基本就知道走哪条路了。1.3 版本号里的信息量CMake 版本号是三位主版本、次版本、补丁号比如 3.27.6。从 3.0 之后主版本一直没有变化实际影响兼容性的是次版本号。我自己的习惯是能装新一点就装新一点但也不用盲目追最新。最新版本通常意味着对最新语言标准比如 C20/23 模块支持最好但有时候旧项目在太新的 CMake 上反而会有一堆 deprecation 警告。折中的方案是装当前次版本线里较新的补丁版本比如 3.27.x 或者 3.28.x既保证功能完整又相对稳定。2. 最快的方式包管理器直接装2.1 Debian/Ubuntu 系Debian 系的安装命令是最简单的sudo apt update sudo apt install cmake装完验证一下cmake --version三行搞定。但要注意如果某个 PPA 或者官方源里的版本太旧而你项目要求高版本直接 apt 装完是没法用的。这时候三条路换 PPA只推荐 Ubuntu不推荐 Debian、用官方二进制包、源码编译后面都会讲到。另外提一句apt 装在 Ubuntu 上会同时把 cmake-data 这个包拉进来移除的时候也要两个一起处理否则可能出现 dpkg 依赖混乱的情况后面“卸载/重装”那节细说。2.2 RHEL / CentOS / Rocky Linux / AlmaLinux 系RedHat 系分两派老一点的 CentOS 7 用 yumCentOS 8 及之后的 Rocky/Alma 9 用 dnf。命令逻辑跟 apt 一样# CentOS 7 / RHEL 7 sudo yum install cmake # CentOS 8 / Rocky 8 / Alma 8 sudo dnf install cmakeCentOS 7 那个 2.8.12 版本确实坑了不少人。遇到这种情况我建议直接跳到源码编译或者官方二进制包不要去折腾第三方源。EPEL 里的 CMake 版本会新一点但也是杯水车薪不解决根本问题。2.3 Arch / Manjaro 系sudo pacman -S cmakeArch 系滚动更新的优势在这就体现出来了装的通常是相当新的版本基本能覆盖绝大多数项目的需求。用 Arch 的场景我基本上从来没为 CMake 版本发过愁。2.4 包管理器方案的优缺点包管理器装 CMake 的最大优势是后续卸载、升级都跟系统包管理走不会留下乱七八糟的文件。缺点是版本不可控发行版源里是什么版本你就得用什么版本哪怕差了好几个大版本。这里想额外提醒一点不要随便在系统层把 CMake 替换成网上找的“最新版”尤其是当你同时还在用 ROS、某些 SDK、或者系统里其它依赖 CMake 的软件时。它们很可能依赖系统包管理器的 CMake 版本存在的某个行为。如果你为了一个项目升级了全局 CMake结果别的软件挂掉排查起来非常痛苦。我的习惯是全局用系统包管理器版本特定项目需要新版本时用虚拟环境/容器或者装到用户目录互不干扰。3. 最灵活的方式官方二进制包直接解压用3.1 为什么说这是“性价比最高”的方式官方会在 cmake.org/download 提供编译好的 Linux 二进制包格式是 .tar.gz解压就能用不依赖系统包管理器想放哪放哪想装几份装几份。这种方式在我看来是“性价比最高”的比源码编译省事得多又比包管理器版本可控得多。版本号自己选下载完直接指向你解压的目录就好。适用范围非常广dev 容器里、CI 环境里、普通开发机上都可以这么干。尤其在 CI 里我几乎都是用官方二进制包因为每次拉下来的环境是固定的源码一检查就版本一致不会出现“本地能编 CI 挂掉”的尴尬。3.2 具体操作步骤这个方案的本质是把官方打包好的二进制当“绿色软件”用不写入系统目录只通过 PATH 环境变量让 shell 能找到它。第一步下载对应架构的包。绝大多数 x86_64 服务器和桌面用这个链接格式wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1-linux-x86_64.tar.gz如果你用的是 ARM 机器Apple Silicon 的虚拟机、树莓派、鲲鹏服务器把链接里的x86_64换成aarch64即可。官方其实也做了这一套二进制不用自己编。第二步解压到指定目录。我习惯统一放/opt/cmake下面方便集中管理sudo mkdir -p /opt/cmake sudo tar -zxvf cmake-3.28.1-linux-x86_64.tar.gz -C /opt/cmake注意这里解压出来会是一个带版本号的目录比如/opt/cmake/cmake-3.28.1-linux-x86_64/。第三步做软链接。把bin下的命令软链到/usr/local/bin这样普通用户也能直接执行——当然前提是/usr/local/bin在 PATH 里默认都在sudo ln -sf /opt/cmake/cmake-3.28.1-linux-x86_64/bin/cmake /usr/local/bin/cmake sudo ln -sf /opt/cmake/cmake-3.28.1-linux-x86_64/bin/ctest /usr/local/bin/ctest sudo ln -sf /opt/cmake/cmake-3.28.1-linux-x86_64/bin/cpack /usr/local/bin/cpack如果不想动系统目录也可以改用户级 PATH在~/.bashrc或~/.zshrc里加上一行然后source ~/.bashrcexport PATH/opt/cmake/cmake-3.28.1-linux-x86_64/bin:$PATH两种方式各有利弊。软链接到/usr/local/bin对所有用户生效适合机器上就你一个人或者团队都用的场景改用户级 PATH 更“无侵入”想切回系统版本时把这一行注释掉就完事适合多版本并存的日子。3.3 怎么管理多个 CMake 版本用官方二进制包管理多版本有一个很自然的思路每个版本一个目录用软链接切换。比如/opt/cmake/cmake-3.28.1-linux-x86_64/和/opt/cmake/cmake-3.27.9-linux-x86_64/并存改一下软链接指向就是切版本。我实际工作中常碰到这种场景项目 A 是旧的必须用 3.16 编译项目 B 要上 C20 新特性需要 3.27 以上。以前我折腾过update-alternatives后来发现那东西配置起来反而是负担。现在就用最简单粗暴的“软链接切换法”脚本里写清楚当前指向哪个版本想换就改链接一分钟搞定。如果你有更复杂的需求比如同一时刻不同终端用不同版本更推荐用虚拟环境方案而不是在全局来回折腾。4. 最“正统”的方式源码编译安装4.1 什么时候必须源码编译如果只图省事、能用前面几种方案都够了。但有些场景你必须走源码编译官方二进制包里没有你要的架构比如某些 MIPS、RISC-V 开发板或者你想深度定制 CMake 自身的功能特性再或者你用的发行版太老旧工具链连官方二进制包都跑不起来。还有一个隐藏场景某些安全要求严的环境里不允许直接执行从网上下载的二进制必须从源码审计后自己编译。这时候源码编译就是唯一选择了。4.2 预备条件依赖和基础工具源码编译的依赖其实不多但缺了哪个都会在某个阶段报错我把常见的列一下。Debian/Ubuntu 系sudo apt install build-essential libssl-dev libcurl4-openssl-devRedHat/CentOS 系sudo dnf install gcc gcc-c make openssl-devel libcurl-devel为什么要这些因为 CMake 自身是用 C 写的编译它需要完整的 C 工具链而 CMake 的 HTTP 下载、SSL 支持等功能依赖 libcurl 和 OpenSSL如果没有这些库编译出的 CMake 在file(DOWNLOAD ...)这类功能上就会受限。4.3 完整实操流程以 3.28.1 为例从官网下载源码包wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1.tar.gz tar -zxvf cmake-3.28.1.tar.gz cd cmake-3.28.1CMake 用了 bootstrap 脚本替代传统的 configure步骤是./bootstrap --prefix/usr/local--prefix指定安装路径默认就是/usr/local。如果你不想覆盖系统自带的 CMake可以换成--prefix/opt/cmake-3.28.1或者--prefix$HOME/.local。bootstrap 过程快慢取决于机器性能一般几分钟到十几分钟不等期间会看到一堆检查信息这是正常的别一看输出一堆就以为报错退出来。只要最后能看到类似 “CMake 3.28.1, Copyright ...” 和 “-- Build files have been written to” 这类提示就算通过。接下来编译和安装make -j$(nproc) sudo make install-j$(nproc)是让 make 用所有 CPU 核心并行编译能在很大程度上缩短编译时间。我实测在 8 核的机器上从零编译 CMake 大约需要 5 到 10 分钟单核的话可能要等半小时以上。装完验证cmake --version如果输出里出现系统自带的旧版本号说明 PATH 里旧版本优先检查一下是不是有别的安装路径抢在了/usr/local/bin前面。4.4 源码编译的坑与心得源码编译最容易踩的坑集中在这几个地方。第一bootstrap 阶段报 “C compiler cannot create executables”。这基本就是 C 编译器没装全或者版本太老。Debian 系跑sudo apt install build-essentialRedHat 系跑sudo dnf groupinstall Development Tools然后再重新 bootstrap。第二bootstrap 报找不到 OpenSSL 头文件。解决方案就是前面列的那些依赖包装上再继续。有些精简容器镜像里连make都没有更别提编译器先补齐再开工。第三提示缺 GCC 特定版本。如果你还在用 CentOS 7 默认的 GCC 4.8那 CMake 3.28 的源码是编译不过去的它对 C 标准要求更高。老系统上要么用官方二进制包要么先升级工具链两者之间我强烈推荐前者省得引出更多系统级改动。5. 几个容易被忽略的安装途径5.1 pip 安装 CMake这听起来有点魔幻但实际上确实有人这么干CMake 官方通过 Python 包索引PyPI发布了cmake这个包pip install cmake之后它会往site-packages目录里放一个功能完整的 CMake 可执行文件。pip install cmake然后执行时注意这个可执行文件在 Python 的bin目录下不一定在 PATH 里。你可以python3 -m cmake --version或者找到路径后加软链接。什么时候用这个方案我主要在两个场景用它一是某些容器环境里已经有大套 Python 生态顺手pip install cmake比 apt 快很多二是你正在用某个 Python 虚拟环境希望在这个环境里绑定 CMake 版本防止污染系统目录。5.2 容器镜像里的预装版本如果你主要在 Docker 容器里干活官方镜像其实已经帮你处理好了绝大多数情况。比如python:3.11这个官方镜像自带 CMakeubuntu镜像没有但你可以在 Dockerfile 里写RUN apt-get update apt-get install -y cmake或者直接用带 CMake 的镜像FROM alpine:latest RUN apk add cmake在容器里建议优先用包管理器因为容器本来就是轻量级的一次性环境不需要为“多版本共存”这类问题操心。镜像重新拉一遍成本并不高没必要在 Dockerfile 里做源码编译这种重活——除非是某些精简到极致的镜像没有预编译好的包。5.3 交叉编译场景下的 CMake嵌入式 Linux 开发比如 ARM 开发板对 CMake 的安装方式没有特殊要求但有一个容易踩的坑宿主机的 CMake 版本最好不要低于目标平台工具链文档要求的版本。某些交叉编译工具链比如比较老牌的 ARM GCC 工具链自带的.cmake配置文件有最低版本要求如果宿主机的 CMake 太旧会在 configure 阶段直接报错或者生成错误的构建文件。交叉编译时通常会把工具链的 toolchain 文件传给 CMakecmake -DCMAKE_TOOLCHAIN_FILE../toolchain-arm.cmake ..这个 toolchain 文件里经常用到一些较新的函数或变量所以这种情况下 CMake 版本优先级会很自然地偏向新版。建议这种需求直接参考上面官方二进制包的方式快速把 CMake 升级到足够新的版本。6. 安装后必做的验证与配置6.1 验证是否安装成功不管用哪种方式装装完第一件事就是检查版本cmake --version输出大致长这样cmake version 3.28.1 CMake suite maintained and supported by Kitware (kitware.com/cmake).如果只输出了版本说明安装本身没问题。但这还不算完我的习惯是继续做一次真实的 mini 项目验证确认 CMake 能真正跑起来而不只是在 PATH 里能找到。mkdir -p /tmp/cmake-test cd /tmp/cmake-test cat CMakeLists.txt EOF cmake_minimum_required(VERSION 3.10) project(cmake_test C) add_executable(main main.c) EOF cat main.c EOF #include stdio.h int main() { printf(cmake ok\n); return 0; } EOF cmake . make ./main看到cmake ok输出说明这个 CMake 跟系统里的编译器配合没问题。这一步能排查出很多隐藏问题比如 PATH 顺序导致调了旧版本或者编译器版本和 CMake 不兼容等等。6.2 环境变量与 PATH 里面的坑如果你用包管理器装的不需要关心 PATH系统都配好了。如果你用官方二进制包或源码编译到自定义目录就要注意 PATH 的顺序问题。查看当前 PATHecho $PATH系统默认把/usr/local/bin放在/usr/bin前面。如果你把 CMake 软链到了/usr/local/bin它会优先于系统包管理器装的那个。如果你改的是用户级 PATH比如在~/.bashrc里export PATH/opt/cmake/cmake-3.28.1-linux-x86_64/bin:$PATH那这个路径会排在所有系统路径前面优先级最高。另外一个常见误区是sudo之后 PATH 不生效。你用自己的用户改了~/.bashrc里的 PATH直接敲cmake能找到但sudo cmake可能报 command not found因为 sudo 默认清理了 PATH。这不是你安装有问题是系统安全机制。解决方法是要么sudo visudo修改 secure_path要么在 sudo 时手动指定完整路径要么直接用sudo env PATH$PATH cmake ...。我自己的经验是尽量别为这事去改 secure_path因为会破坏 sudo 默认的安全策略还是手动指定完整路径或者软链到/usr/local/bin更踏实。6.3 多版本并存的本质问题多版本并存这个话题值得单独拎出来说。很多人一上来就想到update-alternatives但它在处理 CMake 这种“简单命令替换”的场景下其实有点杀鸡用牛刀。而且它管理的是某个命令名到具体路径的映射数据存在系统目录里如果不小心删了 /etc/alternatives 下的链接反而容易搞乱。我更推荐两种方式。一种是软链接切换法/usr/local/bin/cmake这个软链接指向不同版本的二进制想切版本就换链接。简单、直观、一眼就能看懂当前用的是哪个。另一种是CMake preset 结合自定义工具链在项目根目录建CMakePresets.json里面可以指定每个 preset 用哪个 CMake 可执行文件{ version: 3, configurePresets: [ { name: release-3.28, displayName: Release with CMake 3.28, cmakeExecutable: /opt/cmake/cmake-3.28.1-linux-x86_64/bin/cmake, generator: Ninja, binaryDir: ${sourceDir}/build/release } ] }然后跑cmake --preset release-3.28。这种方式最优雅也很适合团队协作中统一 CMake 版本。不过我猜大部分人短期内用不到这个知道有这么个东西就行。7. 常见问题与排查技巧实录7.1 问题速查表收集了这些年我在社区和实际工作中见过的几类高频问题整理成一张速查表方便你遇到问题直接对号入座。症状常见原因解决方案cmake: command not found或bash: cmake: 未找到命令未安装、PATH 未配置、sudo 环境清空 PATH先apt install cmake/ 检查/usr/local/bin是否在 PATH / 手动指定绝对路径执行版本太旧configure 阶段直接报错发行版自带版本过老不满足cmake_minimum_required用官方二进制包或源码编译装新版建议至少 3.16configure 时提示找不到某个 CMake 函数/变量CMake 版本低于项目要求升级 CMake可通过项目文档里的cmake_minimum_required行判断最低版本要求源码编译时 bootstrap 报 C 编译器不可用缺 build-essential 或 Development Tools补齐编译工具链后重新 bootstrapbootstrap 报无法找到 OpenSSL缺 libssl-dev / openssl-devel安装对应依赖后重新 bootstrap源码编译完成后cmake -version还是旧版PATH 里旧版本目录排在前面或没覆盖/usr/local/binwhich cmake查看实际路径调整 PATH 顺序或删掉旧的链接升级 CMake 后旧项目 configure 有大量 deprecation 警告CMake 新版本对旧写法有废弃警告不是错误不用慌有兴趣可配合cmake --warn-uninitialized等开关逐步定位修正CentOS 7 上用 yum 装完只有 2.8.12官方源版本就是老的不要折腾 yum 源换官方二进制包或源码编译同一台机器不同项目需要不同 CMake 版本全局只有一个版本官方二进制包各自放不同目录用软链接或 preset 切换后各项目独立配置sudo cmake提示找不到命令但普通用户能执行sudo 的 secure_path 清掉了用户 PATH不要改 secure_path使用完整路径或sudo env PATH$PATH cmake7.2 排查流程先定位是哪一层的问题遇到 CMake 装好了但用不了的情况我强烈建议按这个顺序排查别一上来就重装系统。第一步确认命令到底在哪which cmake如果输出为空说明确实没装或者 PATH 里没有如果输出在某个不期望的路径比如/usr/bin/cmake而你想用的是/opt/cmake/...那就是 PATH 优先级问题。第二步确认实际版本cmake --version第三步看 CMake 的实际路径里有没有内容ls -l /usr/bin/cmake /usr/local/bin/cmake 2/dev/null第四步检查系统库里是否装了多份 CMakefind /usr /opt $HOME -name cmake -type f 2/dev/null这四个命令基本能定位 90% 的问题。剩下的情况再考虑是不是包管理器状态损坏dpkg 或 rpm 检查异常或者环境变量被某个配置脚本意外覆盖了。拿我上次帮同事排查的一个案例来说他死活觉得 CMake 装好了但一跑就报“没有这个命令”排查了一圈发现是他在~/.bashrc里后面写了一句unset PATH然后又重新拼了一个不含/usr/local/bin的 PATH。这种问题单纯重装 CMake 一百次也没用。7.3 卸载 CMake 的正确姿势卸载这件事放到最后说是因为有些人装了半天发现装错了版本或者装失败了然后想重来结果卸载步骤不对导致下一次安装更混乱。如果用 apt/dnf/pacman 装的卸载就是反向操作# Debian/Ubuntu sudo apt remove cmake # 如果连配置文件一起清掉不推荐日常用 sudo apt purge cmake注意 Ubuntu 上 cmake 和 cmake-data 这两个包经常一起出现移除时建议一起处理避免留下版本不一致的状态sudo apt remove cmake cmake-data如果是源码编译装的卸载方式比较原始进入当时编译的源码目录cd cmake-3.28.1 sudo make uninstall前提是你还留着这个源码目录。如果目录已经删了那就只能手动删掉安装路径下的文件比如/usr/local/bin/cmake、/usr/local/share/cmake-3.28等。这就是为什么我推荐官方二进制包删除时就一个rm -rf /opt/cmake/cmake-3.28.1-linux-x86_64的事干净利落。如果那个“不存在的 CMake”是历史残留的软链接指向一个已经不存在的二进制直接删软链接就好不影响其他文件sudo rm /usr/local/bin/cmake7.4 关于“Windows 下提示不是 cmdlet 或程序名”的简短提示热门搜索词里有一条很典型的 Windows 报错“无法将‘cmake’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。虽然这篇讲 Linux但这个错误在原理上跟 Linux 的 command not found 有很强的共通性都是 PATH 没配置或者没安装好命令在 shell 里找不到。如果你在 Windows 上也用 CMake记得把 CMake 的 bin 目录比如C:\Program Files\CMake\bin加到系统 PATH 变量里。把 Linux 的命令搞明白了Windows 的这个问题其实也能触类旁通。8. 一些个人选择和建议坦白说我自己的 CMake 安装经历大致分三个阶段。最早用 Ubuntu 时一直apt install cmake觉得一切都顺理成章直到第一次在 CentOS 7 上碰壁才意识到“发行版自带的版本可能相当老”。后来开始用官方二进制包把 CMake 当便携软件用这个习惯一直保留到现在尤其是 CI 环境我几乎必用官方二进制包把 CMake 版本这一项完全固定下来这才真正消灭了“本地上传代码后 CI 挂了”这类问题。现在换到个人开发机上我的建议是日常开发就用发行版包管理器自带的 CMake项目要求新版本时再针对性使用官方二进制包或源码安装。这套组合下来系统包管理器的干净和版本的灵活性我都占了。最后分享两个小细节。一个是源码编译安装成功后在终端里敲几条cmake --help之类的命令感受一下新版本命令补全如果你配了 bash completion是否正常很多环境里 CMake 命令补全依赖单独安装的扩展并不随 CMake 本身自动生效。另一个是如果你在配置一些大型项目比如 LLVM、OpenCV、Boost时遇到版本告警先别急着换 CMake去项目的官方文档里看一下他们建议的版本区间在区间内选一个稳定的版本往往比一味追新更靠谱。CMake 这个工具本身并不复杂复杂的是你身处的项目生态对它的要求。把安装这事彻底捋顺了后面配置项目、加第三方库、写 CI 流程才会顺手很多。希望这篇内容能帮你少踩几个坑省下时间专心去写代码。