如果你经历过手动去GitHub下载OpenCV源码、自己配CMake、再跟着一堆教程调编译器选项,折腾一整天最后还卡在链接阶段的痛苦,那你一定能理解C++开发者看到vcpkg时的心情。这个由微软开源的C++包管理器,解决的就是C++生态里长期存在的“依赖地狱”问题——让我用一句话先把它说清楚:vcpkg是一个专门为C++打造的跨平台包管理器,负责第三方库的下载、编译、安装和集成,让开发者像用pip或npm一样管理C++依赖。
我最初接触vcpkg是在一个需要集成OpenCV、Boost和SQLite的老项目里。当时手动编译这些库的代价远超写业务代码本身,不同库的编译顺序、ABI兼容性、运行库类型(/MD还是/MT)稍有不对,整个工程就给你颜色看。后来把项目迁移到vcpkg之后,无论是新建工程还是切换平台,依赖管理几乎不再占用精力。这篇文章我会从安装、日常使用、工作原理到选型对比,把vcpkg从里到外拆一遍,内容覆盖Windows、Linux和macOS,适合所有被C++依赖管理折磨过的开发者,也适合刚入门C++、想建立一套标准工作流的初学者。
1. 为什么C++开发者需要vcpkg:依赖管理的痛点与现实
1.1 C++生态的“手工搬运”困境
C++不像Python有pip、不像JavaScript有npm,多年来第三方库的分发基本靠源码加构建脚本。你从GitHub拉下来一个库,要先看它的README搞清楚依赖了哪些其他库,再逐个去装那些依赖的依赖,最后还得祈祷编译器和运行库版本能对得上。这种”手工搬运“方式有几个老大难问题:
第一,传递依赖非常容易断裂。一个库往往依赖十几个其他库,尤其是Boost这种巨无霸,光是搞清楚它需要哪些子模块就能让人头大。一旦某个依赖版本和当前项目已有版本冲突,就是一场大型劝退现场。
第二,ABI兼容性是个隐形炸弹。C++没有统一的二进制接口标准,编译器版本、标准库实现、运行库方式(动态/静态)、Debug/Release配置都会影响库的二进制兼容性。你辛辛苦苦编译好的静态库,换个编译器版本可能就直接链接失败,更别提跨平台场景。
第三,编译参数组合极其繁杂。同一个库,你要为x86编译一份、x64编译一份、Debug编译一份、Release编译一份,如果还要考虑静态链接和动态链接的区别,组合数量直接翻倍。手动管理这些组合几乎等于给自己找了一份全职工作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
1.2 vcpkg的解决思路:源码构建与状态管理
vcpkg的核心思路其实很朴素:不提供预编译二进制包,而是在本地自动化地完成“下载源码-配置构建-安装产物-注册环境”的全过程。它通过一套名为“端口(port)”的脚本机制,把每个第三方库的获取方式、依赖关系、补丁和构建规则都固化了下来。
这样带来的好处很直接。你执行一条vcpkg install opencv,它会自动检查OpenCV在vcpkg中声明的所有依赖,把protobuf、zlib、libjpeg、libpng这些一并拉下来编译,整个过程无需你手动干预。而且由于vcpkg默认使用当前机器的编译器进行源码编译,从根源上绕开了二进制兼容性问题——这段代码和我其他代码用的是同一套工具链,自然不容易出幺蛾子。
另一个让vcpkg在C++社区站稳脚跟的原因,是它背后有微软持续投入,并且完全开源。底层库的数量增长很快,热门库基本在几周内就会有维护者跟进更新。对于团队项目,还可以搭建私有仓库缓存定制端口,这也是它适合企业级工程的原因之一。
2. vcpkg安装与环境准备:跨平台实战
2.1 Windows平台:三步完成安装
Windows上的安装流程是所有平台里最简单的,官方推荐方式是用Git克隆仓库后执行引导脚本。打开PowerShell或命令提示符,依次执行:
bash复制git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
等待脚本执行完毕后,目录下会生成vcpkg.exe。这里有一个很容易被忽略的细节:引导脚本默认会下载当前最新的vcpkg工具链,如果你的电脑上没有Visual Studio的C++桌面开发组件,或者只装了MinGW,引导脚本会提示找不到合适的编译器。所以执行之前,我建议你先确认两件事:一是安装Visual Studio 2019或2022时勾选了“使用C++的桌面开发”工作负载,二是确认系统环境变量VSINSTALLDIR或VisualStudioDir能被正常解析。
引导完成后,验证安装是否成功:
bash复制.\vcpkg.exe version
如果能看到版本号,说明基础环境没有问题。为了方便全局调用,我习惯把vcpkg.exe所在的目录加入系统PATH环境变量,这样后面在任何终端里都能直接使用vcpkg命令,不用每次都在vcpkg目录下操作。
2.2 Linux/macOS平台:安装依赖与引导
Linux和macOS的流程类似,但需要先用系统包管理器装好构建工具。以Ubuntu 22.04为例:
bash复制sudo apt update
sudo apt install build-essential curl zip unzip tar pkg-config
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
macOS用户则建议先安装Xcode Command Line Tools(执行xcode-select --install),再通过Homebrew安装cmake和ninja。需要留意的是,如果你的Linux发行版默认的gcc版本过老,可能无法编译某些要求C++17甚至C++20的新版本库。这时候要么升级系统编译器,要么安装新版gcc并配置vcpkg使用自定义编译器,后面第5章我会专门讲这个场景。
安装完成后,Linux/macOS下生成的工具是./vcpkg(没有.exe后缀),同样的,推荐把它放进PATH环境变量。在~/.bashrc或~/.zshrc里加一行:
bash复制export PATH=$PATH:/path/to/vcpkg
然后source ~/.bashrc生效即可。
2.3 版本选择与升级策略
vcpkg仓库是滚动更新的,所谓“版本”其实指的是仓库的某个commit。官方推荐的做法是长期跟随master分支,因为vcpkg的端口更新速度很快,停留在旧commit会导致无法安装新版本的库。但如果你所在团队对依赖版本的一致性要求很高,可以使用版本锁定协议,在项目里显式声明一组builtin-baseline,让所有成员和CI服务器拉到同一批端口版本。具体做法在介绍manifest模式时会详细展开。
3. vcpkg的日常使用:三种场景一次讲透
3.1 经典模式:全局安装与项目集成
vcpkg最直观的使用方式就是经典模式。安装单个库:
bash复制vcpkg install fmt
vcpkg install spdlog
默认情况下,vcpkg会针对当前平台的默认triplet进行编译。Windows上默认是x86-windows,Linux上默认是x64-linux。如果你需要指定架构和动态/静态库类型,在库名后面加上冒号:
bash复制vcpkg install opencv:x64-windows
vcpkg install curl:x64-windows-static
这里的x64-windows和x64-windows-static是triplet名称,前者对应动态链接,后者对应静态链接。千万不要不加triplet就以为安装的是x64版本,Windows上默认x86这一点,第一天用vcpkg的人几乎都会踩坑。
经典模式下,安装好的库全局对当前用户可见。接着需要把vcpkg集成到Visual Studio:
bash复制vcpkg integrate install
这一步会在Visual Studio的全局配置中注册vcpkg的include和lib路径,之后新建项目就能直接#include已安装的头文件,项目配置里的附加包含目录和附加库目录不用再手动改。对于CMake项目,则在CMakeLists.txt里指定工具链文件:
cmake复制cmake_minimum_required(VERSION 3.15)
project(vcpkg_demo)
set(CMAKE_TOOLCHAIN_FILE "C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
find_package(fmt CONFIG REQUIRED)
add_executable(demo main.cpp)
target_link_libraries(demo PRIVATE fmt::fmt)
这里find_package(fmt CONFIG REQUIRED)是关键,大多数vcpkg安装的库都会生成CMake的config文件,方便现代CMake以target方式链接。
3.2 manifest模式:项目级依赖声明(现代推荐做法)
经典模式虽然简单,但有一个明显问题:所有项目共享一个全局安装目录,不同项目的依赖版本没法隔离。升级了某个库,可能把另一个正在维护的项目搞坏。为了解决这个问题,vcpkg从2019年开始强推manifest模式,这类比一下就是C++世界里的requirements.txt或package.json。
在项目根目录创建一个vcpkg.json文件:
json复制{
"name": "my-project",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
{
"name": "opencv",
"features": [
"jpeg",
"png"
]
}
]
}
然后在CMakeLists.txt里通过CMAKE_TOOLCHAIN_FILE指定vcpkg工具链后,只要配置CMake,vcpkg就会自动读取这个vcpkg.json,把声明的依赖全部安装到项目本地(默认是build/vcpkg_installed目录)。这样每个项目都有独立的依赖环境,不会互相污染,而且只要把vcpkg.json提交到版本库,任何一个人克隆项目后跑一下CMake配置,就能把整个依赖环境还原出来。
如果你想让团队所有成员锁定在同一批库版本上,可以在vcpkg.json里加上builtin-baseline字段,值是一个Git commit hash:
json复制{
"name": "my-project",
"version": "1.0.0",
"builtin-baseline": "a1b2c3d4e5f6g7h8i9j0",
"dependencies": [
"fmt",
"spdlog"
]
}
这个hash就是vcpkg仓库的某个commit,所有成员只要使用相同hash,拿到的端口定义就完全相同,编译出的库版本自然也就一致了。我建议任何稍微正式一点的项目都使用manifest模式,它比经典模式多了一点前期成本,但版本可重复性带来的收益非常可观。
3.3 与CMake、Visual Studio和VSCode的集成细节
vcpkg最常用的集成环境就是CMake。除了在CMakeLists.txt里写死工具链路径,更优雅的做法是在配置CMake时传递参数:
bash复制cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake-presets也是好选择,可以把工具链路径写进CMakePresets.json里,团队成员不用记复杂命令:
json复制{
"version": 3,
"configurePresets": [
{
"name": "default",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
]
}
这里用到了$env{VCPKG_ROOT},需要提前设置环境变量指向vcpkg目录。有了这个preset,你只需要执行cmake --preset default即可完成配置。
Visual Studio的集成非常顺滑。只要通过vcpkg integrate install注册过一次全局集成,或者项目根目录存在vcpkg.json并配置了工具链,IDE就会自动识别依赖并同步IntelliSense头文件路径。多数时候你不需要手动改项目的VC++目录设置。
VSCode配C++开发环境时,vcpkg的介入也不复杂。核心是确保c_cpp_properties.json里的compileCommands或includePath能读到vcpkg的include目录。如果你使用CMake Tools插件,配合cmake-presets,工具链配置会自动传导给IntelliSense。如果发现vcpkg安装的头文件在VSCode里显示红色波浪线,多半是配置了CMake Toolchain但C_Cpp.default.cppStandard或编译器路径不匹配,重新加载窗口一般能解决。
4. 工作原理拆解:端口、triplet与二进制缓存
4.1 端口机制:vcpkg如何自动化编译第三方库
vcpkg能把“下载源码-打补丁-配置-编译-安装”全部自动化,核心就是它仓库里那些ports/<库名>目录下的脚本文件。每个端口至少包含三个关键部分:
vcpkg.json:描述库的元信息,包括版本、依赖、特性(features)等portfile.cmake:定义具体操作步骤,比如从哪下载源码包、解压后执行什么CMake选项、安装产物到哪个目录usage文件(可选):说明这个库该怎样接入CMake或其他构建系统
以OpenCV为例,其portfile.cmake里定义了几十个CMake选项,vcpkg维护者会针对不同的triplet动态调整这些选项。当你在vcpkg.json中声明安装OpenCV并指定了jpeg、png特性时,vcpkg会重新生成一个扩展后的依赖列表,把对应的图片编解码库也加入编译队列。
端口机制还有一个很实用的延伸:本地自定义端口。如果你的项目依赖某个内部私有库,或者官方端口里的版本太旧、需要改补丁,可以在项目目录下建一个vcpkg-overlay目录,把自己的端口放进去,然后在vcpkg.json里通过"overlay-ports"字段指向它:
json复制{
"name": "my-project",
"version": "1.0.0",
"overlay-ports": [
"./vcpkg-overlay"
],
"dependencies": [
"my-private-lib",
"fmt"
]
}
这样vcpkg会优先使用本地overlay端口里的定义,而不影响官方仓库。这是团队内部复用私有库的最佳实践之一。
4.2 triplet:一份源码,多种构建产物
triplet是vcpkg中我认为最核心也最抽象的概念。它能理解成一张“构建配方表”,定义了目标平台、架构、运行库方式、库类型等约束。常用的triplet有这些:
| triplet名称 | 适用平台 | 架构 | 库类型 | 运行库 |
|---|---|---|---|---|
| x86-windows | Windows | x86 | 动态 | /MD |
| x64-windows | Windows | x64 | 动态 | /MD |
| x64-windows-static | Windows | x64 | 静态 | /MT |
| x64-windows-static-md | Windows | x64 | 静态 | /MD |
| x64-linux | Linux | x64 | 动态 | glibc动态 |
| arm64-windows | Windows | ARM64 | 动态 | /MD |
| x64-osx | macOS | x64 | 动态 | 系统动态库 |
triplet的命名规则是“架构-平台-附加属性”。当你给vcpkg指定triplet时,它会下载对应平台的工具链,配置合适的CMake参数,生成对应的构建产物。这个设计让我觉得巧妙的地方在于,vcpkg实际上把编译第三方库的“矩阵问题”收敛成了一条命令,开发者不需要自己维护不同平台下的编译脚本。
在manifest模式下,你可以在项目的vcpkg-configuration里设置默认triplet,避免每次命令行指定:
json复制{
"triplet": {
"default": "x64-windows"
}
}
也可以在CMakeLists.txt里通过VCPKG_TARGET_TRIPLET变量设置。如果你需要自定义一个新的triplet,拷贝一份现有的triplet文件到vcpkg目录下的triplets文件夹里修改即可,比如关闭动态库特性、启用静态运行时等。
4.3 二进制缓存与版本管理
vcpkg每次编译库都要重新走一遍源码构建流程,如果每次重新配置CMake都要等OpenCV编译半小时,那谁都用不下去。实际上vcpkg默认会在本机维护一个二进制缓存目录(Windows在%LOCALAPPDATA%\vcpkg\archives,Linux/macOS在~/.cache/vcpkg/archives),每次编译完成后,它会按triplet和端口版本生成哈希值,把产物打包存储。下次任何项目如果依赖相同端口、相同版本、相同triplet,就能直接解包使用,不再重复编译。
这个缓存机制对CI/CD尤其重要。团队每个成员第一次编译一个大型依赖都要花几十分钟,如果CI服务器和本地开发机共享一个二进制缓存,效率会高非常多。vcpkg提供了--binarysource参数来指定缓存来源,可以指向文件共享路径:
bash复制vcpkg install --binarysource=files,\\\\server\\vcpkg-cache
也可以配置vcpkg-configuration.json来统一管理。另外,x-scripted类型的二进制源还可以对接Artifactory或OSS等对象存储,团队基础设施允许的话可以搭建一个中心化缓存池。
理解二进制缓存后,你也能明白一个常见现象的根源:有时修改了某个库的版本,但构建却很慢,因为vcpkg判断端口有多个build type时按需重新编译,而旧缓存没有清理,会一直占用磁盘空间。定期清理archives目录里过期的包,是保持vcpkg体验顺畅的日常维护动作。
5. 选型分析:vcpkg、Conan 还是纯手动?
5.1 主流C++包管理器横向对比
现在C++社区里讨论度最高的两个包管理器就是vcpkg和Conan,很多团队在选型时纠结过。我试着从几个关键维度做一个对比:
| 对比维度 | vcpkg | Conan |
|---|---|---|
| 维护方 | 微软 | Conan开源社区(JFrog赞助) |
| 默认模式 | 源码构建,本机构建 | 可源码构建,也可拉取远程预编译二进制包 |
| 版本模型 | 端口滚动更新,可锁定baseline | 严格的版本和revision管理,支持多版本约束 |
| 平台支持 | Windows/Linux/macOS | Windows/Linux/macOS,跨平台支持更强 |
| 与CMake集成 | 官方工具链文件,开箱即用 | CMake toolchain支持完善,但配置稍复杂 |
| 与企业基础设施结合 | 二进制缓存可配置 | 有完整的Artifactory整合方案 |
| 上手门槛 | 低,一条命令安装 | 中,需理解profile、remote、recipe等概念 |
如果你所在团队主要使用Visual Studio或CMake,且希望“开箱即用”的体验,vcpkg几乎是零成本的上手方案。Conan的优势在于版本管理严谨、支持二进制分发和自定义远程仓库,适合大型企业或对依赖版本可追溯性要求极高的场景。
还有一类场景是纯手动管理。如果你只有一两个源码很少的第三方库,且目标平台极其固定,手动拷贝源码或维护子模块并不是不可接受。毕竟vcpkg和Conan都引入了额外的一层抽象,对超小型项目来说有点杀鸡用牛刀。但一旦依赖超过三个,或者需要跨平台发布,包管理器的优势就完全体现出来了。
5.2 什么场景选vcpkg更合适
根据我自己的实践,遇到下面这些情况我基本会直接选vcpkg:
- 项目是标准CMake或Visual Studio工程,团队没人有精力维护第三方库编译脚本
- 需要快速尝试新库,希望几分钟内就在本机跑通示例代码
- 依赖链复杂,比如OpenCV、Boost、PCL这种大型库,手动编译成本过高
- 团队内多个项目希望统一依赖基线,但又不想搭建复杂基础设施
举个例子,之前我在项目里需要接入HTTP服务端库cpp-httplib和WebSocket库websocketpp。手动编译需要先装OpenSSL、Boost.Asio等,光是版本搭配就能让人崩溃。用vcpkg加manifest模式,vcpkg.json里声明两个依赖,CMake配置后直接编译通过,整个过程不到十分钟。这就是vcpkg解决核心痛点的直观体现。
再比如很多热词里出现的“opencv c++”。无论你是做图像处理还是机器视觉,在Windows上用vcpkg安装OpenCV比手动从源码构建省心太多。你只需要执行vcpkg install opencv:x64-windows,它会自动处理OpenCV的依赖链,包括ffmpeg、protobuf、tbb等,一条命令解决。配合CMake的find_package(OpenCV),整个接入体验已经接近Python里pip install opencv-python的顺畅感。
5.3 自定义编译器与工具链的配合
热词里有一条“vcpkg 自定义编译器”,这是很多非MSVC用户在Windows上使用vcpkg时绕不过去的点。默认情况下,vcpkg在Windows上调用的是MSVC,如果你希望用MinGW-w64或Clang来构建,需要指定VCPKG_TARGET_TRIPLET为x64-mingw-dynamic或x64-mingw-static,并且提前装好MinGW工具链。
用命令行时这样操作:
bash复制vcpkg install fmt:x64-mingw-dynamic
在manifest模式下,CMakeLists.txt里设置:
cmake复制set(VCPKG_TARGET_TRIPLET "x64-mingw-dynamic" CACHE STRING "")
注意,vcpkg并不会自动帮你下载MinGW,你需要自己配置好编译器并确保它在PATH里。vcpkg会在编译时通过VCPKG_DETECTED_CMAKE_CXX_COMPILER这类变量来探测工具链。如果你有特殊的交叉编译需求,可以在自定义triplet文件里通过set(ENV{CC} ...)或set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ...)引入自定义工具链,这个能力是官方支持的,网上也有不少交叉编译到ARM平台的案例。
理解了自定义编译器的作用,你就明白vcpkg“源码构建”这一设计的好处:它并不是咬定某一种编译器不放,而是完全跟随当前环境设定的编译器来构建,从而保证ABI一致。
6. 常见问题与避坑实录:我的实际排查经验
6.1 编译失败与网络问题
**“下载源码超时”“哈希校验不通过”**是我在vcpkg使用中遇到最多的两类报错。下载超时往往是因为源码包托管在境外服务器,访问不稳定。这时可以尝试设置代理环境变量(如果公司网络允许),或者手动下载源码包放到vcpkg的downloads目录里。vcpkg在下载前会先检查downloads目录下是否已有对应文件,手动放入可以绕过网络不稳定。
哈希校验不通过通常是因为端口里的SHA512更新了,但本地缓存的旧包没清理。执行:
bash复制vcpkg remove --outdated
把过期的缓存清掉重试即可。不要强行修改端口里的哈希值来绕过校验,那会让构建结果变得不可复现。
还有一个很常见的问题是在Linux上编译时缺少系统依赖。比如安装某些图形库时需要libx11-dev、libxext-dev这些系统包,vcpkg不会自动安装。你需要在报错信息里找到它提示的缺失库,然后通过apt install或yum install补上。这也是为什么我建议在Linux上准备一个“构建基础工具集”,包括build-essential、curl、zip、unzip、tar、pkg-config、cmake、ninja-build,一劳永逸地避免低级的系统依赖问题。
6.2 版本冲突与动态库运行问题
多人协作项目中,经常出现“在我机器上好好的,到你机器上就编译不过”的情况。排查时我首先会对比vcpkg.json里的builtin-baseline是否不一致——只要有一个成员没拉最新提交就提交了新代码,另一个成员拿到旧的baseline,依赖版本自然就不同。对策是把vcpkg作为git子模块,或者把vcpkg.json和vcpkg.lock文件一起提交,后者是vcpkg自动生成的依赖解析结果,能精确锁定每个依赖的版本。
另一个高频问题是运行时找不到DLL。用动态链接triplet编出来的程序,在开发机上能跑,换一台机器就报缺少opencv_world4100.dll之类的错误。这是因为vcpkg的二进制目录没有加入目标机器的PATH。最简单的解决办法是构建时使用静态triplet,比如Windows上把x64-windows换成x64-windows-static-md,不仅免去了DLL分发麻烦,还减少了运行时冲突的风险。代价是可执行文件体积会大不少,需要你根据自己的分发场景权衡。
6.3 与VSCode和CI环境的配置细节
在VSCode里使用vcpkg时,最容易出问题的是IntelliSense找不到头文件。我的经验是不要手动去改c_cpp_properties.json里的includePath,而是通过CMake Tools插件拿到compile_commands.json,然后设置C_Cpp.default.compileCommands指向这个文件。CMake生成的编译命令里天然包含了vcpkg的include路径,IntelliSense就能正确解析。如果发现配置了还不生效,把VSCode的C++插件重新加载窗口,一般能解决问题。
CI环境里用vcpkg,重点是缓存和一致性问题。在GitHub Actions或自建Jenkins上,每次跑CI都从头编译一遍所有依赖,速度完全不可接受。我建议在CI脚本里显式指定二进制缓存目录,比如把VCPKG_BINARY_SOURCES环境变量设为files,/path/to/cache,readwrite,把vcpkg缓存映射到CI的持久化存储上。同时,CI环境里尽量用固定的builtin-baseline,避免因为master分支滚动更新而导致某次构建突然失败。
关于“c++怎么只能加代码的情况下减少运行时间”这类性能优化问题,虽然和vcpkg本身关系不大,但vcpkg可以帮你快速实验不同版本的库——比如怀疑某个算法的性能瓶颈在fmt库的格式化环节,你可以快速切换fmt版本做对比测试,这也是包管理器带来的额外便利。
7. 我的实际使用体会与扩展建议
如果你刚开始接触vcpkg,我强烈建议从manifest模式起步,哪怕只是一个练习项目,也把vcpkg.json建起来。这样做的好处是,你会从第一天就养成依赖显式管理的习惯,等真正进入复杂项目时不会手足无措。
我个人的体会是,vcpkg真正让人上瘾的地方不是“安装库快”,而是它免费赠送了三个附带能力:一是环境可迁移性,新同事加入项目,克隆代码后一条CMake配置命令就能跑起来;二是平台一致性,同一份vcpkg.json在Windows上装的是x64-windows,在Linux上是x64-linux,库版本和API都是一套;三是构建可追踪性,因为所有依赖都在本地编译,一旦编译失败,错误信息能追溯到确切的端口和CMake选项,不像预编译包那样是一个难以打开的黑盒。
最后再分享一个小技巧:如果你经常安装大型库,可以给vcpkg设置一个并行编译参数,比如在vcpkg-configuration或CMake里给VCPKG_MAX_CONCURRENCY赋值。vcpkg默认会根据CPU核心数估算并行度,但在内存有限的机器上,把并行度从默认值降下来反而能减少因内存耗尽导致的编译进程被杀。我有一台8核16G的开发机,编译OpenCV时显式设置VCPKG_MAX_CONCURRENCY=4,比让它自己用满8核还要稳定,编译时间反而更短了。
C++生态经过这么多年的发展,终于有了一个能让人放心依赖的包管理方案,虽然它还有不少可以改进的地方,但对自己动手能力要求极高的C++开发者来说,vcpkg确实把“把第三方库跑起来”这件事变成了一个近乎无感的步骤。如果你还在被依赖问题困扰,按这篇文章的路径试一次,大概率会和我一样,再也回不去手动编译的日子了。
