使用 packages-lists¶
注意
此特性处于 预览版 阶段。这意味着它极不可能被移除,且不太可能引入破坏性变更。维护者将尽可能避免破坏此特性,仅在非常必要时才会进行。更多信息请参阅 Conan 稳定性 部分。
Packages lists(包列表)是 Conan 的一个强大且便捷的特性,它允许自动化和串联不同的 Conan 命令。我们来看看一些常见的用例
列出包并下载它们¶
一个简单的用例可以是列出服务器上的某些 recipe 和/或二进制包,然后下载它们。
我们可以执行任何 conan list
命令,例如,列出所有高于 1.2.11
的 zlib
版本、最新的 recipe revision、该最新 recipe revision 的所有 Windows 二进制包,最后是每个二进制包的最新 package revision。请注意,如果之后确实想要下载某些内容,则必须指定 latest
package revision,否则只会下载 recipe。
$ conan list "zlib/[>1.2.11]#latest:*#latest" -p os=Windows --format=json -r=conancenter > pkglist.json
命令的输出以 json
格式发送到文件 pkglist.json
中,其内容如下:
"conancenter": {
"zlib/1.2.12": {
"revisions": {
"b1fd071d8a2234a488b3ff74a3526f81": {
"timestamp": 1667396813.987,
"packages": {
"ae9eaf478e918e6470fe64a4d8d4d9552b0b3606": {
"revisions": {
"19808a47de859c2408ffcf8e5df1fdaf": {
}
},
"info": {
"settings": {
"arch": "x86_64",
"os": "Windows"
}
}
}
}
}
},
"zlib/1.2.13": {
}
}
pkglist.json
文件中的第一层是“来源” remote 或“Local Cache”(如果列表是在本地缓存中生成)。在本例中,由于我们在 conancenter
remote 中列出了包,因此该 remote 就是来源。
现在我们可以通过一个 conan download
命令调用来下载这些 recipe 和二进制包
$ conan download --list=pkglist.json -r=conancenter
# Download the recipes and binaries in pkglist.json
# And displays a report of the downloaded things
从一个 remote 下载并上传到另一个 remote¶
假设我们从上一步下载的包中创建一个新的 package list
$ conan download --list=pkglist.json -r=conancenter --format=json > downloaded.json
# Download the recipes and binaries in pkglist.json
# And stores the result in "downloaded.json"
生成的 downloaded.json
文件与 pkglist.json
文件几乎相同,但在本例中,这些包的“来源”是 "Local Cache"
(因为下载的包将位于缓存中)
"Local Cache": {
"zlib/1.2.12": {
"revisions": {
}
}
}
这意味着我们现在可以将同一组 recipe 和二进制包上传到另一个 remote
$ conan upload --list=downloaded.json -r=myremote -c
# Upload those artifacts to the same remote
注意
最佳实践
这是一种在不同服务器仓库之间进行迁移(promotions)的缓慢机制。像 Artifactory 这样的服务器提供了无需客户端即可直接在仓库之间复制包的方法,由于文件去重,其速度要快几个数量级,因此这是推荐的方法。本节介绍的方法可用于气隙环境 (air-gapped environments) 以及无法进行服务器到服务器复制的其他情况。
构建并上传包¶
最有趣的流程之一是在本地缓存中使用 conan create
或 conan install --build=xxx
命令构建一些包。通常,我们会希望将本地构建的包上传到服务器,以便其他人不必再次重新构建。但我们可能只想上传构建好的二进制包,而不是所有其他传递性依赖 (transitive dependencies) 或之前已存在于本地缓存中的其他包。
可以从 conan install
、conan create
和 conan graph info
命令的输出中计算 package list。然后,可以使用该 package list 进行上传。分步说明如下:
首先假设我们有一个自己的包 mypkg/0.1
,然后我们创建它
$ conan new cmake_lib -d name=mypkg -d version=0.1
$ conan create . --format=json > create.json
这将生成依赖图的 json 表示形式,其中包含哪些包已被构建的信息 "binary": "Build"
{
"graph": {
"nodes": {
"0": {
"ref": "conanfile",
"id": "0",
"recipe": "Cli",
"context": "host",
"test": false
},
"1": {
"ref": "mypkg/0.1#f57cc9a1824f47af2f52df0dbdd440f6",
"id": "1",
"recipe": "Cache",
"package_id": "2401fa1d188d289bb25c37cfa3317e13e377a351",
"prev": "75f44d989175c05bc4be2399edc63091",
"build_id": null,
"binary": "Build"
}
}
}
我们可以从这个文件中计算 package list,然后将这些 artifact 上传到服务器,使用
$ conan list --graph=create.json --graph-binaries=build --format=json > pkglist.json
# Create a pkglist.json with the known list of recipes and binaries built from sources
$ conan upload --list=pkglist.json -r=myremote -c
移除 package list¶
也可以先执行 conan list
来创建一个要移除的列表,然后再进行移除
# Removes everything from the cache
$ conan list "*#*" --format=json > pkglist.json
$ conan remove --list=pkglist.json -c
请注意,在这种情况下,list
和 remove
命令的默认模式(patterns)是不同的,因为 conan remove
命令具有破坏性。
当 recipe 被传递给
remove
命令时,例如conan remove zlib/1.2.13
,它将移除zlib/1.2.13
的 recipe 及其所有二进制包,因为二进制包不能独立于 recipe 存在。当传递
package_id
时,例如conan remove zlib/1.2.13:package_id
,则会移除该特定的package_id
,但 recipe 不会被移除。
因此,如果我们直接调用 conan remove
命令,或者先调用 conan list
命令,用于移除所有内容的模式(pattern)将有所不同,例如:
# Removes everything from the cache
$ conan remove "*"
# OR via list, we need to explicitly include all revisions
$ conan list "*#*" --format=json > pkglist.json
$ conan remove --list=pkglist.json -c
# Removes only the binaries from the cache (leave recipes)
$ conan remove "*:*"
# OR via list, we need to explicitly include all revisions
$ conan list "*#*:*" --format=json > pkglist.json
$ conan remove --list=pkglist.json -c
更多信息请参阅 参考命令部分