Ubuntu 18.04 上 vcpkg 安装库失败?升级 CMake 与 gcc-9 避坑指南
发布时间:2026/10/18 6:28:34 锦皓数字建站

如果你也是在 Ubuntu 18.04 上折腾 vcpkg大概率撞到过这么一幕./vcpkg install跑了几分钟眼看依赖都拉完了突然刷出一段带error:的红色日志然后整个构建直接中断。我这边出现过的报错核心一句很有意思CMake 3.16 or higher is required. You are running version 3.10.2对问题就出在 Ubuntu 18.04 自带的 CMake 版本上。这玩意儿 2018 年发布默认装的是 CMake 3.10.2而现在主流的 vcpkg、以及大量第三方 C 库早就把最低要求提到了 CMake 3.16 甚至更高。版本代沟一拉出来vcpkg 这种壳子再聪明也没辙它解决不了工具链版本不够的问题。这篇文章我把当时完整的排错过程、最终解法、以及顺手整理的一些避坑经验都写出来。适合正在 Ubuntu 18.04 上跑 vcpkg 装库、但总在编译阶段失败的开发者如果你是老手也可以直接跳到第三节看升级 CMake 的具体路径第四节讲了编译器版本问题这一块很多教程都没提全。1. 一个典型的 vcpkg 安装失败现场先还原一下我当时的具体场景。环境是 Ubuntu 18.04vcpkg 已经 clone 下来bootstrap 也跑完了然后执行./vcpkg install spdlog前几十秒一切正常下载源码、解压、创建构建目录看起来没什么问题。结果在本机编译那一步直接退出屏幕上的报错一大段但核心信息只有几行。我把日志文件拖下来看发现问题集中在 configure 阶段。1.1 日志里那几句决定性报错vcpkg 安装失败时日志不会只给你看一行它会保存在buildtrees/包名/目录下。我这次打开的是类似这样的文件buildtrees/spdlog/install-x64-linux-out.log然后在末尾看到了CMake Error at CMakeLists.txt:10 (cmake_minimum_required): CMake 3.16 or higher is required. You are running version 3.10.2这一条就已经把问题定性了vcpkg 在配置三方库时调用了系统的 CMake而系统 CMake 版本太老连三方库的cmake_minimum_required门槛都满足不了。另外还有一个比较隐蔽的现象即使我临时绕开这个报错后面编译阶段还会陆续冒出其他怪问题。这是因为 Ubuntu 18.04 自带的 gcc 是 7.5.0这个版本对 C17 的支持本身就不是特别稳定稍新一点的库就会触发报错。所以这个问题不是单一的 CMake 老而是整套系统工具链都偏旧。1.2 别急着把锅甩给 vcpkg很多人遇到这种报错会以为 vcpkg 坏了甚至重装 vcpkg、删掉整个目录再来一遍结果问题依旧。其实 vcpkg 本身没坏。它的核心功能是“帮你把源码拉下来配置编译安装”真正干活的还是 CMake、Make 和编译器。可以这么理解vcpkg 是一个调度员但它手下的工具人—— CMake 和 gcc ——是 Ubuntu 18.04 自带的旧员工。调度员指挥得再好员工技能版本过低活还是干不了。所以第一步是搞清楚“哪个工具人掉链子”而不是怀疑调度员。2. 根因Ubuntu 18.04 的老工具链与新版 vcpkg 的代差我前后排查花了不少时间本质问题就两个CMake 版本太低以及编译器版本太老。这俩在 Ubuntu 18.04 上是“配套出现”的。2.1 先看版本对照要判断是不是版本问题最快的方法是把系统和 vcpkg 两边要求的版本列出来对照项目Ubuntu 18.04 默认常见要求CMake3.10.23.16gcc / g7.5.08 或 9C 标准支持C17 部分支持完全支持 C17std::filesystem需要 experimental 和额外链接库标准支持很多三方库的 CMakeLists.txt 会写cmake_minimum_required(VERSION 3.14)或3.16。低于这个版本CMake 直接拒绝干活不会像普通编译警告那样先跑起来再说。这是硬性门槛。而编译器的门槛更麻烦。比如std::filesystem在 gcc 7 里是放在std::experimental::filesystem里面的你得写#include experimental/filesystem namespace fs std::experimental::filesystem;编译时还得手动加-lstdcfs。到了 gcc 8 以上才是标准的std::filesystem。所以一旦三方库用了标准写法gcc 7 就会报“找不到头文件”或者“未定义符号”。这种报错不像 CMake 版本那么直白容易被误判成库本身的问题。2.2 为什么说 vcpkg 替代不了工具链vcpkg 的价值在于“依赖管理和构建流程的封装”它不会给你打包一个全新的编译器。我在早期也犯过这个认知错误以为有了 vcpkg就不需要关心 CMake 和 gcc 版本了。实际上 vcpkg 只是把“下载源码、应用补丁、配置构建、安装产物”这条链路自动化了。它也会尝试下载一些它自己依赖的工具但是在 Linux 上调用系统 CMake 的场景依然很常见。而且就算 vcpkg 内部用它自带的 CMake 副本三方库传给 CMake 的很多探测逻辑最终还是依赖编译器能力。所以正确的处理顺序非常关键先保证系统 CMake 版本足够新再保证编译器版本满足三方库要求最后才去折腾 vcpkg 本身。我最初就是倒过来先是重装 vcpkg后来又怀疑是网络下载不完整白白浪费了很多时间。3. 实操把 CMake 升级到 3.16 并重新安装定位到 CMake 版本问题是第一步接下来就是升级。这里有几个常见方案我简单对比一下然后说我最推荐的做法。3.1 升级 CMake 的几种方案对比方案优点缺点apt 直接升级操作简单Ubuntu 18.04 官方仓库默认最高 3.10升不上去snap 安装较新需要安装 snapd且部分环境受限pip 安装简单可能污染 Python 环境路径管理麻烦官方预编译包新版本可选独立可控需要手动配置 PATH在 Ubuntu 18.04 上apt install cmake默认拿到的基本还是 3.10.2除非额外添加第三方源否则这条路径走不通。所以我选择了下载官方预编译包放到/opt下然后通过修改 PATH 让它生效。这样不影响系统包管理器的状态以后想换版本也方便。3.2 完整升级步骤先下载 CMake 的 Linux x86_64 预编译压缩包。版本号我建议直接选一个比“3.16 最低要求”高一截的稳定版比如 3.22.x。太新不一定好但 3.22 这一代在 Ubuntu 18.04 上稳定性不错很多 C 库也都验证过。# 下载后解压 tar xf cmake-3.22.0-linux-x86_64.tar.gz # 移动到 /opt sudo mv cmake-3.22.0-linux-x86_64 /opt/ # 把 bin 目录加进 PATH echo export PATH/opt/cmake-3.22.0-linux-x86_64/bin:$PATH ~/.bashrc source ~/.bashrc然后验证版本cmake --version如果输出显示cmake version 3.22.0就说明系统当前的 cmake 命令已经指向新版本。这里有个常见坑如果你是在某些终端模拟器里执行或者用了 tmux需要重新打开一个 shell 再执行source ~/.bashrc否则 PATH 可能没有刷新。3.3 让 vcpkg 使用新 CMakeCMake 装好了还要确保 vcpkg 调用的确实是新版本。理论上 vcpkg 会从 PATH 里找 cmake所以只要你在同一个 shell 里跑./vcpkg install spdlog它就会自动使用新的 CMake。但如果你之前设置过VCPKG_FORCE_SYSTEM_BINARIES之类的手动指定变量或者自定义过 triplet 里的CMAKE_MAKE_PROGRAM那就要额外检查一下配置。我这边升级完 CMake 后重新执行安装之前卡住的 configure 阶段顺利通过了。紧接着又撞上了编译器相关的问题这个在下一节单独说。注意如果 vcpkg 之前已经构建到一半最好先把对应库的 buildtrees 目录清掉避免旧缓存干扰。后面第五节我会讲具体清理方法。4. 顺手把编译器也调好gcc-9 与 vcpkg 的搭配CMake 问题解决后我遇到的下一个报错不再那么“醒目”但更迷惑。日志里出现的是error: std::filesystem has not been declared或者cc1plus: fatal error: ... 不支持该 C17 特性原因很简单Ubuntu 18.04 默认的 gcc 是 7.5.0对 C17 的支持不完整。这几年新出的 C 库要求 C17 几乎成了标配所以 gcc 7 在编译时会频繁翻车。4.1 为什么推荐升到 gcc-9 而不是 gcc-11之前我也试过直接上 gcc-11结果在新装库时又遇到 glibc 和新 libstdc 的兼容问题。后来对比下来gcc-9 是 Ubuntu 18.04 上一个比较平衡的选择它对 C17 支持完整又不会因为它要求的系统库太新导致缺一堆依赖。当然如果你用的库明确要求 gcc-10 或更高那就得按需升级。我这里说的是“默认不知道怎么办时优先选 gcc-9”。4.2 安装 gcc-9 并只让 vcpkg 使用它不建议直接改系统默认的 gcc那样可能影响系统里其他软件。更安全的做法是单独安装 gcc-9然后只让 vcpkg 这条链路使用它。安装命令大致如下sudo apt update sudo apt install gcc-9 g-9安装后先确认版本gcc-9 --version g-9 --version然后在跑 vcpkg 之前通过环境变量指定编译器和 C 编译器export CCgcc-9 export CXXg-9 ./vcpkg install spdlog这种做法的好处是系统默认 gcc 还是 7.5其他项目不受影响vcpkg 构建时使用的则是 gcc-9。如果你用 CMake 前缀配置也不排斥可以在 vcpkg 的 triplet 文件里加两行效果一样set(CMAKE_C_COMPILER gcc-9) set(CMAKE_CXX_COMPILER g-9)不过环境变量方案更快也更容易临时切换版本。4.3 验证编译器和 CMake 确实“搭”在一起升级完之后我建议做一个非常简单的自测写个 3 行 C 文件用 g-9 编一下确认 filesystem 没问题#include filesystem #include iostream int main() { std::cout std::filesystem::temp_directory_path() std::endl; return 0; }编译命令g-9 -stdc17 test.cpp -o test能正常编译并输出路径就说明编译器侧没有硬伤了。之后再看一眼 vcpkg 安装日志里用的编译器版本确认是 gcc-9而不是默认的 gcc-7。5. 常见问题与排查技巧实录工具链升级完之后vcpkg 安装库基本恢复了正常。但这个过程里我还积累了不少排查经验正好是常规文档里不会写的东西整理成速查表方便你直接对号入座。5.1 报错关键词速查报错关键词真正含义处理办法CMake 3.x or higher is required / running 3.10.2CMake 版本过低升级 CMake见第三节CXX compiler ... is not able to compile a simple test program编译器缺失或工具链不完整检查 gcc/g 是否安装试装 gcc-9std::filesystem has not been declaredgcc 版本太老升级 gcc 并使用 g-9unrecognized command line option编译器不认识某些参数换新版 gccpermission denied编译阶段曾经用 sudo 跑过 vcpkg修复文件属主别用 sudo 跑 vcpkgDownload failed在 downloads 目录网络或工具下载失败检查网络清理 downloads 后重试这张表基本覆盖了 Ubuntu 18.04 vcpkg 环境里 80% 的安装失败场景。5.2 教训一不要用 sudo 跑 vcpkg我踩过最无语的坑就是一开始用sudo ./vcpkg install装了部分库后续再跑就接二连三报permission denied。原因是 vcpkg 的下载缓存和 buildtrees 目录变成了 root 所有当前用户根本写不进去。解决方式是sudo chown -R $(whoami) ~/vcpkg然后后续所有 vcpkg 命令都不要加 sudo。vcpkg 本身就不需要管理员权限它会把内容安装到自己的packages目录里而不是系统目录。加了 sudo 不但没好处还制造权限混乱。5.3 教训二分不清“CMake 报错”和“编译器报错”很多安装失败日志一大坨人眼一看红字就慌。其实只要抓住两个关键位置看 configure 阶段是否有版本不满足的报错这通常是 CMake 问题看 compile 阶段是否有error:和.cpp文件行号这通常是编译器或代码兼容问题。我见过有人把编译器报错当成 vcpkg bug反复删目录重装其实只要把 gcc 换掉就解决了。建议报错后先跑一遍grep -iE error|fatal buildtrees/包名/*.log把关键行拉出来再判断效率会高很多。5.4 教训三升级完了要清理残留构建缓存CMake 升级、编译器升级之后vcpkg 里可能还残留着上次失败时生成的部分构建文件。如果直接重跑有时会复现一些奇怪错误因为旧缓存里存的 CMakeCache 还是按旧路径生成的。我一般会先做一次清理rm -rf buildtrees/包名 rm -rf packages/包名然后再跑./vcpkg install 包名这样能确保从头走一遍干净流程。如果你想彻底一点也可以把downloads目录里已经下载的源码包删掉强制重新拉取源码。但大多数时候只删 buildtrees 就够了没必要全删。5.5 备选思路实在不行用容器如果公司电脑或自己的开发机不想动系统工具链还有一个非常省心的方案用 Docker 或 Podman 拉一个较新的 Ubuntu 镜像比如 20.04 或 22.04在容器里跑 vcpkg。好处很明显新镜像自带 CMake 和 gcc 版本都是比较新的起点就高容器环境相对隔离不会影响宿主机系统万一搞坏了直接丢弃容器重建成本很低。坏处是如果你的项目需要和宿主机上的其他工具联动可能要额外的 mount 和端口映射配置。但单论“用 vcpkg 装 C 库”这个需求容器方案其实是最省心的。我后来在一些不常用的项目里就直接用容器不再折腾宿主机工具链。写在最后的个人经验经过这次折腾我养成了一个习惯在新环境里准备跑 vcpkg 之前先做一次“体检”。cmake --version gcc --version uname -a这三行命令能省下很多时间。尤其看到 Ubuntu 18.04 这种自带工具链偏旧的系统我会直接先把 CMake 升到 3.22 左右、把 gcc 升到 9然后再碰 vcpkg。这件事做在前面后面基本一路顺畅。另外还想补一个小技巧vcpkg 的日志文件其实非常有用它会记录完整的 configure 和 compile 输出。出问题时不要只看终端那最后几行红色文字去buildtrees/包名/目录下翻完整日志定位会精准很多。很多所谓“玄学报错”拆开看都是工具链版本不够跟个例的运气没什么关系。希望这篇记录能帮你少走一点弯路。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。