注册表概念

概述

vcpkg 在 https://github.com/Microsoft/vcpkg 托管一些被打包到端口的库。 此端口集合称为精选注册表。 但是,vcpkg 不限于特选注册表。 用户可以通过创建自定义注册表来扩展端口选择。

注册表是按特定结构排列的端口和帮助程序文件的集合。 通过遵循注册表结构,注册表中包含的端口可以与精选注册表中提供给端口的相同功能(版本控制二进制缓存)一起安装。

目前有三种类型的注册表:

可以使用 vcpkg-configuration.json 文件来指示 vcpkg 考虑自定义注册表中可用的端口。 有关如何在项目中使用自定义注册表的教程,请参阅 教程:从基于 Git 的注册表安装依赖项 一文。

注册表结构

若要使 vcpkg 与注册表进行交互,它必须符合以下结构:

  • 名为 ports 的目录包含端口集合,每个子目录包含与子目录名称匹配的特定端口。 例如,端口 foo 的文件位于 ports/foo中。
  • 名为 versions 的目录包含构成 版本数据库的文件。

示例:注册表结构

ports/
  foo/
    portfile.cmake
    vcpkg.json
versions/
  f-/
    foo.json
  baseline.json

版本数据库

所有注册表都包含注册表根目录中的 versions 目录,其中包含 版本数据库

版本数据库有两个组件:

  • 基线文件
  • 版本文件

基线文件是一个名为 baseline.json 的 JSON 文件,该文件位于 versions 目录的根目录中。

版本文件是 JSON 文件,其名称与可用端口相同。 它们必须存在于 versions/<prefix>/<port name>.json,其中 <prefix> 是端口名称的第一个字母,后接一个连字符。 例如,端口 foo 的版本文件必须位于 versions/f-/foo.json

版本文件的用途有两个方面:

  • 列出每个端口的所有可用版本
  • 指向每个版本的检索位置。

版本文件的格式取决于注册表的类型。

基线文件

所有注册表(无论其类型如何)都必须包含一个名为 baseline.json 的文件,该文件位于 versions/baseline.json

基线文件的目的是描述被视为注册表中所有端口的最新版本集。 预计每次将新版本的端口添加到注册表时,都会更新此文件。

该文件是由一个对象组成的 JSON 文件,其属性命名为基线对象。 每个基线对象的属性都是端口名称,其值是版本条目。 注册表参考文章更详细地介绍了基线文件的布局。

每个基线版本条目都是具有以下属性的对象:

  • baseline:该值是与其相应 vcpkg.json 文件匹配的端口版本。
  • port-version:该值是端口的port-version,与其对应的vcpkg.json文件相匹配。

示例基线文件

{
  "default": {
    "foo": { "baseline": "1.0.0", "port-version": 0 },
    "bar": { "baseline": "2024-08-01", "port-version": 1 },
    "baz": { "baseline": "vista-xp", "port-version": 0 }
  }
}

请参阅以下参考文档:

版本文件

注册表中的每个端口都有相应的版本文件。 版本文件存储在 versions/<prefix>/<port name>.json,其中 <prefix> 是端口名称的第一个字母,后跟连字符。 例如,端口 foo 的版本文件在 versions/f-/foo.json

版本文件的目的是双重的:

  • 列出每个端口的所有可用版本
  • 指示这些版本各自的检索位置

版本文件的布局是包含 "versions" 数组的对象,该数组中的每个条目都是版本对象。 版本对象必须包含以下属性:

  • 版本属性:属性的键和值必须与端口在其 vcpkg.json 文件中使用的值匹配。 密钥必须是 versionversion-semverversion-dateversion-string之一;该值必须是端口清单文件(vcpkg.json)中显示的版本。
  • port-version:值是端口的 port-version,因为它出现在端口的 vcpkg.json 文件中。
  • git-tree:(仅在 Git 注册表上)值是对应于端口目录的 git 树 SHA。 这是通过对端口目录的内容进行哈希计算的 SHA;Git 可以使用此 git 树 SHA 来检索与提供的 git 树匹配的端口的内容。 这使得 vcpkg 可以从注册表 Git 历史记录中检索旧版本的端口。 请阅读 git 注册表 部分,了解如何获取任何给定端口版本的此值。
  • path:(仅在文件系统注册表上)该值是包含特定版本的端口文件的目录的完整路径。

文件系统注册表版本文件的示例

{
  "versions": [
    {
      "path": "$/ports/foo/1.2.0",
      "version": "1.2.0",
      "port-version": 0
    },
    {
      "path": "$/ports/foo/1.1.0",
      "version": "1.1.0",
      "port-version": 0
    },
    {
      "path": "$/ports/foo/1.0.0",
      "version": "1.0.0",
      "port-version": 0
    }
  ]
}

请参阅以下参考文档:

内置注册表

内置注册表是一种特殊的注册表。 它是 经典模式中使用的默认注册表。 在 清单模式中,如果未指定 默认注册表,vcpkg 会隐式使用内置注册表。

内置注册表是指在您从 https://github.com/Microsoft/vcpkg 对 vcpkg 存储库进行 git clone 操作时创建的精选注册表的本地副本。 某些操作预期 VCPKG_ROOT 环境变量 指向内置注册表。

如果 vcpkg 是通过“一行命令”或 Visual Studio 安装程序获取的,那么内置注册表将等同于指向 https://github.com/Microsoft/vcpkg 存储库的 Git 注册表

Git 注册表

Git 注册表是一个存储库,遵循注册表结构,并利用 Git 的功能为注册表中的端口提供版本控制。 https://github.com/Microsoft/vcpkg 的特选注册表是 Git 注册表的实现。

Git 注册表可以托管在任何 Git 存储库提供程序中,使你能够使用所选的 Git 托管服务来控制对自定义注册表的访问,同时使注册表易于共享。

Git 注册表是实现自定义注册表的建议方法。 由于版本控制机制与特选注册表使用相同的版本控制机制,因此 Git 注册表可以使用 x-add-version 来管理版本数据库文件。

有关 Git 注册表的实施详细信息,请参阅 注册表参考

将新版本添加到 Git 注册表

x-add-version 命令可用于向注册表添加新端口或新版本。 使用此命令添加版本时,需要注意以下几点:

重要

添加新版本时,请始终记得将端口的声明版本更新为尚未发布的版本,以避免重写版本历史记录。

对端口进行更改时,第一步应该是在 vcpkg.json 文件中增加其版本。 如果更改包括对包上游 版本的 更新,请记住将 port-version 设置为 0;否则,请记住将 port-version 增加一个。

x-add-version 命令 要求在更新版本数据库之前将所有端口更改提交到存储库。

示例:将新的端口版本添加到 Git 注册表

git add ports/foo/.
git commit -m "Temporary commit"
vcpkg x-add-version --x-builtin-ports-root=./ports --x-builtin-registry-versions-dir=./versions foo
added version 1.0.0#1 to path/to/registry/versions/f-/foo.json
added version 1.0.0#1 to path/to/registry/versions/baseline.json

重定向选项 --x-builtin-ports-root--x-builtin-registry-versions-dir 应分别指向注册表的 portsversions 目录。

一旦 x-add-version 命令成功运行,请修改上一次的提交记录,以将版本文件的更改包含在内。

git commit --amend -m "Update foo to new version"

Filesystem 注册表

文件系统注册表是驻留在文件系统上的注册表的实现。 它们遵循常见的注册表结构,但不利用 Git 提供版本控制功能。 相反,它们使用版本控制的基元形式,为每个版本的端口使用不同的路径。

此类注册表适合作为端口的测试平台,也可以为非 Git 版本控制系统中的注册表提供替代方案。 不建议将文件系统注册表用于大量端口的集合,也没有提供工具来管理此类注册表的版本数据库文件。

有关如何实现文件系统注册表的详细信息,请参阅 注册表参考

使用注册表

若要在项目中使用自定义注册表,需要在项目的 清单文件(vcpkg.json旁边创建一个 配置文件(vcpkg-configuration.json

默认注册表

解析端口名称时,当端口的名称与 registries 数组中其他注册表声明的任何 模式不匹配时,默认注册表将充当回退。

为了方便不与自定义注册表交互的用户,vcpkg 隐式添加 内置注册表 作为默认注册表。 若要更改此行为,可以将默认注册表设置为任何注册表,或使用 default-registry 属性将其完全禁用。

示例:将自定义注册表设置为默认值

vcpkg-configuration.json

{
  "default-registry": {
    "kind": "git",
    "repository": "https://github.com/Microsoft/vcpkg",
    "baseline": "84a143e4caf6b70db57f28d04c41df4a85c480fa"
  }
}

示例:禁用默认注册表

vcpkg-configuration.json

{
  "default-registry": null
}

注册表数组

若要扩展可使用 vcpkg 安装的端口选择,可以使用 registries 数组指定其他注册表。

示例:将自定义注册表添加到配置

注意

根据注册表类型,可能需要在 registries 数组中提供不同的信息。 请参阅 vcpkg-configurtion.json 参考,了解每种注册表类型所需的属性。

vcpkg-configuration.json

{
  "default-registry": {
    "kind": "git",
    "repository": "https://github.com/Microsoft/vcpkg",
    "baseline": "84a143e4caf6b70db57f28d04c41df4a85c480fa"
  },
  "registries": [
    {
      "kind": "git",
      "repository": "https://my.privateregistry.git",
      "baseline": "caf6b70db5784a143e4f28d05c480fa4c41df4a8",
      "packages": [ "foo" ]
    },
    {
      "kind": "filesystem",
      "path": "C:/path/to/registry",
      "baseline": "baseline1",
      "packages": [ "bar" ]
    }
  ]
}

不要重写版本历史记录

将版本发布到版本文件后,请不要在 git 注册表或文件系统注册表的目录中更改其关联的 git-tree

vcpkg 的设计原则之一是,安装依赖项的版本在用户干预的情况下不会更改。 通过更改 git-tree 条目重写版本文件历史记录违反了此原则。

如果现有版本有问题,首选创建新的 port-version

请勿删除版本文件

注意

本部分仅适用于 Git 注册表

从注册表中删除端口时,请从端口目录及其基线文件中的条目中删除其内容。 但不要删除其关联的版本文件。

即使注册表中不再存在端口,只要版本文件仍然存在,该端口的用户也可以使用 版本 overrides安装旧版本。

后续步骤

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