包名称解析
vcpkg 先确定每个包的负责注册表(或覆盖),然后再联系网络。 这样做可以防止包依赖项混淆攻击,因为名称解析不依赖于任何外部状态。
名称解析算法步骤如下:
- 如果在覆盖中找到名称,则使用该覆盖;否则
- 如果存在与端口名称匹配的
"packages"
模式,则使用此注册表;否则 - 如果默认注册表不是
null
,则使用此注册表;否则 - 无法将端口解析为注册表。
如果有多个 "packages"
模式与名称匹配,vcpkg 将如下所示优先设置:
- 通过
boost*
选择完全匹配 --boost
- 通过
b*
选择最长的模式 --boost*
- 第一个匹配 -- 声明最佳模式的第一个注册表已选择
示例 #1:包名称解析
vcpkg-configuration.json
{
"registries": [
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg-docs",
"reference": "vcpkg-registry",
"baseline": "768f6a3ad9f9b6c4c2ff390137690cf26e3c3453",
"packages": ["bei*"]
},
{
"kind": "git",
"repository": "https://github.com/vicroms/vcpkg-registry",
"baseline": "dacf4de488094a384ca2c202b923ccc097956e0c",
"packages": ["beicode", "bei*"]
}
]
}
vcpkg.json
{
"dependencies": [
"beicode",
"beison",
"fmt"
],
"builtin-baseline": "7e7c62d863b1bf599c1d104b76cd8b74475844d4"
}
鉴于此配置,每个包名称解析为:
beicode
:来自注册表https://github.com/vicroms/vcpkg-registry
(在beicode
上完全匹配)beison
:来自注册表https://github.com/Microsoft/vcpkg-docs
(beison
上的模式匹配,并在"registries"
数组中首先声明)fmt
:来自默认注册表(无匹配项)
由于多个注册表声明 bei*
,vcpkg 也会发出警告:
Found the following problems in configuration (path/to/vcpkg-configuration.json):
$ (a configuration object): warning: Package "bei*" is duplicated.
First declared in:
location: $.registries[0].packages[0]
registry: https://github.com/microsoft/vcpkg-docs
The following redeclarations will be ignored:
location: $.registries[1].packages[1]
registry: https://github.com/vicroms/vcpkg-registry
示例 #2:将多个模式分配给默认注册表
可以通过两种方式更改默认注册表。 第一种,通过定义 "default-registry"
:
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3"
}
}
第二种,通过将 "default-registry"
设置为 null
,并在 "registries"
数组中使用 "*"
模式。
{
"default-registry": null,
"registries": [
{
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3",
"packages": ["*"]
}
]
}
第二种形式的优势在于可以向包数组添加更多条目,而 "default-registry"
对象则完全不允许你定义包数组。 当需要确保包来自默认注册表,这种差异变得很重要。
假设有一个注册表可以提供 Qt 架构库。
vcpkg-configuration.json
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "7e7c62d863b1bf599c1d104b76cd8b74475844d4"
},
"registries": [
{
"kind": "git",
"repository": "https://github.com/custom-qt/custom-qt-registry",
"baseline": "adfc4de488094a384ca2c202b923ccc097956e0c",
"packages": ["qt*"]
}
]
}
以及以下项目依赖项:
vcpkg.json
{
"dependencies": [
"qt5",
"qt-advanced-docking-system",
"qtkeychain"
]
}
"qt*"
模式匹配 vcpkg.json
中的所有端口名称。 但是有一个问题! 端口 qt-advanced-docking-system
和 qtkeychain
不是官方 Qt Framework 库的一部分,因为 vcpkg 将无法在自定义注册表中找到端口,安装将失败。
可以通过将这些包分配给默认注册表来修复此问题。
我们通过更改声明默认注册表的方式,并将 qt-advanced-docking-system
和 qtkeychain
添加到其 "packages"
数组来实现。
vcpkg-configuration.json
{
"default-registry": null,
"registries": [
{
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3",
"packages": ["*", "qt-advanced-docking-system", "qtkeychain"]
},
{
"kind": "git",
"repository": "https://github.com/custom-qt/custom-qt-registry",
"baseline": "adfc4de488094a384ca2c202b923ccc097956e0c",
"packages": ["qt*"]
}
]
}
因为完全匹配项优先于模式匹配项,qt-advanced-docking-system
和 qtkeychain
会解析为默认注册表。
覆盖
覆盖是为 vcpkg 扩展更多端口和三联密码的一种方法,无需创建完整的注册表。 在执行任何注册表查找或版本控制之前,会考虑覆盖层,并替换任何内置的三联密码或端口。 有关详细信息,请参阅覆盖端口。
按以下顺序评估覆盖设置:
- 按传递顺序从命令行 覆盖;然后
- 按顺序从
vcpkg-configuration.json
覆盖;然后 - 按顺序从
VCPKG_OVERLAY_[PORTS|TRIPLETS]
环境变量覆盖。