包管道:多配置

在上一节中,我们只构建了一个配置。本节将涵盖需要构建多个配置的情况。为方便起见,我们将在这里使用ReleaseDebug配置,因为它更容易理解,但在实际情况下,这些配置更像是Windows、Linux、OSX,针对不同架构的构建,交叉构建等。

让我们开始清理缓存

$ conan remove "*" -c  # Make sure no packages from last run

我们将在自己的计算机上按顺序创建这两个配置的包,但请注意,这些通常会在不同的计算机上运行,因此CI系统通常会并行启动不同配置的构建。

Release 构建
$ cd ai  # If you were not inside "ai" folder already
$ conan create . --build="missing:ai/*" -s build_type=Release --format=json > graph.json
$ conan list --graph=graph.json --graph-binaries=build --format=json > built.json

$ conan remote enable packages
$ conan upload -l=built.json -r=packages -c --format=json > uploaded_release.json
$ conan remote disable packages

我们做了一些改动和额外的步骤

  • 第一步与上一节中的步骤类似,执行conan create,只是为了清楚起见,明确指定了配置-s build_type=Release,并将conan create的输出捕获到graph.json文件中。

  • 第二步是从graph.json创建built.json包列表文件,其中包含需要上传的包。在本例中,只有从源代码构建的包(--graph-binaries=build)才会被上传。这样做是为了提高效率和加快上传速度。

  • 第三步是启用packages仓库。之前未启用它是为了确保所有可能的依赖都只来自develop仓库。

  • 然后,我们将built.json包列表上传到packages仓库,创建包含包新位置(服务器仓库)的uploaded_release.json包列表。

  • 最后,我们将再次禁用packages仓库

同样,Debug 构建也将执行相同的步骤

Debug 构建
$ conan create . --build="missing:ai/*" -s build_type=Debug --format=json > graph.json
$ conan list --graph=graph.json --graph-binaries=build --format=json > built.json

$ conan remote enable packages
$ conan upload -l=built.json -r=packages -c --format=json > uploaded_debug.json
$ conan remote disable packages

当Release和Debug配置都成功完成后,我们将在仓库中拥有这些包

digraph repositories { node [fillcolor="lightskyblue", style=filled, shape=box] rankdir="LR"; subgraph cluster_0 { label="Packages server"; style=filled; color=lightgrey; subgraph cluster_1 { label = "packages\n repository" shape = "box"; style=filled; color=lightblue; "packages" [style=invis]; "ai/1.1.0\n (Release)"; "ai/1.1.0\n (Debug)"; } subgraph cluster_2 { label = "products\n repository" shape = "box"; style=filled; color=lightblue; "products" [style=invis]; } subgraph cluster_3 { rankdir="BT"; shape = "box"; label = "develop repository"; color=lightblue; rankdir="BT"; node [fillcolor="lightskyblue", style=filled, shape=box] "game/1.0" -> "engine/1.0" -> "ai/1.0" -> "mathlib/1.0"; "engine/1.0" -> "graphics/1.0" -> "mathlib/1.0"; "mapviewer/1.0" -> "graphics/1.0"; "game/1.0" [fillcolor="lightgreen"]; "mapviewer/1.0" [fillcolor="lightgreen"]; } { edge[style=invis]; "packages" -> "products" -> "game/1.0" ; rankdir="BT"; } } }

ai/1.1.0的所有不同二进制文件都正确构建后,包管道可以认为其任务成功并决定提升这些二进制文件。但还需要进一步的包构建和检查,因此包管道不会将它们提升到develop仓库,而是将它们提升到products二进制仓库。由于所有其他开发者和CI都使用develop仓库,因此在此阶段也不会有任何人受到影响

从 packages->product 提升
# aggregate the package list
$ conan pkglist merge -l uploaded_release.json -l uploaded_debug.json --format=json > uploaded.json

$ conan remote enable packages
$ conan remote enable products
# Promotion using Conan download/upload commands
# (slow, can be improved with art:promote custom command)
$ conan download --list=uploaded.json -r=packages --format=json > promote.json
$ conan upload --list=promote.json -r=products -c
$ conan remote disable packages
$ conan remote disable products

第一步使用conan pkglist merge命令合并“Release”和“Debug”配置的包列表,并将其合并为一个单独的uploaded.json包列表。此列表将用于运行提升。

在此示例中,我们使用缓慢的conan download + conan upload提升方式。通过conan art:promote扩展命令,效率可以大大提高。

运行提升后,服务器中将有以下包

digraph repositories { node [fillcolor="lightskyblue", style=filled, shape=box] rankdir="LR"; subgraph cluster_0 { label="Packages server"; style=filled; color=lightgrey; subgraph cluster_1 { label = "packages\n repository" shape = "box"; style=filled; color=lightblue; "packages" [style=invis]; "ai/1.1.0\n (Release)"; "ai/1.1.0\n (Debug)"; } subgraph cluster_2 { label = "products\n repository" shape = "box"; style=filled; color=lightblue; "products" [style=invis]; "ai/promoted release" [label="ai/1.1.0\n (Release)"]; "ai/promoted debug" [label="ai/1.1.0\n (Debug)"]; } subgraph cluster_3 { rankdir="BT"; shape = "box"; label = "develop repository"; color=lightblue; rankdir="BT"; node [fillcolor="lightskyblue", style=filled, shape=box] "game/1.0" -> "engine/1.0" -> "ai/1.0" -> "mathlib/1.0"; "engine/1.0" -> "graphics/1.0" -> "mathlib/1.0"; "mapviewer/1.0" -> "graphics/1.0"; "game/1.0" [fillcolor="lightgreen"]; "mapviewer/1.0" [fillcolor="lightgreen"]; } { edge[style=invis]; "packages" -> "products" -> "game/1.0" ; rankdir="BT"; } } }

总结

  • 我们构建了两种不同的配置,ReleaseDebug(也可以是Windows/Linux或其他),并将它们上传到packages仓库。

  • 当所有配置的所有包二进制文件都成功构建后,我们将它们从packages提升到products仓库,使其可用于products pipeline

  • 包列表在包创建过程中被捕获,并合并为一个,用于运行提升。

我们还有一个方面尚未考虑,即ai/1.1.0的依赖项在构建过程中可能发生变化。请转到下一节,了解如何使用锁定文件实现更一致的多配置构建。