原文:Managing dependencies in a C++ project with vcpkg
作者:Declaration of VAR
半年前我曾尝试使用 Conan 包管理器来解决我们 C++ 项目中的依赖问题。研究进展顺利,但我们从未真正在整個项目中使用 Conan。几周前,我开始研究 vcpkg。
我之前听说过 vcpkg,甚至在几年前尝试为某个库制作过 vcpkg 包,但那时我没有找到相关文档(现在我明白了,因为实际上并不是创建一个"包"),于是就放弃了。我从没想过会再次接触 vcpkg,但最近我发现有些团队正在从 Conan 切换到 vcpkg,这听起来很有趣且充满希望,因为我们仍然需要为项目找一个包管理器。
目录
- [为什么我们没有继续使用 Conan](#为什么我们没有继续使用 Conan)
- [关于 vcpkg](#关于 vcpkg)
- [创建自己的 ports](#创建自己的 ports)
- [从注册表安装 ports](#从注册表安装 ports)
- [更新 port](#更新 port)
- [发布前测试 ports](#发布前测试 ports)
- 各平台特定问题
- 依赖图
- 分发项目
- [vcpkg 与 Conan 的对比](#vcpkg 与 Conan 的对比)
为什么我们没有继续使用 Conan
我认为这是因为我们选择了错误的方法。乍一看,将 Conan 集成到构建系统中似乎过于破坏性,所以我们决定只打包 install 目录中的预构建产物。也就是说,我们没有制作源码包,也没有在 recipe 中实现 build() 方法。
实际上,我们为所有目标平台预构建了所有依赖,这非常耗时,所以除了研究项目中那个小范围的依赖之外,我们几乎没有进展。
是的,也许如果我们选择将 Conan 集成到构建系统中并从源码构建依赖,结果会更好(更快)。为什么我们没有这么做?嗯,我们之前一直在使用其他包管理器------APT/deb、NuGet、npm 等------这些包大多只是带有元信息的归档文件,我们也是以同样的方式看待 Conan,没有期望它还能管理构建。此外,我们阅读 Conan 文档的方式也比较混乱。
总之,在覆盖了 pilot 项目的依赖后,我们邀请了几个其他团队来测试,结果发现他们使用了不同的平台/编译器组合,我们没有为这些组合预构建,所以他们不得不强制指定特定版本。
但还不止这些,用户(可以理解 )希望从 Conan Center 获取第三方依赖,从我们的 Artifactory 获取内部包,而我们从自己的 Artifactory 获取所有东西,这种情况在 Conan 中处理得不太好(或者我们没有找到方法)。
最后,不是每个人都喜欢通过添加另一个工具来使构建工具链变得复杂化,因为不仅需要在构建项目之前多运行一个步骤,而且安装这个工具本身也不太简单,需要先安装 Python、pip 才能安装 Conan。
第二次尝试后的更新
几年后,我回来尝试实现正确的 Conan recipes,支持 --build missing,包括 Conan 1.x 和最新的 Conan 2.x。
毫无疑问,从源码构建包是正确的做法,从一开始我们就应该这样做。然而,Conan 与 vcpkg 对比中的所有其他要点仍然成立。即使在现代 Conan 2.x 中,我也经历了与多年前相同的"越南闪回"般的挣扎,并且这次还受到了更多的创伤。所以我认为这次第二次尝试只突显了 Conan 比 vcpkg 更令人困惑、更不直观,总体更"慢"。
关于 vcpkg
简而言之,vcpkg 是一个 CMake 工具链文件 和一个 CLI 工具 的组合。它们共同处理以下事项:
- 确定构建环境(平台、编译器、链接方式);
- 获取依赖源码,必要时打补丁;
- 在配置主项目之前构建或恢复这些依赖。
恢复意味着如果依赖之前已经构建过,那么 vcpkg 将恢复预先构建好的二进制包,而不是重新构建。这个功能称为二进制缓存,和 Conan 一样,这是我们使用 vcpkg 解决依赖的主要原因------避免重新构建不经常变化的代码。
这里的示意图简化展示了 vcpkg 的功能:

安装
系统需要安装最新的 CMake 版本之一,否则 vcpkg 安装脚本会为你下载并放在系统的某个地方,导致你的电脑上有多个 CMake。在我的情况下,它要求最低 CMake 3.24。
关于系统环境,我在 Windows、Mac OS 和 GNU/Linux 上都有主机,本文假设你使用 Mac OS 环境,但所有步骤在其他平台上 99% 相同。在 Windows 上,建议使用 Git BASH。
安装 vcpkg 首先要克隆其仓库:
shell
$ cd /path/to/programs/
$ git clone git@github.com:microsoft/vcpkg.git
$ cd ./vcpkg/
这将带来两个组件中的第一个------CMake 工具链文件------它会被放在 /path/to/programs/vcpkg/scripts/buildsystems/vcpkg.cmake。
在继续之前,设置 VCPKG_DISABLE_METRICS 环境变量以防止遥测探查。
现在可以执行脚本来开始"安装":
shell
$ ./bootstrap-vcpkg.sh
这将调用 ./scripts/bootstrap.sh 脚本并下载第二个组件------vcpkg CLI 工具二进制文件。
最终你会在 /path/to/programs/vcpkg/vcpkg(Windows 上是 vcpkg.exe )得到工具二进制文件。为了方便,可以将 /path/to/programs/vcpkg 添加到 PATH 中。同时设置 VCPKG_ROOT 环境变量为 /path/to/programs/vcpkg。
什么是 vcpkg 包
准确地说,称它们为"包"并不正确,因为它们更像是配置和构建的 recipe。在 vcpkg 的术语中,它们被称为"ports"。
一个基本的 vcpkg port 只需两个文件:
./glfw
├── portfile.cmake
└── vcpkg.json
其中:
portfile.cmake------ 用于获取源码、配置、构建、安装和整理的 CMake 指令;vcpkg.json------ 包/port 的信息:名称、描述、主页、版本及其自身的依赖。
如果你想要添加为依赖的库已经有良好的现代 CMake 项目文件并且有正确的安装过程,那么你只需要这两个文件就可以制作一个包 port。
但很多时候你至少需要给原始的 CMakeLists.txt 打补丁,甚至需要从头创建一个,因为原始库仓库可能根本没有 CMake 支持。关键在于,portfile.cmake 文件不是用来替代可能缺失的 CMakeLists.txt 的,它的目的只是获取源码并运行构建/安装命令,因此它预期 CMakeLists.txt 已经可用。
缺失/附加的文件应该被放置在包文件夹中,并从 portfile.cmake 中引用。例如:
./dearimgui
├── CMakeLists.txt
├── fixing-something.patch
├── portfile.cmake
└── vcpkg.json
其中:
CMakeLists.txt------ 如果你不幸需要一个没有 CMake 支持的库;fixing-something.patch------ 如果库维护者不想/不能修复某些问题或变更;portfile.cmake------ 在获取库源码后应用补丁,并将CMakeLists.txt复制到库源码目录;vcpkg.json------ 名称、版本等。
注册表
包或者说 ports 需要存储在某处,这样的地方称为"注册表(registry)"。实际上,你克隆来安装 vcpkg 的仓库同时也是一个注册表:包 ports 位于 ./ports 文件夹中。
是的,你可以使用微软的 vcpkg 仓库作为项目的注册表。但我们当然想要一个自己的、由我们自己维护的内部注册表。你知道吗,设置你自己的 vcpkg 注册表简直是世界上最简单的事情。
简而言之,vcpkg 注册表只是一个具有以下结构的 Git 仓库:
├── ports
└── versions
这个 Git 仓库可以托管在 GitHub、GitLab、Gitea 或任何其他服务上,也可以只是一个通过 SSH/HTTP 访问的普通 bare Git 仓库。这简直太棒了!我当时高兴得差点尿裤子。
所以让我们创建自己的 vcpkg 注册表。开始时它只包含一个 port------GLFW 库------仓库结构如下:
├── ports
│ └── glfw
│ ├── portfile.cmake
│ └── vcpkg.json
└── versions
├── baseline.json
└── g-
└── glfw.json
Port 结构
以我的 GLFW port 为例。
vcpkg.json
json
{
"name": "glfw",
"version": "3.3.8",
"description": "A multi-platform library for OpenGL/Vulkan/etc, window and input",
"homepage": "https://www.glfw.org/",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}
"host": true 表示这些是所谓的"主机依赖",因此它们会在依赖它们的包之前被获取和安装。
portfile.cmake
cmake
# 从哪里获取包源码
vcpkg_from_git(
OUT_SOURCE_PATH SOURCE_PATH
URL git@github.com:glfw/glfw.git
REF 7482de6071d21db77a7236155da44c172a7f6c9e
)
# 如何配置项目
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DGLFW_BUILD_EXAMPLES=0
-DGLFW_BUILD_TESTS=0
-DGLFW_BUILD_DOCS=0
)
# 构建并安装项目
vcpkg_cmake_install()
# 修复导入目标的潜在问题
vcpkg_cmake_config_fixup(
PACKAGE_NAME "glfw3"
CONFIG_PATH "lib/cmake/glfw3"
)
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
# vcpkg 期望许可证信息包含在名为 "copyright" 的文件中
file(
INSTALL "${SOURCE_PATH}/LICENSE.md"
DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}"
RENAME copyright
)
vcpkg_from_git
vcpkg_from_git() 函数从 Git 仓库获取库源码。
vcpkg_cmake_configure
这个函数执行常规的 CMake 项目配置。需要:
- 设置
SOURCE_PATH指向CMakeLists.txt所在文件夹; - 提供
-D选项(如果有的话)。建议禁用构建示例/演示/测试和文档相关的内容。
vcpkg_cmake_install
这个函数构建并安装已配置的项目。它实际调用 vcpkg_cmake_build() 函数并设置 TARGET install。
vcpkg_cmake_config_fixup
这个函数修复已安装 CMake 目标的潜在问题,因为有些项目的 CMake 配置非常混乱。
版本
baseline.json
baseline.json 列出注册表中所有包的默认版本:
json
{
"default":
{
"glfw":
{
"baseline": "3.3.7",
"port-version": 0
}
}
}
版本文件
各个 *.json 文件确定 port 的哪个版本在哪个提交中可用:
json
{
"versions":
[
{
"version": "3.3.8",
"git-tree": "597fa07e1afd57c50dfdbeb0c0d28f4157748564"
}
]
}
要获取当前 port 版本的提交哈希值(git-tree 属性),需要运行:
shell
$ cd /path/to/your/vcpkg-registry
$ git rev-parse HEAD:./ports/glfw
597fa07e1afd57c50dfdbeb0c0d28f4157748564
Triplets(三元组)
vcpkg 的 triplet 是一组定义目标平台的值的文件:CPU 架构、链接类型等。可以说它类似于 Conan 的 profiles,但参数更少。
默认 triplets 位于 /path/to/programs/vcpkg/triplets/。如果你不满意标准集合,可以添加自己的 triplets,但不要编辑默认的,否则以后肯定会出问题。
创建自己的 ports
这部分内容在 [vcpkg 注册表](#vcpkg 注册表) 一节中已经覆盖了很多,但还有一些额外的东西需要说明。
微软的注册表已经有很多端口。如果不够用,比如你想以不同方式构建某个库,或者你需要的库在注册表中缺失,你可以创建自己的 port 并存储在你的注册表中,或者发布到微软的注册表。
Portfile
在简单情况下,为一个库创建 vcpkg port 只需要编写 portfile 并列出其版本。但通常你还需要添加文件、打补丁或引入特性。
添加文件
许多库不具备 CMake 支持,所以你需要为其创建并添加 CMakeLists.txt。将其放入 port 文件夹,并在 portfile.cmake 中的 vcpkg_cmake_configure() 之前添加:
cmake
file(COPY "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" DESTINATION "${SOURCE_PATH}")
补丁
当你不需要添加新文件但想修改现有文件时,可以应用补丁。只需在 vcpkg_from_git() 中添加 PATCHES 参数:
cmake
vcpkg_from_git(
OUT_SOURCE_PATH SOURCE_PATH
URL git@github.com:glfw/glfw.git
REF 45ce5ddd197d5c58f50fdd3296a5131c894e5527
PATCHES
some.patch
another.patch
)
注意,some.patch 必须是 Git patch,而不是 bare diff。创建方式:
shell
$ git diff --cached --binary > some.patch
特性
你可以通过"特性"来控制项目的构建方式,这本质上是对 CMake -D 选项的简单映射。
使用 vcpkg_check_features() 函数实现。例如,我为 Dear ImGui 库添加了一个带 GLFW 支持构建的特性:
cmake
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
backend-glfw BACKEND_GLFW
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
)
在 vcpkg.json 中:
json
{
"name": "dearimgui",
"features":
{
"backend-glfw":
{
"description": "Using GLFW as graphics backend",
"dependencies": [ "glfw" ]
}
}
}
CMake 助手
可以在 portfile 中使用助手包,它们不是用于开发的库,而是扩展 portfile 功能的 CMake 模块。vcpkg-cmake 和 vcpkg-cmake-config 就是这样的助手包。
你也可以自己创建这样的助手。如果助手旨在提供可供 portfile 使用的 CMake 函数,则必须包含 vcpkg-port-config.cmake------vcpkg 会自动导入/包含这些文件。
CMake 包装器
我找不到关于此功能的文档,但自己搞清楚并不复杂。基本上,在你的 port 中添加 CMake 包装器可以在 find_package() 调用之前或之后"注入"CMake 语句。
例如,Xerces-C++ 库在 Mac OS 上需要链接 CoreServices 框架。与其在每个项目中都添加,不如在端口的 CMake 包装器中只做一次:
cmake
_find_package(${ARGS})
if(APPLE)
if(TARGET XercesC::XercesC)
set_target_properties(XercesC::XercesC
PROPERTIES
INTERFACE_LINK_LIBRARIES "-framework CoreServices"
)
endif()
endif()
需要将该包装器安装到 ${CURRENT_PACKAGES_DIR}/share/${PORT} 路径中。
从注册表安装 ports
不通过项目安装
即使没有需要依赖它的项目,你也可以尝试安装 GLFW port。这是快速测试新 port 的便捷方式:
shell
$ vcpkg install glfw --overlay-ports=./ports/glfw
在项目中安装
以我的 GLFW Dear ImGui 应用程序 为例。依赖项列在项目的 vcpkg.json 中:
json
{
"name": "glfw-imgui-example",
"version": "0",
"dependencies":
[
"glad",
"glfw",
{
"name": "dearimgui",
"features": [ "backend-glfw" ]
}
]
}
配置项目:
shell
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
..
第一次运行会从源码构建所有依赖,后续运行会从缓存恢复。
锁定依赖版本
如果你想锁定特定版本的依赖,可以使用 overrides:
json
{
"name": "glfw-imgui-example",
"version": "0",
"dependencies": [ ... ],
"overrides":
[
{
"name": "glfw",
"version": "3.3.8",
"port-version": 0
}
]
}
注意:不能在 port 的 manifests 中使用 overrides 来控制传递依赖。
多注册表
项目可以有多个注册表:
json
{
"default-registry":
{
"kind": "git",
"repository": "git@github.com:retifrav/vcpkg-registry.git",
"baseline": "5c1a089c3a542dfbe818625bf4a3dadfb834e2af"
},
"registries":
[
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg.git",
"baseline": "71f51b100be2b5d32e3907572d99dc2f97088c8d",
"packages": [ "glslang" ]
}
]
}
CMake 预设
较新版本的 CMake 引入了 CMake presets 功能。你可以在 JSON 文件中为项目定义一组 CMake 选项:
shell
$ cmake --preset vcpkg-default-triplet
$ cmake --build --preset vcpkg-default-triplet
静态 CRT/MSVC 链接
在 Windows 上,如果 triplet 是 x64-windows-static,则静默链接 CRT/MSVC。如果某些依赖是动态链接的,会引发链接错误。解决方法是使用 CMake 策略:
cmake
if(WIN32 AND CRT_LINKAGE_STATIC)
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
set_property(TARGET ${CMAKE_PROJECT_NAME}
PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)
endif()
更新 port
添加新版本
- 在
portfile.cmake中设置新的REF值; - 更新
vcpkg.json中的version; - 可选地更新
baseline.json; - 提交并执行
rev-parse; - 在版本 JSON 文件中添加(不是替换)新版本。
添加旧版本
与添加新版本步骤基本相同。
递增 port-version
当修改 port 但不升级依赖版本时,递增 port-version 是一个更好的做法:
json
{
"name": "glfw",
"version": "3.3.8",
"port-version": 1
}
发布前测试 ports
覆盖端口(Overlay ports)
最简单的方法。将待修改的 port 复制到其他路径:
shell
$ cp -r /path/to/your/vcpkg-registry/ports/glfw /tmp/vcpkg-test-registry/
然后通过 --overlay-ports 或 VCPKG_OVERLAY_PORTS 使用:
shell
$ vcpkg install --overlay-ports /tmp/vcpkg-test-registry
注册表分支
更方便的方法是在注册表中创建新分支,然后在项目中引用:
json
{
"default-registry":
{
"kind": "git",
"repository": "git@github.com:retifrav/vcpkg-registry.git",
"reference": "updating-glfw",
"baseline": "4b4ae3fea063fc04c2d5a6089c8aa7c2d0129879"
}
}
各平台特定问题
WebAssembly
链式加载 Emscripten 工具链
将 vcpkg toolchain 与 Emscripten 配合使用时,需要同时设置 -DCMAKE_TOOLCHAIN_FILE 和 -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE:
shell
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
-DVCPKG_TARGET_TRIPLET="wasm32-emscripten" \
..
启用 pthreads 支持
需要为所有 port 设置 -pthread 标志,方法是通过自定义 triplet 和工具链。
Windows
MSVC 工具集
如果需要使用特定工具集,创建自定义 triplet:
cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_PLATFORM_TOOLSET "v141")
Release 二进制文件体积变大
默认情况下,vcpkg 在 Release 配置中也设置了 /Z7(调试信息)标志。可以通过自定义链式加载工具链来移除它。
对比:
| 库 | 含 /Z7 |
不含 /Z7 |
|---|---|---|
| assimp | 195.3 MB | 63.8 MB |
| draco | 94.4 MB | 27 MB |
| glfw3 | 2.1 MB | 633.1 KB |
| 总计 | 312.74 MB | 99.52 MB |
使用 Clang 替代 MSVC
需要创建自定义 triplet 和工具链来将编译器设置为 Clang。
禁止复制 DLL 到构建目录
设置 -DVCPKG_APPLOCAL_DEPS=0 可以阻止 vcpkg 复制 DLL 到构建目录。
GNU/Linux
缺少可执行属性
某些 configure 脚本可能缺少 x 属性,需要手动添加:
cmake
vcpkg_execute_build_process(
COMMAND chmod +x ./configure
WORKING_DIRECTORY ${SOURCE_PATH}
...
)
iOS
组合/胖/通用二进制
为设备和模拟器构建通用二进制,需要自定义工具链以设置多个架构:
cmake
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
Mac OS
通用二进制
通过设置 VCPKG_OSX_ARCHITECTURES 实现:
cmake
set(VCPKG_OSX_ARCHITECTURES "arm64;x86_64")
查找 OpenGL 框架
vcpkg 将 CMAKE_FIND_FRAMEWORK 设置为 LAST,导致优先查找 Homebrew 的 OpenGL 而非系统框架。解决方法是在 find_package(OpenGL) 之前临时设置为 FIRST。
依赖图
Conan 可以方便地生成依赖图,vcpkg 的能力相对有限。vcpkg 的 depend-info 命令可以输出 DOT 和 DGML 格式的依赖图:
shell
$ vcpkg depend-info glfw-imgui-example \
--overlay-ports=/path/to/project \
--overlay-ports=/path/to/vcpkg-registry/ports \
--dot | nop > ./graph.dot
然后用 Graphviz 可视化:
shell
$ dot -T svg ./graph.dot -o ./graph.svg
分发项目
如果项目包含库需要分发给用户,需要将 vcpkg 管理的依赖与项目安装合并。可以使用 install(DIRECTORY ...) 命令或 vcpkg-artifacts 脚本来完成,并排除不必要的依赖。
vcpkg 与 Conan 的对比
简单性
vcpkg 本质上只是 CMake 和 Git 的组合,加上一些 CLI 工具胶水,这些都是大家熟悉的工具。它的组件比 Conan 少,特别是注册表------vcpkg 注册表就是普通的 Git 仓库,创建和维护非常简单。
速度
对我来说,创建 vcpkg port 和将 vcpkg 集成到项目中比使用 Conan 更容易理解和实现。
例如,用 Conan 需要两周的研究项目,用 vcpkg 几乎只用了 3 天。
文档
矛盾的是,vcpkg 的文档似乎比 Conan 更差,或者说更不详细,但开始使用 vcpkg 却比使用 Conan 更容易。很多问题你可以自己弄清楚。
总体印象
在我看来,vcpkg 能做的事情 Conan 基本都能做,但 Conan 没有做起来。vcpkg 更直接、更接地气、更"基础"。
我们使用 Conan 的不太愉快的经历可能有些方面是使用方式有问题,但使用 vcpkg 我们从一开始就在正确的轨道上,所以公平地说 vcpkg 更直观(尤其是如果你已经有一些 CMake 经验)。
无论如何,有替代方案总是好的,C++ 开发者有多个包管理器可以选择是很棒的。
更新
2023-09-01 | 构建时间改进
几个月后,我们将项目中所有捆绑的依赖从仓库中移出,并为它们在我们的 vcpkg 注册表中创建了 port。注册表中 port 总数超过 60 个。
构建时间确实有所改善,但不同平台改善幅度不同。对于我们来说,使用包管理器的主要目标不是更快的构建,而是摆脱在仓库中捆绑第三方源码的做法。
2024-07-24 | 作为主机依赖的工具
有时构建需要某些工具(如 cURL、SQLite 等),可以将它们作为主机依赖。在 portfile 中可以使用 CURRENT_HOST_INSTALLED_DIR 变量,但在项目 CMakeLists.txt 中,获取主机 triplet 路径比较困难,需要使用 vcpkg z-print-config 命令来获取主机 triplet。
2024-10-11 | JFrog Artifactory 缓存
vcpkg 缓存包括两部分:
- 二进制缓存 ------ 构建产物
- 资源缓存 ------ 构建所需工具(CMake、PowerShell、Python 等)
对于 HTTP 后端的二进制缓存,设置环境变量:
shell
export VCPKG_BINARY_SOURCES="clear;http,https://artifactory.YOUR.HOST/artifactory/vcpkg-binary-caching/{name}/{version}/{triplet}/{sha},readwrite,Authorization: Bearer YOUR-ACCESS-TOKEN"
对于资源缓存,需要一个脚本来处理下载/上传。
2025-09-04 | Gitea 缓存
由于 Artifactory 许可证价格大幅上涨,我们迁移到了 Gitea。配置类似,但 URL 格式不同。
2025-09-23 | 不更新 port 的情况下修改原始源码
vcpkg 目前不提供此功能。可以创建一个覆盖 port,移除 vcpkg_from_git() 调用,直接设置 SOURCE_PATH 指向已有的构建目录中的源码。
2025-09-30 | 最烂的 CMake 项目
在制作了 100 多个 vcpkg port 后,我列出了一个"最烂项目"列表,根据补丁总大小排序。冠军是:
- GDAL------74.8 KB
- dawn------57.7 KB
- spirv-tools------39.5 KB
- sdl-image------38.2 KB
- xz------33.6 KB
2026-03-22 | Windows triplets 中不再提供 VCPKG_ROOT
vcpkg 工具版本 2026-03-04 开始,Windows triplets 中不再提供 VCPKG_ROOT 环境变量。可以使用 $ENV{VCPKG_COMMAND} 替代。