使用 vcpkg 管理 C++ 项目中的依赖

原文: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/vcpkgWindows 上是 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-cmakevcpkg-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

添加新版本

  1. portfile.cmake 中设置新的 REF 值;
  2. 更新 vcpkg.json 中的 version
  3. 可选地更新 baseline.json
  4. 提交并执行 rev-parse
  5. 在版本 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-portsVCPKG_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 缓存包括两部分:

  1. 二进制缓存 ------ 构建产物
  2. 资源缓存 ------ 构建所需工具(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 后,我列出了一个"最烂项目"列表,根据补丁总大小排序。冠军是:

  1. GDAL------74.8 KB
  2. dawn------57.7 KB
  3. spirv-tools------39.5 KB
  4. sdl-image------38.2 KB
  5. xz------33.6 KB

2026-03-22 | Windows triplets 中不再提供 VCPKG_ROOT

vcpkg 工具版本 2026-03-04 开始,Windows triplets 中不再提供 VCPKG_ROOT 环境变量。可以使用 $ENV{VCPKG_COMMAND} 替代。

相关推荐
feixing_fx2 小时前
选择器的威力——深入理解优先级计算与层叠规则
开发语言·前端·css·前端框架·html
6v6-博客2 小时前
C语言字符串中空格的表示方法
c语言·开发语言
geovindu2 小时前
python: speech to text offline
开发语言·python·语音识别
于指尖飞舞2 小时前
java后端面试题(多线程极简)
java·开发语言
techdashen2 小时前
从 Windows 的 ping.exe 入手:动态库、调用约定与 Rust FFI
开发语言·windows·rust
AI科技星3 小时前
数术宇宙:零一无穷创世史诗
开发语言·网络·量子计算·拓扑学
是多巴胺不是尼古丁3 小时前
期末java复习--string
java·开发语言·python
blueman88883 小时前
VS2022 切换定义(F12 / Go to Definition)反应慢
c++·visual studio
Survivor0013 小时前
高并发系统流量治理的底层算法
java·开发语言