教程:安装特定版本的包

重要

仅在清单模式下提供此功能。

vcpkg 可以控制项目中每个依赖项的精确版本。

在本教程中,学习:

先决条件

  • 终端
  • 代码编辑器
  • vcpkg
  • CMake

1 - 创建包含清单的项目

在空文件夹中,创建以下项目文件:

源文件 (main.cpp):

#include <fmt/core.h>
#include <zlib.h>

int main()
{
    fmt::print("fmt version is {}\n"
               "zlib version is {}\n", 
               FMT_VERSION, ZLIB_VERSION);
    return 0;
}

CMake 项目文件 (CMakeLists.txt):

cmake_minimum_required(VERSION 3.18)

project(versionstest CXX)

add_executable(main main.cpp)

find_package(ZLIB REQUIRED)
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE ZLIB::ZLIB fmt::fmt)

vcpkg 清单 (vcpkg.json):

{
  "dependencies": [ "fmt", "zlib" ]
}

构建项目,将 %VCPKG_ROOT% 替换为 vcpkg 安装路径:

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
cmake --build build

运行该程序:

fmt version is 70103
zlib version is 1.2.11

运行程序时,这些库的版本可能与上述输出不同。 在下一步中,我们将介绍如何锁定这些依赖项的版本,以便它们在你每次生成项目时保持一致。

2 - 使用基线添加版本约束

版本基线为所有包建立最低版本基础。 阅读 vcpkg 概念,了解基线。

要获取上一步中使用的确切版本,请将 vcpkg.json 的内容修改为:

{
  "dependencies": [
    "fmt",
    "zlib"
  ],
  "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}

builtin-baseline 设置为 vcpkg 存储库的特定提交 SHA 会指示 vcpkg 使用该特定提交的包版本作为所有包的最低版本。

可以使用 Git 检查该特定基线的版本:

git show 3426db05b996481ca31e95fff3734cf23e0f51bc:versions/baseline.json | Select-String -Pattern '"zlib"|"fmt"' -Context 0,3

输出应如下所示:

    "fmt": {
      "baseline": "7.1.3",
      "port-version": 1
    },
--
    "zlib": {
      "baseline": "1.2.11",
      "port-version": 9
    },

3 - 更新基线版本

基线提供了一种方便的机制来同时更新所有依赖项的版本。 要更新基线,请运行以下命令:

vcpkg x-update-baseline

x-update-baseline 命令将修改清单文件,以将 builtin-baseline 设置为 vcpkg 实例的当前 Git 提交。

你可以使用 --add-initial-baseline 选项向没有基线的清单添加一个 builtin-baseline

4 - 添加最低版本约束

基线并非锁定包版本的唯一方法。 vcpkg 还接受采用 version>= 形式的最低版本约束。

vcpkg.json 的内容修改为:

{
  "dependencies": [
    {
        "name": "fmt",
        "version>=": "10.1.1"
    },
    "zlib"
  ],
  "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}

上述清单文件使用依赖项对象表示法对 fmt 设置最低版本约束 (version>=)。 为了满足依赖项,vcpkg 需要满足两个约束,一个来自基线,另一个来自 dependencies 列表中的最低版本约束。

  • 基线约束 "version>=": "7.1.3"
  • 依赖项列表约束 "version>=": "10.1.1"

构建并运行项目,将 %VCPKG_ROOT% 替换为 vcpkg 安装路径:

rm -r build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
cmake --build build
./build/main

输出应如下所示:

fmt version is 100100
zlib version is 1.2.11

在这种情况下,fmt 的版本 10.1.1 满足这两个约束。 请注意 zlib 获取其基线版本 1.2.11 的方式。

5 - 强制采用特定版本

在某些情况下,可能需要强制采用特定版本的包,例如:

  • 解决版本冲突。
  • 锁定早于基线的版本。
  • 锁定其他不可比的版本,例如:vistaxp

vcpkg 使你能够使用版本替代来解决这些问题。

vcpkg.json 内容修改为:

{
  "dependencies": [
    {
        "name": "fmt",
        "version>=": "10.1.1"
    },
    "zlib"
  ],
  "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc", 
  "overrides": [
    { 
        "name": "zlib", 
        "version": "1.2.8"
    }
  ]
}

"overrides" 列表中包含的任何包都将使用指定版本,同时忽略所有其他版本约束。 在本例中,基线 3426db05b996481ca31e95fff3734cf23e0f51bc1.2.11zlib 增加了最低版本约束,但替代声明强制改用版本 1.2.8

构建并运行项目,将 %VCPKG_ROOT% 替换为 vcpkg 安装路径:

rm -r build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
cmake --build build
./build/main

输出应如下所示:

fmt version is 100100
zlib version is 1.2.8

后续步骤

在本教程中,你了解了 vcpkg 提供的锁定特定包版本的不同机制。 阅读版本控制概念参考,以详细了解 vcpkg 如何处理版本解析。

以下是接下来要尝试的一些其他任务: