Ubuntu上CMake安装与卸载全攻略:APT、源码、预编译包与Conda对比 📅 2026/8/15 5:30:17 1. 为什么CMake在Ubuntu上这么“折腾”如果你在Ubuntu上搞过C/C项目尤其是那些从GitHub上拉下来的开源库那你对CMake肯定不陌生。它几乎是现代C项目的标配构建工具从LLVM、OpenCV到各种深度学习框架背后都离不开CMake的身影。但就是这个看似简单的工具在Ubuntu上的安装和卸载却常常让新手甚至老手都踩坑。你可能遇到过cmake: command not found或者更头疼的项目要求CMake 3.20而你系统自带的却是3.16编译直接报错。又或者你为了尝鲜装了最新版结果发现和某些老项目不兼容想退回旧版本却发现用apt remove之后系统里还残留着一堆东西下次安装时版本混乱。这背后的原因恰恰是Ubuntu软件包管理的“稳定”特性与开发者对“前沿”工具需求之间的矛盾。Ubuntu的官方仓库apt源为了保证系统稳定性提供的软件版本往往比较保守。而CMake作为一个活跃的开发工具新版本会频繁引入重要的新特性比如对C新标准的更好支持、改进的依赖查找机制等。这就导致了直接从apt安装的CMake版本经常落后于项目所需。因此在Ubuntu上管理CMake从来不是简单地apt install cmake就完事了你需要根据你的使用场景在“系统稳定”、“版本可控”和“管理便捷”之间做出权衡和选择。今天我就结合自己多年在Ubuntu上折腾C项目的经验把安装和卸载CMake的几种主流方式掰开揉碎了讲清楚。我们不止讲“怎么做”更重点讲“为什么这么做”以及“每种方式的坑在哪里”。无论你是需要为一个特定项目锁定某个CMake版本还是希望全局使用最新版或者是想在多版本间灵活切换这篇文章都能给你一个清晰的路线图。2. 基础操作使用APT包管理器这是最直接、最系统化的方式适合绝大多数只需要基础版本或对版本要求不高的用户。Ubuntu的APTAdvanced Package Tool体系设计精妙它处理的不仅仅是单个软件的安装更是一整套依赖关系的维护。2.1 APT安装CMake的核心逻辑当你执行sudo apt install cmake时背后发生了几件关键事情查询仓库APT会连接配置好的软件源默认为Ubuntu官方源查找名为cmake的软件包及其元数据。解析依赖树CMake本身可能依赖其他库如libssl、zlib等。APT会递归计算出需要安装或升级的所有软件包列表确保环境完整。下载与验证从源服务器下载.deb安装包并使用GPG密钥验证其完整性和真实性防止被篡改。解包与配置将包内文件解压到系统预定目录如/usr/bin,/usr/share并执行包内的预置脚本postinst来完成一些配置工作比如更新man手册页数据库。这个过程的优势在于自动化与安全性。所有文件都由Ubuntu官方或可信的维护者打包版本经过测试能与系统其他部分和谐共处。安装后CMake会直接位于/usr/bin/cmake全局可用。2.2 安装特定版本与潜在陷阱有时项目明确要求CMake 3.18而你的Ubuntu 20.04仓库里只有3.16。你可能会想到先查找有哪些版本可用apt-cache policy cmake或者搜索所有包含cmake的包apt-cache search cmake | grep ^cmake你可能会发现除了cmake还有cmake-data、cmake-curses-gui等。但关键在于官方源通常只提供一个主要版本。如果你想安装cmake-3.22大概率是找不到的。这时一个常见的“野路子”是添加第三方PPAPersonal Package Archive比如ppa:kitware/kitware-ppa它提供了更新的CMake版本。添加PPA并更新源后你就可以安装较新的版本了sudo add-apt-repository ppa:kitware/kitware-ppa sudo apt update sudo apt install cmake但是这里有一个必须警惕的陷阱第三方PPA的维护质量参差不齐。它可能会替换或升级你系统中一些关键的底层依赖库以适配其新版本的CMake。这有可能在无形中破坏系统其他软件的依赖关系带来难以预料的稳定性问题。对于生产环境或追求绝对稳定的系统我个人不建议轻易添加非官方PPA来升级核心构建工具。2.3 APT卸载的“干净”与“不干净”很多人认为sudo apt remove cmake就是卸载这其实不完全准确。remove指令只删除软件包本身安装的数据文件但保留其配置文件通常位于/etc目录下。这是为了方便你未来重装时保留自定义配置。如果你想连配置文件一并删除需要使用purge指令sudo apt purge cmake这个命令会将cmake包相关的所有文件和配置文件从系统中彻底清除。你可以通过以下命令来验证which cmake # 应返回空或“未找到” cmake --version # 应报错“命令未找到”然而APT卸载的“不干净”之处在于依赖处理。remove或purge默认不会删除那些被cmake依赖但现在已经不被任何其他程序使用的包即“未使用的依赖”。要自动清理这些“孤儿”包你需要sudo apt autoremove这是一个好习惯可以保持系统精简。但务必在操作前用sudo apt autoremove --simulate预览一下将要删除的包列表防止误删重要组件。注意autoremove是一把双刃剑。有时一个库可能同时被cmake和你手动编译安装的某个程序所使用。APT无法知晓手动安装程序的依赖关系因此autoremove可能会删除这个库导致你手动安装的程序崩溃。在执行前审阅列表至关重要。3. 进阶选择从源码编译安装当APT提供的版本无法满足需求且你不想冒险使用第三方PPA时从源码编译安装就成了最可靠、最灵活的选择。这种方式让你能精确控制版本、安装路径和编译选项。3.1 为什么选择源码编译版本自由你可以从CMake官网或GitHub发布页下载任何一个历史版本无论是为了兼容老项目还是尝鲜最新特性。路径隔离你可以将CMake安装到/usr/local、/opt或你自己的家目录下避免污染系统目录。这对于没有sudo权限的用户或者需要在同一台机器上维护多个CMake版本的情况尤其有用。定制编译你可以根据需求启用或禁用某些特性尽管CMake本身选项不多并针对你的CPU架构进行优化。3.2 详细编译安装步骤与原理剖析假设我们需要安装CMake 3.28.3以下是完整流程第一步准备工作——安装编译依赖CMake本身是C写的它的构建过程需要编译器如g和一些库。Ubuntu下通常需要sudo apt update sudo apt install build-essential libssl-devbuild-essential一个元包包含了gcc,g,make,libc-dev等编译必备工具。这是编译几乎所有C/C项目的起点。libssl-devCMake的某些功能如下载模块可能需要OpenSSL库的开发文件。即使不是必须预先安装也能避免后续可能出现的链接错误。第二步获取并解压源码前往CMake官网的 发布页面 找到cmake-3.28.3.tar.gz的源码包链接使用wget下载wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3.tar.gz然后解压tar -xzvf cmake-3.28.3.tar.gz cd cmake-3.28.3这里使用tar的-z选项是因为后缀为.tar.gz表示文件经过gzip压缩。如果是.tar.xz格式则需使用-J选项或先用xz命令解压。第三步配置构建系统——bootstrap脚本CMake的构建过程比较特殊它需要用已有的CMake或一个更基础的构建系统通常是./bootstrap脚本来构建它自己。这就是所谓的“自举”。./bootstrap --prefix/usr/local--prefix/usr/local这是最关键的一个参数。它指定了软件安装的根目录。编译产生的二进制文件会放在/usr/local/bin库文件在/usr/local/lib头文件在/usr/local/include。/usr/local是系统级别的本地软件安装目录通常不会被系统包管理器管理适合手动编译的软件。脚本会检查你的编译环境生成用于编译的Makefile。如果缺少关键依赖它会报错并停止。第四步编译与安装make -j$(nproc) sudo make installmake -j$(nproc)make开始根据上一步生成的Makefile进行编译。-j选项允许并行编译$(nproc)命令会获取你CPU的核心数从而启动相应数量的编译任务这能极大加快编译速度。sudo make install将编译好的文件二进制、库、文档等复制到--prefix指定的目录这里是/usr/local。因为/usr/local通常需要管理员权限写入所以需要sudo。第五步验证安装安装完成后打开一个新的终端让系统重新读取PATH环境变量然后验证which cmake # 应输出 /usr/local/bin/cmake cmake --version # 应输出 3.28.3如果which cmake仍然指向/usr/bin/cmake旧版本说明/usr/local/bin目录没有在PATH环境变量中排在/usr/bin之前。你可以通过echo $PATH查看路径顺序。通常/usr/local/bin的优先级是高于/usr/bin的如果不对可以检查shell配置文件如~/.bashrc。3.3 源码安装的“卸载”艺术从源码安装的软件没有像APT那样的包管理数据库记录。因此“卸载”意味着你需要手动删除所有安装时复制的文件。这就是为什么记录--prefix路径如此重要。卸载命令非常简单但前提是你还在源码目录内并且没有删除它# 假设仍在 cmake-3.28.3 目录下 sudo make uninstall如果Makefile中定义了uninstall目标这个命令会反向执行安装操作删除相关文件。但请注意并非所有源码包都提供uninstall目标。CMake的官方源码包是提供的这很友好。更常见也更彻底的手动卸载方法 如果你已经删除了源码目录或者该软件没有提供uninstall目标你就需要根据--prefix的路径手动清理。对于安装在/usr/local的CMake# 删除二进制文件 sudo rm -f /usr/local/bin/cmake /usr/local/bin/ctest /usr/local/bin/cpack /usr/local/bin/ccmake # 删除库文件如果有 sudo rm -rf /usr/local/lib/cmake-3.28 sudo rm -rf /usr/local/share/cmake-3.28 # 删除文档和手册页 sudo rm -rf /usr/local/share/doc/cmake sudo rm -rf /usr/local/share/man/man1/cmake.1.gz # ... 可能还有其他散落的文件具体取决于编译选项这种方式比较粗暴需要你清楚地知道安装了哪些文件。一个更稳妥的办法是在安装前记录下/usr/local目录下所有文件的时间戳或快照安装后再对比找出新增文件进行删除但这操作起来比较繁琐。个人心得对于像CMake这样的核心工具如果采用源码安装我强烈建议使用一个独立的、易于管理的安装前缀例如/opt/cmake-3.28.3。这样卸载时直接删除整个/opt/cmake-3.28.3目录即可完全不会影响系统其他部分。只需要将/opt/cmake-3.28.3/bin添加到你的PATH环境变量最前面。4. 灵活方案使用官方预编译二进制包这是介于APT的“稳定但旧”和源码编译的“灵活但繁琐”之间的一个绝佳平衡点。CMake官方为Linux提供了预编译的*.tar.gz包解压即用无需编译且版本非常新。4.1 预编译包的优势与适用场景优势极速部署下载解压即可使用省去漫长的编译等待编译CMake本身可能需要10-30分钟。版本即时官网总是提供最新的稳定版甚至候选版紧跟上游发布。环境纯净它是一个独立的文件夹所有文件都在内部与系统其他部分隔离。多版本共存可以轻松地在不同版本间切换只需修改PATH。适用场景你需要快速使用最新版CMake来测试一个项目。你的开发环境没有编译工具链如干净的Docker容器。你需要在同一台机器上为不同项目维护多个CMake版本。4.2 具体部署流程与环境变量配置以下载CMake 3.28.3的Linux x86_64版本为例第一步下载并解压到指定目录# 选择一个合适的目录例如 /opt 或家目录下的 tools wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.tar.gz sudo tar -xzvf cmake-3.28.3-linux-x86_64.tar.gz -C /opt这里我选择解压到/opt目录这是一个存放第三方应用软件的传统位置。第二步创建软链接或直接配置PATH有两种方式让系统找到这个CMake方法A创建符号链接适用于希望全局替换的情况sudo ln -sf /opt/cmake-3.28.3-linux-x86_64/bin/cmake /usr/local/bin/cmake sudo ln -sf /opt/cmake-3.28.3-linux-x86_64/bin/ctest /usr/local/bin/ctest sudo ln -sf /opt/cmake-3.28.3-linux-x86_64/bin/cpack /usr/local/bin/cpack这样当你调用cmake时系统会通过/usr/local/bin/cmake这个软链接找到/opt下的实际文件。注意如果之前通过APT安装了CMake/usr/bin/cmake可能依然存在。由于/usr/local/bin通常在PATH中先于/usr/bin被搜索所以软链接方式会优先使用新版本。你可以用which cmake确认。方法B修改用户环境变量更推荐更灵活编辑你的shell配置文件如~/.bashrc或~/.zshrc在文件末尾添加export PATH/opt/cmake-3.28.3-linux-x86_64/bin:$PATH然后执行source ~/.bashrc使配置生效。这种方式将自定义路径添加到了PATH的最前面系统会优先从这里查找命令。方法B的进阶用法——版本管理 你可以在~/.bashrc中定义一个函数或使用工具来动态切换版本。例如在/opt下同时有cmake-3.25.2和cmake-3.28.3两个目录# 在 ~/.bashrc 中添加函数 function use_cmake() { local version$1 local cmake_path/opt/cmake-${version}-linux-x86_64/bin if [ -d $cmake_path ]; then export PATH$cmake_path:$(echo $PATH | sed -e s|:/opt/cmake-[^:]*/bin||g -e s|/opt/cmake-[^:]*/bin:||g) echo Switched to CMake $version else echo CMake $version not found in /opt fi } # 默认使用3.28.3 use_cmake 3.28.3这样你可以在终端里通过use_cmake 3.25.2快速切换版本非常适合需要测试不同项目兼容性的场景。4.3 预编译包的卸载简单到极致卸载预编译包可能是所有方式中最简单的因为它是完全独立的。# 如果你放在了 /opt 目录下 sudo rm -rf /opt/cmake-3.28.3-linux-x86_64 # 如果你创建了软链接也需要删除它们 sudo rm -f /usr/local/bin/cmake /usr/local/bin/ctest /usr/local/bin/cpack # 如果你修改了 ~/.bashrc记得删除或注释掉添加的那行 PATH 配置 # export PATH/opt/cmake-3.28.3-linux-x86_64/bin:$PATH # 注释掉或删除删除目录和清理配置后该版本CMake就从你的系统中彻底消失了不会留下任何配置文件或依赖残留。5. 高阶技巧使用Conda环境管理如果你是一名数据科学家或机器学习工程师你的工作流里很可能已经包含了Anaconda或Miniconda。Conda不仅仅是一个Python包管理器它还是一个强大的跨平台环境管理器可以管理包括C/C工具链在内的任意软件包。5.1 Conda管理CMake的独特价值环境隔离这是Conda最大的优势。你可以为项目A创建一个环境安装CMake 3.20同时为项目B创建另一个环境安装CMake 3.25。两个环境完全隔离互不干扰。依赖解析Conda能自动解决软件包之间的依赖关系。安装CMake时它会自动安装合适版本的编译器、库文件等形成一个自包含的环境。跨平台一致性你的开发环境配置environment.yml可以在Linux、macOS甚至Windows上复现保证团队协作和持续集成的一致性。5.2 在Conda环境中安装与管理CMake首先确保你已经安装了Miniconda或Anaconda。然后可以按照以下步骤操作创建一个新的Conda环境并安装CMake# 创建一个名为 my_cpp_project 的新环境并指定Python版本可选 conda create -n my_cpp_project python3.9 # 激活该环境 conda activate my_cpp_project # 在激活的环境中安装特定版本的CMake conda install -c conda-forge cmake3.26.4这里使用了-c conda-forge指定从conda-forge频道安装。conda-forge是一个社区维护的频道软件包更新更及时版本也更丰富。Conda会自动处理所有依赖。在环境中使用CMake 环境激活后你执行的cmake命令就是该环境中的版本。你可以通过which cmake查看路径通常会指向~/miniconda3/envs/my_cpp_project/bin/cmake。管理多个版本 只需创建多个环境即可。例如conda create -n project_old cmake3.18 conda create -n project_new cmake3.28工作时用conda activate project_old或conda activate project_new来切换每个环境都有自己独立的CMake和工具链。5.3 Conda环境的“卸载”在Conda中“卸载”CMake有两种粒度1. 从当前环境中移除CMake包conda activate my_cpp_project conda remove cmake这个命令会从当前激活的my_cpp_project环境中删除cmake包及其专属依赖如果这些依赖没有被环境中其他包使用。2. 删除整个环境最彻底conda deactivate # 先退出待删除的环境 conda env remove -n my_cpp_project这个命令会删除整个my_cpp_project环境目录里面安装的所有包包括CMake、Python、以及任何通过Conda安装的库都会一并消失。这是最干净、最彻底的“卸载”方式。踩坑提醒Conda环境虽然隔离性好但要注意环境激活对终端的影响。有时在Shell脚本或CI/CD流程中如果没有正确激活环境会误用系统自带的CMake。一种可靠的做法是在脚本中直接使用环境的绝对路径如~/miniconda3/envs/my_cpp_project/bin/cmake。6. 实战排坑版本冲突与路径优先级问题无论采用哪种安装方式最终都可能面临一个共同的问题系统里存在多个CMake到底哪个会被调用这就是路径优先级和命令解析的问题。6.1 诊断当前生效的CMake当你在终端输入cmake系统会按照PATH环境变量中列出的目录顺序从左到右查找第一个名为cmake的可执行文件。# 1. 查看当前使用的是哪个cmake which cmake # 或更详细地 type -a cmake # 这个命令会列出所有能找到的cmake路径及其顺序 # 2. 查看当前PATH变量的顺序 echo $PATH | tr : \ntype -a cmake的输出非常有用它能告诉你所有同名命令的位置。排在第一位的就是终端实际会调用的那个。6.2 解决版本冲突的常见策略假设你通过APT安装了3.16又通过源码安装到了/usr/local3.28还通过预编译包在~/tools下放了3.25。type -a cmake可能会显示cmake is /usr/local/bin/cmake cmake is /usr/bin/cmake cmake is /home/yourname/tools/cmake-3.25.3/bin/cmake系统会使用/usr/local/bin/cmake3.28。如果你想使用预编译包的3.25有几种方法方法一临时使用绝对路径~/tools/cmake-3.25.3/bin/cmake -S . -B build这是最直接、最不会出错的方式特别适合写在脚本里。方法二调整PATH顺序在你的~/.bashrc中确保你想要的CMake路径排在前面。例如想优先使用家目录下的版本export PATH$HOME/tools/cmake-3.25.3/bin:$PATH注意如果/usr/local/bin也在PATH里且位置靠后它会被覆盖。添加后记得source ~/.bashrc。方法三使用别名alias在~/.bashrc中为特定版本的CMake设置一个短别名alias cmake325~/tools/cmake-3.25.3/bin/cmake这样平时用cmake命令默认版本需要3.25时就用cmake325命令。方法四使用update-alternatives系统级管理对于安装在系统目录如/usr/local的多个版本Debian/Ubuntu提供了update-alternatives工具进行集中管理。但这通常用于管理/usr/bin下的命令。对于手动安装的版本配置稍显复杂这里不展开但对于通过包管理器安装的多个版本如从不同PPA安装它是一个标准的解决方案。6.3 特定项目锁定CMake版本的最佳实践对于需要特定CMake版本的项目最专业的方法不是在系统层面折腾而是在项目层面指定。在CMakeLists.txt中声明最低版本这是最基本的要求。cmake_minimum_required(VERSION 3.18)如果系统CMake版本低于此要求配置阶段会直接报错提示清晰。使用版本管理器脚本许多大型开源项目如LLVM会在源码根目录提供一个CMakeLists.txt的同时提供一个configure或bootstrap.py脚本。这个脚本的首要任务就是检查并确保CMake版本符合要求如果不符合它会指导你如何安装或自动下载一个合适版本的CMake到本地构建目录中使用。你可以借鉴这种模式。容器化Docker为项目编写Dockerfile在镜像中安装指定版本的CMake。这保证了任何地方构建环境都完全一致是解决环境问题的最终极方案。在CI/CD中指定在GitHub Actions、GitLab CI等配置文件中明确使用安装了特定版本CMake的官方镜像或运行安装脚本例如# GitHub Actions 示例 steps: - uses: actions/checkoutv4 - name: Install CMake 3.25 run: | wget -qO- https://github.com/Kitware/CMake/releases/download/v3.25.3/cmake-3.25.3-linux-x86_64.tar.gz | sudo tar -xz -C /opt echo /opt/cmake-3.25.3-linux-x86_64/bin $GITHUB_PATH7. 如何彻底清理综合卸载与系统恢复当你尝试了多种安装方式系统可能已经有点混乱想要一个“干净”的起点时就需要进行一次综合清理。我们的目标是移除所有通过非系统包管理器方式安装的CMake并恢复系统APT仓库的版本如果需要。7.1 清理检查清单按照以下顺序操作可以最大程度确保清理干净第一步移除通过APT安装的CMake包括PPA版本# 1. 清除通过apt安装的cmake包及其配置 sudo apt purge cmake cmake-data cmake-curses-gui # 2. 如果你添加了Kitware等PPA建议也移除避免未来update时混淆 sudo add-apt-repository --remove ppa:kitware/kitware-ppa sudo apt update # 3. 执行自动清理移除不再需要的依赖 sudo apt autoremove --purge执行autoremove前务必确认列表防止误删。第二步查找并删除手动安装的二进制包检查常见的安装目录# 检查 /usr/local ls -la /usr/local/bin/cmake* /usr/local/bin/ctest /usr/local/bin/cpack 2/dev/null ls -la /usr/local/share/cmake-* 2/dev/null # 检查 /opt ls -la /opt/cmake-* 2/dev/null # 检查家目录下的工具目录 ls -la ~/tools/cmake-* ~/apps/cmake-* 2/dev/null找到对应的目录后使用sudo rm -rf命令删除。例如sudo rm -rf /opt/cmake-3.28.3-linux-x86_64 sudo rm -rf /usr/local/bin/cmake /usr/local/bin/ctest /usr/local/bin/cpack sudo rm -rf /usr/local/share/cmake-3.28第三步清理Conda环境如果使用# 列出所有环境 conda env list # 删除包含cmake的环境 conda env remove -n your_env_name第四步检查并清理环境变量编辑你的shell配置文件~/.bashrc,~/.zshrc,~/.profile等注释或删除所有添加CMake自定义路径的export PATH...行。特别是那些指向你刚才删除的目录的路径。第五步验证清理结果打开一个新的终端窗口执行type -a cmake which cmake cmake --version 21此时type -a cmake应该返回“未找到”cmake --version应该报“命令未找到”。这表示清理完成。7.2 恢复到一个已知的干净状态清理完毕后如果你仍然需要一个可用的CMake最推荐的方式是重新通过APT安装官方仓库版本这是最稳定、最易于管理的状态。sudo apt update sudo apt install cmake现在你的系统里只有一个由APT管理的、版本明确的CMake。对于需要其他版本的项目建议采用前面提到的“项目级”解决方案如使用预编译包并配置项目本地PATH或者使用Docker容器而不是再去污染全局系统环境。经过这样一轮彻底的清理和重构你对Ubuntu上CMake的管理应该有了更清晰的认识。核心思想就是系统级工具求稳用APT项目级需求求准用隔离方案预编译包、Conda、Docker。把握好这个原则就能在灵活性和稳定性之间找到最佳平衡点。