跳到主要内容

教程:安装特定版本的包

注意

此功能仅在清单模式下可用。

kmpkg 允许你精确控制项目中每个依赖项的版本。

在本教程中,你将掌握以下操作:

前提条件

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

1 - 创建带清单的项目

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

源文件(main.cpp):

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):

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)

kmpkg 清单文件(kmpkg.json):

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

构建项目(将 %KMPKG_ROOT% 替换为你的 kmpkg 安装路径):

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%KMPKG_ROOT%/scripts/buildsystems/kmpkg.cmake
cmake --build build

运行程序:

fmt version is 70103
zlib version is 1.2.11

你运行程序时,这些库的版本可能与上述输出不同。下一步中,我们将演示如何锁定这些依赖项的版本,确保每次构建项目时版本保持一致。

2 - 通过基线添加版本约束

版本基线(baseline)为所有包设定了最低版本下限。如需了解基线的详细信息,请阅读kmpkg 核心概念

要锁定上一步中使用的精确版本,将 kmpkg.json 的内容修改为:

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

builtin-baseline 设置为 kmpkg 仓库的特定提交 SHA,会指示 kmpkg 使用该提交对应的包版本作为所有包的最低版本。

你可以通过 Git 查看该基线对应的包版本:

PowerShell

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

bash

git show 3426db05b996481ca31e95fff3734cf23e0f51bc:versions/baseline.json | egrep -A 3 -e '"zlib"|"fmt"'

输出应类似如下内容:

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

3 - 更新基线版本

基线提供了一种便捷的方式,可一次性更新所有依赖项的版本。要更新基线,请运行以下命令:

kmpkg x-update-baseline

x-update-baseline 命令会修改清单文件,将 builtin-baseline 设置为你当前 kmpkg 实例的 Git 最新提交。

若清单文件尚未配置 builtin-baseline,可使用 --add-initial-baseline 选项为其添加初始基线。

4 - 添加最低版本约束

基线并非锁定包版本的唯一方式,kmpkg 还支持通过 version>= 格式设置最低版本约束。

kmpkg.json 的内容修改为:

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

上述清单文件使用依赖项对象语法为 fmt 设置了最低版本约束(version>=)。kmpkg 需同时满足两个约束条件:一是来自基线的约束,二是来自 dependencies 列表的最低版本约束。

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

构建并运行项目(将 %KMPKG_ROOT% 替换为你的 kmpkg 安装路径):

rm -r build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%KMPKG_ROOT%/scripts/buildsystems/kmpkg.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)。

kmpkg 支持通过版本覆盖(version overrides)解决这些问题。

kmpkg.json 的内容修改为:

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

包含在 "overrides" 列表中的包会忽略所有其他版本约束,强制使用指定版本。本示例中,基线 3426db05b996481ca31e95fff3734cf23e0f51bczlib 设置的最低版本约束是 1.2.11,但覆盖声明强制使用 1.2.8 版本。

构建并运行项目(将 %KMPKG_ROOT% 替换为你的 kmpkg 安装路径):

rm -r build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%KMPKG_ROOT%/scripts/buildsystems/kmpkg.cmake
cmake --build build
./build/main

输出应如下所示:

fmt version is 100100
zlib version is 1.2.8

后续步骤

在本教程中,你学习了 kmpkg 提供的多种锁定包特定版本的机制。如需了解 kmpkg 版本解析的更多细节,请阅读版本控制核心概念参考文档

你可尝试以下进阶操作: