产品流水线:构建顺序¶
上一节使用了 --build=missing
在同一台 CI 机器上构建所有必要的软件包。这并非总是理想的,甚至不可能,在许多情况下,最好进行分布式构建,以实现更快的构建并更好地利用 CI 资源。最自然的构建负载分配方式是在不同的机器上构建不同的软件包。让我们看看如何使用 conan graph build-order
命令来实现这一点。
像往常一样,首先确保我们拥有一个具有正确仓库定义的干净环境。
# First clean the local "build" folder
$ pwd # should be <path>/examples2/ci/game
$ rm -rf build # clean the temporary build folder
$ mkdir build && cd build # To put temporary files
$ conan remove "*" -c # Make sure no packages from last run
# NOTE: The products repo is first, it will have higher priority.
$ conan remote enable products
我们现在将忽略 mapviewer/1.0
产品,并将本节重点放在 game/1.0
产品上。第一步是计算“构建顺序”,即需要构建的软件包列表及其顺序。这可以通过以下 conan graph build-order
命令完成。
$ conan graph build-order --requires=game/1.0 --build=missing --order-by=recipe --reduce --format=json > game_build_order.json
请注意几个要点
必须以与上一节完全相同的方式使用
--build=missing
。未能提供预期的--build
策略和参数将导致不完整或错误的构建顺序。--reduce
参数会删除结果顺序中所有不具有binary: Build
策略的元素。这意味着,生成的“构建顺序”不能与其他构建顺序文件合并以将其聚合到一个文件中,这在存在多个配置和产品时非常重要。--order-by
参数允许按“recipe”或“configuration”定义不同的顺序。在本例中,我们使用--order-by=recipe
,其目的是并行构建每个 recipe,这意味着,在构建engine/1.0
的任何使用者之前,应首先构建给定软件包(如engine/1.0
)的所有可能不同的二进制文件。
生成的 game_build_order.json
如下所示
{
"order_by": "recipe",
"reduced": true,
"order": [
[
{
"ref": "engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb",
"packages": [
[
{
"package_id": "de738ff5d09f0359b81da17c58256c619814a765",
"binary": "Build",
"build_args": "--requires=engine/1.0 --build=engine/1.0",
}
]
]
}
],
[
{
"ref": "game/1.0#1715574045610faa2705017c71d0000e",
"depends": [
"engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb"
],
"packages": [
[
{
"package_id": "bac7cd2fe1592075ddc715563984bbe000059d4c",
"binary": "Build",
"build_args": "--requires=game/1.0 --build=game/1.0",
}
]
]
}
]
]
}
为方便起见,与 conan graph info ... --format=html > graph.html
可以生成包含 HTML 交互式依赖关系图的文件的方式相同,conan graph build-order ... --format=html > build_order.html
可以生成上述 json 文件的 HTML 可视化表示。
生成的 json 包含一个 order
元素,它是一个列表的列表。这种排列方式很重要,顶层列表中的每个元素都是一组可以并行构建的软件包,因为它们之间没有任何关系。您可以将此列表视为“级别”列表,在级别 0 中,存在不依赖于任何其他正在构建的软件包的软件包,在级别 1 中,存在仅依赖于级别 0 中元素的软件包,依此类推。
然后,最外层列表中元素的顺序非常重要,必须遵守。在完成一个列表项中所有软件包的构建之前,不可能开始下一个“级别”的构建。
使用 graph_build_order.json
文件中的信息,可以执行必要的软件包的构建,方式与上一节的 --build=missing
相同,但不是由我们直接管理。
从 json 中获取参数,要执行的命令将是
$ conan install --requires=engine/1.0 --build=engine/1.0
$ conan install --requires=game/1.0 --build=game/1.0
我们正在手动执行这些命令,但在实践中,它将是 CI 中在 json 输出上执行的 for
循环。我们稍后将看到一些 Python 代码。此时,我们希望关注 conan graph build-order
命令,但我们尚未真正解释如何进行分布式构建。
另请注意,每个元素内部都有一个内部列表的列表,即 "packages"
部分,其中包含必须为特定 recipe 的不同配置构建的所有二进制文件。
现在让我们看看如何计算多产品、多配置构建顺序。