从源码编译安装新版 CMake:解决版本过低与 PATH 配置问题
2026/9/7 3:10:34 网站建设 项目流程

简介:CMake 3.24.0 源码包,面向需要从源码构建或定制CMake的C++开发者、系统集成与构建系统维护人员,主要解决多编译器、多平台环境下构建配置复杂、依赖管理繁琐的问题。该版本在跨平台构建、依赖检测与测试集成方面表现稳定,适合在Linux/Unix环境中通过bootstrap、make等流程自行编译部署,也可作为学习CMake内部机制与研究CMakeLists编写范式的参考素材。整个压缩包约9.91MB,内含约2000个文件,核心类型包括txt说明文档、cmake构建脚本、rst文档以及大量C/C++头文件与源文件,整体目录结构清晰,文档部分便于查阅使用说明,脚本与源码则呈现了完整的构建逻辑与实现细节。已有425人学习下载。通过这份源码,开发者能够获得一套可编译的完整构建树,深入理解add_executable、find_package、add_library等命令背后的实现逻辑,同时可以复用其官方测试用例与CMake模块,为自身项目的跨平台构建配置和持续集成提供有价值的模板与排错思路。 前几天在一台老旧的 Linux 服务器上部署一个内部项目,configure 阶段直接弹了一句CMake 3.16 or higher is required. You are running version 2.8.12.2。系统包管理仓库里的 CMake 版本早就被冻结在远古时代,没办法,我只能去官网下载cmake-3.24.0.tar.gz源码包手动编译安装。整个过程不算难,但中间有几个点特别容易踩坑,比如校验、PATH 优先级、版本冲突,还有编译到一半才发现缺依赖。这篇就完整记录一下我是怎么从拿到 tar.gz 到最终跑出新版本 CMake 的,给同样被老环境逼到手动编译的朋友做个参考。

1. 为什么系统包管理器里的 CMake 总是不够用

1.1 发行版稳定策略和实际需求之间的落差

用 apt 或 yum 装 CMake 确实方便,一条命令就完事。但很多生产环境用的都是长期支持发行版,比如 CentOS 7 或者 Ubuntu 18.04,这类系统的软件源为了保证整体稳定性,往往会把版本号锁得很低。CentOS 7 自带的是 CMake 2.8.12.2,Ubuntu 18.04 最多到 3.10.2,而现代 C++ 项目,尤其是这两年基于新标准重写的工程,通常会要求 3.16 甚至 3.20 以上。这个落差不是个小问题,它不是一个"能用就行"的差异,而是新写的target_precompile_headersCMAKE_CUDA_ARCHITECTURESFetchContent增强这些功能在旧版本里根本不存在。

我当时遇到那个项目报错时也想过,要不要直接升级系统的 cmake 包。但仔细一看,系统里有好几个软件包是依赖/usr/bin/cmake的,如果直接卸载或者替换旧版本,可能会把系统工具链搅乱。更稳妥的思路是源码安装到一个独立目录,然后通过 PATH 控制用哪个版本。这正是cmake-3.24.0.tar.gz这类官方源码包的典型用途。

1.2 源码包适合什么场景

源码编译适合几种情况。一是没有 root 权限,或者不想污染系统环境,想装到用户目录;二是项目对 CMake 版本有明确要求,而官方 apt 源里的版本不满足;三是服务器架构特殊,比如 aarch64 或者自定义交叉编译环境,官方预编译二进制不一定能用。源码包的好处是足够“干净”,你完全控制安装路径,不依赖系统包管理器的依赖关系。

不过也别误会,源码编译不是唯一选项。CMake 官网除了cmake-3.24.0.tar.gz源码包之外,还提供了cmake-3.24.0-linux-x86_64.tar.gz这种平台二进制包。如果你只是日常使用,不关心怎么从源码构建,那直接下二进制包解压配置 PATH 就行。我这次选择源码包,一方面是想保证和系统的 libc、编译器兼容,另一方面也是想顺便看一下新版 CMake 的 bootstrap 机制有没有变化。

1.3 旧版本带来的实际报错

版本过低最常见的报错就是开头那段:CMake X.Y.Z or higher is required. You are running version x.y.z。有些项目还会在cmake_minimum_required上做额外判断,版本不够直接FATAL_ERROR。还有一些更隐蔽的情况,比如target_precompile_headers这个命令在旧版里根本没有,configure 时不报错,编译到一半才提示 command not found,排查起来更费劲。

所以如果你也遇到这类问题,别急着去改项目的 CMakeLists 文件来绕开检查。正确做法是安装一个满足要求的新版 CMake,然后确保命令行里实际执行的是那个新版。这个“实际执行”说起来简单,实际上后面配置 PATH 时最容易出问题,我会在第 4 部分细讲。

2. 下载与校验:解压之前先做三件事

2.1 版本选择:3.24.0 能覆盖哪些需求

下载之前先确认版本号是否满足项目要求。我用的cmake-3.24.0在 2022 年 8 月发布,对当时主流项目的 3.16、3.18、3.20 要求都能满足。它支持CMP0074CMP0130这一堆策略,对FetchContentfile(GENERATE)CUDA的支持也很完善。

需要注意一点:CMake 源码包命名很简单,就是cmake-版本号.tar.gz。如果你不想自己编译,下载页面还有带平台后缀的二进制包,比如cmake-3.24.0-linux-x86_64.tar.gz。两者的区别在于前者是源代码,需要先编译才能用;后者解压出来就能跑。这次我选择源码包,但如果你要装的环境是内网没有外网,又不想带一堆编译依赖,可以提前在官网把对应平台的二进制包拉下来。

另外,CMake 每个大版本后面还有小补丁版本,比如 3.24.1、3.24.2。如果项目没有强制要求 3.24.0 这个名字,建议能拿最新补丁就拿最新补丁,因为修了不少 build 层面的 bug。我当时因为构建脚本里写死了这个文件名,所以还是用了 3.24.0。

2.2 下载方式和官网地址

下载地址我习惯用官网的 files 目录:https://cmake.org/files/v3.24/cmake-3.24.0.tar.gz。直接 wget 就行:

wget https://cmake.org/files/v3.24/cmake-3.24.0.tar.gz

如果服务器没有外网,也可以在自己电脑上下载,再通过 scp 或者 U 盘拷贝进去。这个包不到 10 MB,传起来很快。顺便说一句,官网首页的 Download 按钮跳转的是 GitHub 的 release 页面,文件名和官网 files 目录是一致的,但考虑到生产环境网络策略,我一般优先用 cmake.org 官方地址,避免被 GitHub 的跳转搞得很慢。

2.3 校验哈希和 GPG 签名

下载完成后第一件事不是解压,而是校验文件完整性。这一步很多人会跳过,但真不能省。源码包体积不小,传输过程可能出错,哪怕一个字节损坏,后面 bootstrap 或 make 阶段都会出现莫名其妙的报错,排查起来比重新下载还浪费时间。

官方在同一个目录下提供了.sha256文件,下载后校验:

sha256sum -c cmake-3.24.0.tar.gz.sha256

如果输出OK,说明哈希一致。更严格的校验是用 GPG 签名文件.asc验证签名,但很多场景下 sha256 已经能拦住传输错误。我个人建议至少做 sha256,如果是从 GitHub 或者镜像站下载,那签名验证就更重要了,因为镜像不可控。

2.4 编译前的依赖确认

源码编译 CMake 需要几样东西:C/C++ 编译器、make、openssl 开发头文件。前两个不用多说,gccg++make都要装好。openssl 那块比较特殊,CMake 在 bootstrap 阶段会检测 OpenSSL,用于支持 HTTPS 下载相关功能。如果没有,bootstrap 会自动把相关功能关掉,不会直接报错,但之后某些模块可能功能不完整。

所以我通常先确认一下:

gcc --version g++ --version make --version

在 Debian/Ubuntu 系上如果缺依赖,就执行:

sudo apt install build-essential libssl-dev

CentOS 上对应的是yum install gcc gcc-c++ make openssl-devel。编译前把这些装好,能省去后面一半的排错功夫。

3. 从 tar.gz 到可执行文件:完整的源码编译过程

3.1 解压命令与目录规划

拿到cmake-3.24.0.tar.gz之后,解压是第一步。最常见的命令是:

tar -zxvf cmake-3.24.0.tar.gz

这里z表示解 gzip 压缩,x表示解压,v是显示解压文件列表,f后面跟文件名。如果不想要那么多输出刷屏,可以换成tar -zxf cmake-3.24.0.tar.gz。新版 tar 其实会自动识别压缩格式,直接tar -xf cmake-3.24.0.tar.gz也可以。

解压出来的目录名就是cmake-3.24.0。我一般会把它放到/tmp下编译,因为源码编译会生成大量临时文件,放/tmp不占用家目录空间,装完之后删掉也省事。但要注意,/tmp在某些系统上可能被清空,如果编译到一半机器重启,你可能要重新解压,所以根据自己的环境取舍。

还有一个细节:编译产物默认放在源码目录里,所以解压后要先cd cmake-3.24.0,再执行后面的命令。如果目录已经存在残留的编译缓存,建议先清理一下:

rm -rf CMakeCache.txt CMakeFiles

避免上次的缓存干扰这次构建。

3.2 用 bootstrap 脚本生成构建系统

进入目录后,核心命令是:

./bootstrap --prefix=/opt/cmake-3.24.0

这个bootstrap脚本是 CMake 自己写的一个“自举”过程。因为 CMake 本身太复杂,不能一步到位用 CMake 构建,所以脚本会先生成一个最小化的临时 CMake 可执行文件,再用这个临时 cmake 去配置和构建完整版本。类似“先有鸡还是先有蛋”的问题,用一个小鸡先孵化出整只鸡。

--prefix指定安装目录。这里我建议不要直接设成/usr/local,而是用一个带版本号的独立目录比如/opt/cmake-3.24.0或者$HOME/opt/cmake-3.24.0。这样以后切换版本、删旧版本都清晰,不会跟系统自带版本混在一起。

如果你的机器核数多,想让 bootstrap 也并行跑,可以加--parallel=4,或者后面在 make 阶段用-j。bootstrap 本身很快,主要时间花在后面的正式编译上。

3.3 make 与 make install

bootstrap 执行完后,会生成 Makefile。接下来就是常规操作:

make -j$(nproc)

-j是并行编译参数,$(nproc)返回 CPU 核心数。如果你的编译器版本比较老,或者机器内存不大,-j$(nproc)可能会因为同时编译太多文件导致内存爆掉,进程被 kill。这时候可以保守一点,用make -j2make -j4

编译过程中会有大量警告,大部分是从系统头文件来的,只要不中断就问题不大。整个编译在我的四核服务器上大概跑了八九分钟,如果你的机器更强,两三分种也可能完成。等 make 结束,确认没有报错,再执行:

sudo make install

如果--prefix使用的是用户目录,比如$HOME/opt/cmake-3.24.0,那就不需要 sudo。安装完成后,可以看一下安装目录的结构:

ls /opt/cmake-3.24.0/bin

里面应该有cmakectestcpack这几个主要可执行文件。cmake-gui默认不会编译,除非你安装了 Qt 相关依赖,这也说明源码包安装的默认路径确实轻量。

3.4 额外构建选项和性能控制

如果你明确不需要 OpenSSL,可以在 bootstrap 时直接禁用,避免因为依赖缺失导致某些功能静默关闭:

./bootstrap --prefix=/opt/cmake-3.24.0 -- -DCMAKE_USE_OPENSSL=OFF

不过我认为一般不需要,能装 openssl 就装上。还有一个选项是--no-qt-gui,强制不构建图形界面。默认情况下只要检测不到 Qt,它也不构建,所以通常不用手动加。

这里有一个小坑:如果你在 bootstrap 之后发现编译选项想调整,不要重新执行./bootstrap,而是直接rm -rf CMakeCache.txt CMakeFiles,重新 bootstrap,不然旧配置会污染新配置。编译失败也一样,先看错误输出,再用make clean或者清缓存重来。

4. 安装完成不等于能用:PATH 配置与版本验证

4.1 敲 cmake --version 还是旧版本的根因

装完新 CMake 之后,你可能会兴冲冲地敲cmake --version,结果发现输出还是老的 2.8.12.2。我第一次编译 CMake 时就遇到这个问题,第一反应是“安装失败了”,其实安装完全成功,问题是 shell 执行的cmake还是/usr/bin/cmake

原因很简单:/usr/bin在 PATH 里的优先级通常低于/usr/local/bin,但你可能既没有把/opt/cmake-3.24.0/bin加到 PATH,也没有对系统里的旧 CMake 做替换。shell 按 PATH 顺序找第一个叫cmake的可执行文件,找到/usr/bin/cmake就用旧版。

所以安装完第一件事应该看which cmake,确认它指向哪里。如果指向/usr/bin/cmake,说明新版还没接管。可以用hash -r清一下 shell 的命令缓存,因为 bash 会把之前找到的命令路径缓存下来,即使 PATH 更新了也可能继续用旧路径。

4.2 配置 PATH 的三种方式

临时使用可以这样:

export PATH=/opt/cmake-3.24.0/bin:$PATH

这条命令只对当前终端会话生效,关掉就没了。想持久化,就把这一行加到~/.bashrc末尾,然后执行:

source ~/.bashrc

如果你用 zsh,加在~/.zshrc。不建议把这种配置写在/etc/profile里,因为那是系统级配置,影响面太大;除非你确定这台机器上所有用户都应该用新版 CMake。

还有一种方式是做一个软链接:

sudo ln -s /opt/cmake-3.24.0/bin/cmake /usr/local/bin/cmake

因为/usr/local/bin在默认 PATH 里优先级比/usr/bin高,所以这条软链接能让所有用户直接使用新版 cmake。但这样做需要系统里没有其他冲突的/usr/local/bin/cmake,而且要小心以后升级时先把旧软链接删掉。

4.3 验证命令集合

配置完成后,用下面几条命令确认:

which cmake cmake --version ctest --version cpack --version

如果which cmake返回/opt/cmake-3.24.0/bin/cmakecmake --version第一行显示cmake version 3.24.0,就说明成功接管了。

不过要注意,一些构建脚本内部可能写死了/usr/bin/cmake绝对路径,这个不会受 PATH 影响。如果你遇到脚本里调用的还是旧版本,可以直接把脚本里的路径改成/opt/cmake-3.24.0/bin/cmake,或者用update-alternatives配置系统级默认版本。我个人的习惯是尽量不在脚本里写绝对路径,统一靠 PATH 控制,然后用cmake --version在脚本开头做一次版本断言,避免静默用错版本。

4.4 源码编译装上后还有哪些东西

除了cmake可执行文件,这个安装目录里还有cmake-curses-gui之类的东西吗?不一定。源码编译在默认配置下不会生成图形界面,但会带ccmake吗?这取决于 bootstrap 时是否检测到 ncurses。大多数情况下,安装后 bin 目录里能看到cmakectestcpack三个,基本够用。ctest是测试驱动工具,cpack是打包工具,它们和cmake配套使用,很多项目在 CI 里都需要。

如果你发现自己运行ccmake提示命令不存在,而你又需要图形化配置界面,那得重新安装 libncurses-dev 后再次编译。不过对这种“服务器上编译安装”的场景来说,命令行cmake已经覆盖百分之百的日常工作,我不太建议为了 GUI 多折腾一轮。

5. 版本冲突、编译报错和后续升级经验

5.1 要不要卸载系统自带 CMake

安装完新版之后,很多人会想“把系统里那个旧的卸掉,省得冲突”。我的建议是:不要轻易卸载。系统自带的 CMake 可能被其他软件包通过依赖关系引用,比如某些图形库或者系统构建脚本会调用/usr/bin/cmake。你一旦卸载旧版,轻则那些软件变成 broken 状态,重则某些系统升级流程直接失败。

正确做法是保留旧包,让新版通过 PATH 来“遮蔽”它。你验证过cmake --version显示新版之后,日常使用就都是新版;万一哪天需要旧版,直接把 PATH 里那一行注释掉就行。这种隔离思路比暴力替换安全得多,也方便回滚。

5.2 编译与运行阶段常见错误排查

源码编译 CMake 最常见的问题集中在 bootstrap 阶段。比如提示C compiler cannot create executables,大概率是 gcc 没装,或者编译器版本太老;提示Could NOT find OpenSSL则看是否要补装 libssl-dev。make 阶段如果进程被 killed,基本可以判断是内存不够,把-j改小重新来。

还有一个容易忽视的错误:如果你之前已经用老版本 CMake 配置过同一个源码目录,重新用新版配置时可能会报CMakeCache.txt中的版本不匹配。解决办法就是删掉这个缓存文件,别让它一直留在目录里影响判断。我一般在编译前会先跑一遍rm -rf CMakeCache.txt CMakeFiles,特别是反复下载不同版本试的时候。

至于项目本身报CMake 3.16 or higher is required. You are running version 2.8.12.2,如果你已经完成 PATH 配置,再用cmake --version看到新版,那这种报错不会再出现。但要注意,如果你下的是 3.24.0,而某个项目必须要求 3.26 或更高,那 3.24 也是不够的。遇到这种情况不要抱着“应该差不多”的侥幸,直接去官网拿 3.26 或更新版本,省得 configure 到一半又被打回来。

5.3 新版 CMake 能带来哪些实际体验变化

装了 3.24.0 之后,你会发现很多之前在旧版上没法用的 CMake 命令现在可以写了。比如target_precompile_headers,这个功能从 CMake 3.16 开始引入,但从 3.16 到 3.24 之间不断在完善。该命令可以帮你把vectorstring这类常用头文件预先编译,减少重复解析时间。一个典型用法是:

cmake_minimum_required(VERSION 3.16) project(PCHDemo CXX) add_executable(app main.cpp) target_precompile_headers(app PRIVATE <vector> <string> )

如果你还在用 2.8.12.2,写这段代码连target_precompile_headers这个命令都不会被识别。所以对于想尝试现代 CMake 写法的人来说,手动装一个新版源码包几乎是一条必经之路。

另外,新版 CMake 对策略的处理更清晰,CMAKE_POLICY_DEFAULT_CMP????这种解耦方式也比老版本可靠,迁移项目时更容易定位问题。当然,新版也会带来一些默认策略变化,可能导致旧项目意外报 warning 或 error。遇到这种变化不用慌,看一下它提示的策略编号,可以在 CMakeLists.txt 里临时设置兼容行为,但我建议还是按新版本的写法去修代码,毕竟你装新版就是为了把项目往前推。

5.4 内网环境与 CI 里的安装技巧

如果你不是在本地开发机编译,而是在内网 CI 或者离线环境,下载cmake-3.24.0.tar.gz之前最好就把源码包和校验文件都放好。更好的方案是在 CI 构建机里缓存编译后的/opt/cmake-3.24.0整个目录,因为 CMake 的安装目录不依赖源码目录,你可以在一个地方编译好然后 tar 走。缓存一个大目录比每次跑 10 分钟编译划算得多。

如果 CI 用的镜像可以直接拉官方提供的 Linux 二进制包,我反而更推荐那个方案。它不需要编译,解压之后同样配置 PATH 就行。源码编译的价值更多在于理解机制和适配特殊环境,日常追求效率和确定性,预编译包是个最优解。

最后分享一个我自己的检查习惯:下载后第一件事永远是sha256sum -c,安装后第一件事永远是which cmake而不是cmake --version。前者能过滤掉 80% 的“编译到一半才炸”的问题,后者能避免你浪费半天时间怀疑安装失败,最后发现只是 PATH 顺序不对。这两个动作看着小,但在多次折腾 CMake 版本的过程中,真的帮我省了最多的返工时间。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询