这是一份 vcpkg 的详细使用教程,内容涵盖从安装、核心命令到与 CMake 和 Visual Studio 集成的完整流程,重点推荐使用清单模式 (Manifest Mode) 进行项目开发。
一、安装与初始配置
1.1 获取 vcpkg
首先,从 GitHub 克隆 vcpkg 仓库到本地。建议选择一个简单路径,如 C:\dev\vcpkg 或 ~/tools/vcpkg
bash
git clone https://github.com/microsoft/vcpkg.git
1.2 运行引导脚本
进入 vcpkg 目录,执行引导脚本以生成 vcpkg 可执行文件。
| 操作系统 | 命令 |
|---|---|
| Windows | .\bootstrap-vcpkg.bat |
| Linux/macOS | ./bootstrap-vcpkg.sh |
1.3 (可选)设置环境变量
为方便使用,建议将 vcpkg 目录添加到系统 PATH,并设置 VCPKG_ROOT 环境变量。
Windows (命令提示符):
setx VCPKG_ROOT "C:\path\to\vcpkg"
setx PATH "%VCPKG_ROOT%;%PATH%"
Visual Studio Code 终端 (临时设置):
$env:VCPKG_ROOT="C:\path\to\vcpkg"
$env:PATH="$env:VCPKG_ROOT;$env:PATH"
1.4 与 Visual Studio 集成(可选)
如果使用 Visual Studio,执行以下命令可使 vcpkg 安装的库对所有项目全局可见,无需额外配置即可 #include。
bash
vcpkg integrate install
注意:此命令适用于"经典模式"。如果使用"清单模式"(推荐),则无需执行此步骤。
二、两种工作模式
vcpkg 提供两种工作模式,强烈建议新项目使用清单模式。
| 特性 | 经典模式 (Classic Mode) | 清单模式 (Manifest Mode) |
|---|---|---|
| 依赖声明 | 手动执行 vcpkg install 命令 | 在项目根目录的 vcpkg.json 文件中声明 |
| 依赖安装 | 手动安装,全局共享 | 自动安装,配置项目时自动下载安装 |
| 版本控制 | 难以锁定版本,项目间可能冲突 | 通过 builtin-baseline 锁定统一版本基线 |
| 项目隔离 | 全局安装在 <vcpkg-root>/installed | 安装在项目构建目录 vcpkg_installed 下,实现项目隔离 |
| 推荐场景 | 个人学习、小型或临时性项目 | 团队协作、持续集成、需要精确控制版本的项目 |
三、核心命令
| 命令 | 作用 | 示例 |
|---|---|---|
| search | 搜索可用的库 | vcpkg search json |
| install | 安装一个库 | vcpkg install fmt |
| list | 列出已安装的库 | vcpkg list |
| remove | 卸载一个库 | vcpkg remove fmt |
| update | 更新 vcpkg 自身和包目录 | vcpkg update |
| upgrade | 重新构建所有过时的库 | vcpkg upgrade |
指定架构(三元组 Triplet):默认安装 x86 版本,如需 x64 可在包名后指定 :x64-windows,例如 vcpkg install fmt:x64-windows。使用 vcpkg help triplet 查看所有支持的架构。
四、清单模式详细使用教程
这是现代 C++ 项目推荐的使用方式,通过声明式文件管理依赖。
4.1 初始化清单文件
在项目根目录下打开终端,执行以下命令创建必要的配置文件:
bash
vcpkg new --application
该命令会生成两个文件:
vcpkg.json:项目清单,用于声明依赖项。vcpkg-configuration.json:配置文件,用于配置注册表、覆盖端口等。
4.2 添加依赖项
使用 add port 命令添加所需的库,例如添加 fmt 库:
bash
vcpkg add port fmt
此时,vcpkg.json 文件的内容将更新为:
json
{
"dependencies": [
"fmt"
]
}
你也可以手动编辑 vcpkg.json 文件,添加更复杂的配置,例如版本锁定和依赖特性:
json
{
"dependencies": [
"fmt",
{
"name": "curl",
"features": ["openssl"]
}
],
"builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}
4.3 与 CMake 项目集成
4.3.1 创建 CMakeLists.txt
在项目根目录创建 CMakeLists.txt 文件,内容如下:
cmake
cmake_minimum_required(VERSION 3.10)
project(HelloWorld)
find_package(fmt CONFIG REQUIRED)
add_executable(HelloWorld helloworld.cpp)
target_link_libraries(HelloWorld PRIVATE fmt::fmt)
4.3.2 配置 CMake 工具链
为了能让 CMake 找到 vcpkg 安装的库,需要指定 vcpkg 提供的工具链文件。推荐使用 CMakePresets.json 来配置。
在项目根目录创建 CMakePresets.json:
json
{
"version": 2,
"configurePresets": [
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}
为了方便团队协作,再创建一个用户级别的 CMakeUserPresets.json(此文件不应提交到版本控制):
json
{
"version": 2,
"configurePresets": [
{
"name": "default",
"inherits": "vcpkg",
"environment": {
"VCPKG_ROOT": "C:/path/to/your/vcpkg"
}
}
]
}
4.3.3 配置和构建
- 在 Visual Studio Code 中:安装 "C++" 和 "CMake Tools" 扩展后,打开项目,CMake 工具会自动检测预设并开始配置,期间 vcpkg 会自动安装
vcpkg.json中声明的依赖。 - 在命令行中:
bash
cmake --preset=default
cmake --build build
4.4 与 Visual Studio 项目集成
如果你使用的是 Visual Studio 并采用清单模式,可以按以下步骤配置:
- 确保已执行
vcpkg integrate install。 - 在项目根目录创建
vcpkg.json和vcpkg-configuration.json文件。 - 打开 Visual Studio,右键点击项目 → 属性。
- 在左侧导航栏找到 vcpkg 选项。
- 将 Use Vcpkg 设置为 是。
- 将 Use Vcpkg Manifest 设置为 是。
完成配置后,Visual Studio 在构建项目时会自动读取清单文件并安装/更新依赖项。安装的库会位于项目目录下的 vcpkg_installed 文件夹中。
五、进阶功能
5.1 版本控制
builtin-baseline:在vcpkg.json中通过指定 vcpkg 官方仓库的一个 Git Commit ID,来锁定所有依赖的统一版本基线。overrides:强制覆盖特定包的版本,用于精确控制。
5.2 自定义功能 (Features)
你可以为项目定义可选的功能模块,每个模块可以有自己的依赖。
json
{
"name": "my-game",
"dependencies": ["grpc"],
"features": {
"client": {
"description": "Client Game Executable",
"dependencies": ["sdl2", "bullet3"]
},
"server": {
"description": "Multiplayer Server Executable",
"dependencies": ["proxygen"]
}
}
}
安装时,可以通过 --x-feature 选项指定要启用的功能:
bash
vcpkg install --x-feature=client
5.3 覆盖端口 (Overlay Ports)
如果你需要修改某个官方库的构建方式(例如为 curl 添加自定义编译选项),可以使用覆盖端口功能。首先创建一个本地目录存放自定义端口,然后通过 vcpkg-configuration.json 或命令行指定该目录。
vcpkg-configuration.json 配置示例:
json
{
"overlay-ports": [
"./my-overlay"
]
}
5.4 清理空间
vcpkg 会下载源码包并编译,占用较多磁盘空间。你可以安全地删除以下文件夹来释放空间,vcpkg 在需要时会重新下载或生成它们:
buildtrees/packages/downloads/
六、vcpkg库查找逻辑
vcpkg 查找库的逻辑,本质上是根据名称在多个配置好的"端口"源中按优先级顺序搜索的过程。这个查找发生在执行 vcpkg install 或 CMake 配置(清单模式)时。
为了更清晰地理解,我先把这个查找过程的核心流程图展示出来:
找到
未找到
有配置文件
在某个 registry 找到
所有 registry 未找到
配置了 default-registry
未配置 default-registry
无配置文件
未找到
开始:需要安装库名 "xxx"
在当前上下文环境中查找
(环境变量 / CMake 变量)
检查 覆盖层
✅ 使用覆盖层中的端口
检查 vcpkg-configuration.json
遍历配置中的 registries
(按声明顺序)
✅ 使用该 registry 的端口
检查 default-registry
✅ 使用默认 registry 的端口
❌ 查找失败,报错
使用内置的官方 GitHub registry
✅ 在官方仓库中查找
❌ 查找失败,报错
下面将按优先级从高到低,详细解释每一步的具体规则。
优先级 1:覆盖层 (Overlay Ports) ------ 最高优先级
这是查找的第一站,优先级最高。只要在这里找到库,就会立即使用,不会再往下查找。
-
本质:一个你指定的本地文件夹路径,里面存放着自定义的端口(每个端口是一个子文件夹,包含
vcpkg.json和portfile.cmake)。 -
作用:
- 覆盖:如果你想修改官方某个库的构建方式(比如改编译选项、打补丁),可以把官方端口复制到覆盖层里修改,vcpkg 就会优先用它。
- 补充:添加官方没有收录的私有库。
-
如何指定(三选一即可):
- CMake 变量(推荐):配置时加
-DVCPKG_OVERLAY_PORTS=你的端口文件夹路径。 - 环境变量:设置
VCPKG_OVERLAY_PORTS。 - 配置文件:在
vcpkg-configuration.json中写"overlay-ports"数组。
- CMake 变量(推荐):配置时加
优先级 2:配置文件中的注册表 (Registries)
如果覆盖层没找到,vcpkg 就会检查项目根目录下的 vcpkg-configuration.json 文件。这个文件定义了自定义的库搜索源。
查找规则如下:
按 "registries" 数组的声明顺序:vcpkg 会挨个检查你列出的每个注册表(比如公司的私有 Git 仓库、某个团队的注册表)。
找到即停:一旦在某个注册表中找到这个库名,就立即使用,不再往后查。
最后查 "default-registry":如果所有 registries 里都没有,最后才会去 default-registry(通常是官方 GitHub 仓库)里找。
都不存在则失败:如果 default-registry 里也没有,查找就失败了。
你可以把 vcpkg-configuration.json 理解为 Maven 的 settings.xml 或 npm 的 .npmrc,用于精细控制依赖的来源。
优先级 3:默认官方注册表 (Default Registry)
如果没有 vcpkg-configuration.json 文件,或者配置文件里没匹配到任何注册表,vcpkg 就会使用内置的默认源:微软官方 GitHub 仓库 (https://github.com/Microsoft/vcpkg)。
- 这是最常用的路径:绝大多数情况下,你安装的库都是从这里来的。
- 版本由
builtin-baseline锁定:在清单模式(有vcpkg.json)下,官方仓库的版本由vcpkg.json中的"builtin-baseline"字段(一个 Git commit ID)锁定,确保版本一致。
一个完整的查找流程示例
假设你的项目要安装 fmt 库,vcpkg 的查找过程是这样的:
-
检查覆盖层:你有设置
VCPKG_OVERLAY_PORTS指向./my-ports吗?或者 CMake 传了-DVCPKG_OVERLAY_PORTS=...吗?-
如果有:去
./my-ports文件夹里找有没有fmt子文件夹。- 找到:✅ 就用这个
fmt(可能是你修改过的版本)。 - 没找到:➡️ 进入下一步。
- 找到:✅ 就用这个
-
如果没有设置覆盖层:➡️ 直接进入下一步。
-
-
检查
vcpkg-configuration.json:项目根目录下有这个文件吗?-
有:读取文件。
-
假设
registries数组里第一个是公司私有 Git 仓库https://git.mycompany.com/vcpkg-registry.git。 -
vcpkg 会去这个仓库里找有没有
fmt这个端口。- 找到:✅ 从公司仓库安装。
- 没找到:继续检查
registries里的下一个。
-
如果所有
registries都没找到,最后去default-registry(假设配置为官方仓库)。- 找到:✅ 从官方仓库安装。
- 没找到:❌ 报错
error: 'fmt' does not exist in the default registry。
-
-
没有:➡️ 直接使用默认官方仓库。
- 去官方 GitHub 仓库找
fmt。 - 找到:✅ 安装。
- 没找到:❌ 报错(这种情况极少见,因为
fmt是官方收录的)。
- 去官方 GitHub 仓库找
-
总结与最佳实践
| 场景 | 推荐方案 |
|---|---|
| 使用官方标准库 | 什么都不用做,vcpkg 会自动从官方仓库查找。 |
| 临时修改某个官方库的构建方式 | 使用 覆盖层 (Overlay Ports)。把官方端口复制出来修改,通过环境变量或 CMake 变量指定覆盖层路径。 |
| 团队内使用私有库,或固定某个特定版本的库 | 使用 vcpkg-configuration.json 配置私有 Git 注册表,并在 vcpkg.json 中用 overrides 锁定版本。 |
| 需要完全控制所有依赖的来源 | 同时使用覆盖层 + 配置文件,并把 default-registry 设为 null,强制所有库都必须从你指定的源找到。 |
理解了这个查找逻辑,你就能灵活地控制 vcpkg 从哪里获取依赖,无论是使用公共库、修改官方库,还是管理私有库,都能得心应手。
七、临时修改某个官方库的构建方式
临时修改某个官方库的构建方式,最核心的方法就是使用 vcpkg 的 覆盖端口 (Overlay Ports) 功能。这个功能可以让你在本地创建一个"定制版"的库,vcpkg 在安装时会优先使用你定制的版本,而不是官方仓库中的版本。
整个过程大致分为三步:
第三步:使用
通过命令行
--overlay-ports 指定目录
安装时,vcpkg 会
优先使用你的定制版本
第二步:定制
复制官方库的
vcpkg.json 和 portfile.cmake
按需修改
构建脚本和配置
第一步:准备
创建覆盖目录
例如:./my-overlay/
在目录下创建
以库名命名的子文件夹
例如:./my-overlay/zlib/
下面我们详细看看每一步具体怎么做。
第一步:准备覆盖目录
首先,在你的项目或任意位置创建一个文件夹,用来存放所有自定义的库。通常建议放在项目根目录下,方便管理。
例如,创建一个名为 my-overlay 的文件夹。然后,在这个文件夹里,为你要修改的库再创建一个子文件夹,名字必须和官方库的名字完全一致。
bash
# 假设你要修改的是 zlib 库
mkdir -p my-overlay/zlib
这样,目录结构就是:
your-project/
├── my-overlay/
│ └── zlib/ # 名字必须和官方库名一致
│ └── ...
├── CMakeLists.txt
└── vcpkg.json
第二步:复制并修改官方端口文件
接下来,你需要从 vcpkg 的官方安装目录中找到这个库的"端口 (port)",把它复制到你刚刚创建的 my-overlay/zlib/ 文件夹下。
一个标准的端口通常包含两个核心文件:
vcpkg.json: 声明库的元数据,如名称、版本、依赖项等。portfile.cmake: 核心构建脚本,定义了如何下载源码、配置、编译和安装。
官方端口的位置通常在 <vcpkg的安装根目录>/ports/<库名>/ 下。
找到后,将这两个文件复制到你的 my-overlay/zlib/ 目录中。现在,你可以开始自由修改了:
- 修改
portfile.cmake:这是最常用的方式。你可以在这里调整 CMake 配置参数、给源码打补丁、替换下载地址等。例如,如果你想在编译zlib时开启某个特定的编译选项(如ZLIB_COMPAT),可以在vcpkg_cmake_configure()调用前添加相应的-D参数。 - 修改
vcpkg.json:通常不需要改动,但如果你的修改引入了新的依赖,或者改变了库的版本,可以在这里更新。
进阶技巧:使用 Overlay Triplets 调整编译参数
如果你的修改只是想改变一些全局的编译选项(例如,为某个特定的库开启一个特殊的宏),但又不想完整复制一个 portfile.cmake,可以使用 覆盖三元组 (Overlay Triplets)。
这需要你创建一个 my-triplets 文件夹,并在其中放置修改过的三元组文件(如 x64-windows.cmake),然后在脚本中根据 PORT 变量来判断是否为特定库添加参数:
cmake
# 在 my-triplets/x64-windows.cmake 文件中
if (PORT STREQUAL "zlib-ng")
set(ZLIB_COMPAT ON)
endif()
使用时,通过 --overlay-triplets=./my-triplets 来指定。
第三步:让 vcpkg 使用你的定制版本
现在,需要告诉 vcpkg 优先去你的 my-overlay 目录里找库。有三种方式,选择最适合你的一种即可:
- 命令行指定 (最直接)
在每次执行vcpkg install时,通过--overlay-ports参数指定路径。
bash
vcpkg install zlib --overlay-ports=./my-overlay
- 项目配置文件指定 (推荐,适合团队协作) 在项目根目录的 vcpkg-configuration.json 文件中,添加 "overlay-ports" 数组。这样,团队成员无需额外操作就能自动使用相同的覆盖配置。
json
{
"default-registry": { ... },
"overlay-ports": [ "./my-overlay" ]
}
- 环境变量指定 (全局生效)
设置VCPKG_OVERLAY_PORTS环境变量,将其指向你的my-overlay目录。这种方法会影响所有使用该环境变量的 vcpkg 操作。
完成以上设置后,当你的项目(无论是通过 vcpkg install 命令还是 CMake 的 manifest 模式)尝试安装 zlib 时,vcpkg 会按照"覆盖端口 -> 自定义注册表 -> 官方注册表"的顺序查找。由于你的 my-overlay 优先级最高,它会直接使用你定好的版本进行构建。
总结与最佳实践
- 为每个库单独创建文件夹:在
my-overlay下,确保每个要修改的库都有一个独立的子文件夹,并且名字与官方库名完全一致。 - 仅修改必要的文件:通常只需复制并修改
portfile.cmake,这能满足大部分构建定制的需求。 - 妥善维护:你的定制版本是独立于 vcpkg 官方更新的。当官方端口有重要更新(如安全补丁)时,你需要手动将更新合并到你的覆盖端口文件中。
- 团队协作首选
vcpkg-configuration.json:将overlay-ports配置在项目文件中,可以确保所有开发者使用一致的、项目指定的依赖构建方式,实现"配置即代码"。
一个简单的路径示例:
假设你正在使用 manifest 模式,那么你的项目目录结构最终可能会是这样:
your-project/
├── my-overlay/
│ └── zlib/ # 你定制过的 zlib 端口
│ ├── portfile.cmake # 修改过的构建脚本
│ └── vcpkg.json # 可选的元数据文件
├── vcpkg.json # 项目清单,声明依赖 zlib
├── vcpkg-configuration.json # 项目配置,声明 overlay-ports 路径
└── CMakeLists.txt
以curl库示例
以修改 curl 为例,来完整走一遍流程。先创建目录,复制官方端口文件,然后根据需求修改 portfile.cmake。
第一步:创建覆盖目录并复制官方端口
bash
# 在项目根目录下创建覆盖目录
mkdir -p my-overlay/curl
# 复制官方 curl 端口文件
cp -r <vcpkg安装路径>/ports/curl/* my-overlay/curl/
官方端口文件通常包含这些关键文件:
| 文件 | 作用 |
|---|---|
| vcpkg.json | 端口元数据:名称、版本、依赖、特性声明 |
| portfile.cmake | 核心构建脚本:下载源码、配置编译选项 |
| 其他辅助文件 | 如 usage 文件、wrapper 等 |
第二步:修改 portfile.cmake 实现定制
curl 的 portfile.cmake 中大量使用 vcpkg_check_features() 来将特性映射到构建选项:
cmake
# curl portfile.cmake 中的典型特性映射
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
http2 USE_NGHTTP2
openssl CURL_USE_OPENSSL
schannel CURL_USE_SCHANNEL
sspi CURL_USE_SSPI
winssl CURL_USE_WINSSL # 旧版
INVERTED_FEATURES
ldap CURL_DISABLE_LDAP
)
常见的定制需求及修改方式:
- 切换 TLS 后端(如从 Schannel 改为 OpenSSL)
cmake
# 在 vcpkg_check_features 调用之前添加
# 强制使用 OpenSSL 而非 Schannel
set(CURL_USE_OPENSSL ON)
set(CURL_USE_SCHANNEL OFF)
- 添加自定义编译宏
cmake
# 在 vcpkg_cmake_configure 调用之前
set(EXTRA_OPTIONS
-DCURL_ENABLE_CURL_OPTION=ON
-DENABLE_CUSTOM_FEATURE=1
)
# 然后在 vcpkg_cmake_configure 的 OPTIONS 参数中添加
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
${EXTRA_OPTIONS} # 添加自定义选项
# ... 其他选项
)
- 静态库的额外处理
curl 在静态链接时可能需要特殊的处理。在 portfile.cmake 中通常会看到类似这样的逻辑:
cmake
# 静态库时修改头文件中的默认宏
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
# 在 Windows 上静态链接时需要定义 CURL_STATICLIB
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/curl/curl.h"
"#ifdef CURL_STATICLIB"
"#if 1")
endif()
endif()
- 禁用不需要的协议或特性
cmake
# 在调用 vcpkg_check_features 之后,可以覆盖某些选项
set(EXTRA_OPTIONS
-DCURL_DISABLE_FTP=ON # 禁用 FTP
-DCURL_DISABLE_POP3=ON # 禁用 POP3
-DCURL_DISABLE_SMTP=ON # 禁用 SMTP
-DCURL_DISABLE_TELNET=ON # 禁用 Telnet
-DCURL_DISABLE_TFTP=ON # 禁用 TFTP
)
第三步:使用覆盖端口
有两种方式让你的项目使用修改后的 curl:
方式一:通过 vcpkg-configuration.json(推荐团队协作)
在项目根目录创建 vcpkg-configuration.json:
json
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
},
"overlay-ports": [
"./my-overlay"
]
}
方式二:命令行临时指定
bash
vcpkg install curl --overlay-ports=./my-overlay
或在 CMake 配置时:
bash
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=<vcpkg>/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_OVERLAY_PORTS=./my-overlay
如果只是想切换 curl 的 TLS 后端(更简单的方案)
如果你不是要修改构建逻辑,而只是想更换 curl 使用的 TLS 库(比如从默认的 Windows Schannel 换成 OpenSSL),其实不需要使用覆盖端口,直接在 vcpkg.json 中声明即可:
json
{
"name": "my-project",
"version": "1.0.0",
"dependencies": [
{
"name": "curl",
"default-features": false, // 关闭默认特性(包括 schannel)
"features": ["openssl"] // 只开启 openssl 后端
}
]
}
为什么这样可以? 因为 curl 端口在设计时就考虑到了 TLS 后端的可选择性,OpenSSL 和 Schannel 被定义为不同的 feature(特性)。用户可以通过选择不同的 feature 来切换后端,而不需要覆盖整个端口。
完整示例:修改 curl 添加自定义 CA 路径
假设你希望 curl 使用自定义的 CA 证书包:
cmake
# 在 portfile.cmake 中找到 vcpkg_cmake_configure 调用处
# 添加以下选项:
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
-DCURL_CA_BUNDLE="C:/custom/ca-bundle.crt" # 自定义 CA 路径
# ... 其他现有选项
)
建议先用 vcpkg edit curl 命令查看官方端口文件的完整内容,再决定需要修改哪些部分。
总结
| 定制需求 | 推荐方案 | 是否需要覆盖端口 |
|---|---|---|
| 切换 TLS 后端(OpenSSL/Schannel) | 在 vcpkg.json 中用 features 选择 | ❌ 不需要 |
| 禁用/启用某些协议(FTP、SMTP 等) | 修改 portfile.cmake 中的 CMake 选项 | ✅ 需要 |
| 添加自定义编译宏 | 修改 portfile.cmake | ✅ 需要 |
| 修改静态库的头文件行为 | 修改 portfile.cmake 中的后处理逻辑 | ✅ 需要 |
| 替换源码下载地址或打补丁 | 修改 portfile.cmake 中的 vcpkg_from_github | ✅ 需要 |
八、vcpkg查找自定义库
要让 vcpkg 找到你私有的或修改过的自定义库,核心方法是使用覆盖端口 (Overlay Ports)。它本质上是一个本地文件夹,拥有最高查找优先级,让你可以轻松地覆盖官方库或添加全新的库。
整个过程分为两步:1) 编写自定义库的端口文件;2) 配置 vcpkg 使用这个覆盖端口。下面我会用mylib这个库来演示具体怎么做。
第一步:编写自定义端口 (Port)
端口是一个文件夹,里面必须包含两个文件,定义了如何获取和构建你的库。
- 创建目录:在项目里新建一个文件夹,比如
my-overlay,然后在里面为你的库mylib创建一个子目录。
bash
mkdir -p my-overlay/mylib
- 创建 vcpkg.json (元数据):在 my-overlay/mylib 文件夹下创建此文件,声明库的基本信息。对于私有库,"version" 字段可以用日期等自定义。
json
{
"name": "mylib",
"version": "1.0.0",
"description": "My custom library",
"license": "MIT"
}
- 创建 portfile.cmake (构建脚本):在相同目录下创建此文件,它是告诉 vcpkg 如何下载和编译库的核心脚本。这里分几种情况:
情况A:库在本地源码目录
cmake
# 假设你的库源码在项目根目录下的 libsrc/mylib 文件夹中
vcpkg_check_linkage(ONLY_STATIC_LIBRARY) # 可选:限制为静态库
# 直接将源码路径赋值给 SOURCE_PATH
set(SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../libsrc/mylib")
# 如果你的库是用 CMake 构建的
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup()
情况B:库托管在 Git 仓库 (如 GitHub)
cmake
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
# 从 GitHub 下载源码
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO <你的GitHub用户名>/mylib # 仓库地址
REF v1.0.0 # 标签或提交ID
SHA512 0 # 首次设为0,运行后会提示正确哈希值
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup()
获取 SHA512 哈希值:在 SHA512 处先填 0,然后运行 vcpkg install --overlay-ports=... 命令,安装会失败,但控制台会打印出正确的哈希值,复制并替换掉文件中的 0 即可。
第二步:配置 vcpkg 使用覆盖端口
告诉 vcpkg 去你的 my-overlay 文件夹查找,有以下三种方式。推荐使用第一种,它对团队协作最友好。
- 项目级配置 (最佳实践):在项目根目录的
vcpkg-configuration.json文件中添加"overlay-ports"数组。此文件通常与vcpkg.json并列。
json
{
"overlay-ports": [
"./my-overlay" # 指向你第一步创建的文件夹
]
}
配置好后,在项目的 vcpkg.json 中像使用普通库一样声明 "mylib" 即可。团队成员拉取代码后,无需额外配置就能自动识别。
- 命令行指定 (快速测试):在每次执行 vcpkg 命令时通过参数指定。
cmake
vcpkg install mylib --overlay-ports=./my-overlay
或者在 CMake 配置时:
bash
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=<vcpkg路径>/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_OVERLAY_PORTS=./my-overlay
- 全局环境变量 (永久生效):设置
VCPKG_OVERLAY_PORTS环境变量。这会作用于你电脑上所有使用 vcpkg 的地方,可能会造成干扰,一般不太推荐。
一个更巧妙的用法:用覆盖端口"替换"官方库
这个功能非常强大。如果你想用 zlib-ng 来完全替代官方的 zlib,可以利用覆盖端口的优先级来"偷梁换柱"。
原理:vcpkg 查找库时,my-overlay 的优先级高于官方仓库。你只需在 my-overlay 里创建一个名为 zlib 的端口,并在其 vcpkg.json 中写上 "dependencies": ["zlib-ng"]。
这样,当任何项目依赖 zlib 时,vcpkg 会先找到你的覆盖端口,然后自动去安装 zlib-ng。对项目来说,它毫不知情,依然在请求 zlib,但实际获得的却是 zlib-ng。
九、官方文档与资源
vcpkg 的官方文档已迁移至 Microsoft Learn 平台,你可以通过以下链接获取最新、最全面的信息: