利用平台进行构建

报告问题 查看来源 每晚 · 7.2。 · 7.1敬上 · 7.0 · 6.5 条 · 6.4

Bazel 为建模平台工具链。将其与真实项目集成需要 代码所有者、规则维护人员和核心 Bazel 开发者之间密切合作。

本页总结了平台的用途,并展示了如何使用这些平台构建应用。

tl;dr:Bazel 的平台和工具链 API 可用,但无法正常运行 直到所有语言规则、select() 和其他旧版引用 。这项工作仍在进行中。最终,所有 build 都将基于平台。 请阅读下文,了解您的 build 的适用区域。

如需查看更正式的文档,请参阅:

背景

引入了平台工具链,以实现软件 项目针对不同的机器,并使用合适的语言工具进行构建。

这是相对新近的 Bazel 添加功能。时间是 启发了 观察到语言维护者已经在投放广告中采取了这种做法 临时的、不兼容的方式。例如,C++ 规则使用 --cpu--crosstool_top 来设置 build 的目标 CPU 和 C++ 工具链。这两个模型都不正确 即“平台”历史上尝试这样做的尝试导致了构建尴尬且不准确的构建。 这些标志也不控制 Java 编译,而 Java 编译已经发展出了自己的 与 --java_toolchain 的独立接口。

Bazel 适用于大型、多语言和多平台项目。这个 需要更有条理地支持这些概念,包括清晰明了的 API, 鼓励语言和项目的互操作性。这就是这些新的 API 。

迁移

平台和工具链 API 仅在项目实际使用它们时才有效。这个 项目的规则逻辑、工具链、依赖项和 select() 必须支持它们。这需要谨慎的迁移序列 确保所有项目及其依赖项正常运行。

例如,Bazel 的 C++ 规则支持平台。但 Apple 规则则不然。您的 C++ 项目 可能并不关心 Apple但其他人可能会。因此 为所有 C++ build 全局启用平台尚不安全。

本页的其余部分将介绍此迁移顺序,以及迁移方式和时机

目标

当所有项目都使用以下格式构建时,Bazel 的平台迁移完成:

bazel build //:myproject --platforms=//:myplatform

这意味着:

  1. 项目使用的规则可以推断出正确的工具链 //:myplatform
  2. 项目的依赖项使用的规则可以推断出正确的工具链 //:myplatform起。
  3. 根据您的项目任何项目//:myplatform 项目支持旧版 API(例如 --crosstool_top)。
  4. //:myplatform 参考 [通用声明][通用平台声明]{: .external} 包含 CPUOS 和其他支持自动跨项目的通用概念 兼容性。
  5. 所有相关项目的 select() 了解 //:myplatform 隐含的机器属性。
  6. //:myplatform 在清晰且可重复使用的位置进行定义:在项目的 如果平台是您的项目独有的,则使用 repo;否则为所有项目 其他对象。

实现此目标后,旧 API 将被移除。然后 成为项目选择平台和工具链的标准方式。

我是否应该使用平台?

如果您只想构建或交叉编译项目,则应遵循 项目的官方文档。

如果您是项目、语言或工具链维护人员,您最终会希望 来支持这些新 API是否等待全局迁移完成 或提前选择启用,具体取决于您的具体价值 / 费用需求:

  • 您可以使用 select() 或选择您关注的属性上的工具链 而不是 --cpu 等硬编码标记。例如, 可以支持相同的指令集
  • 更正确的 build。如果您在上述示例中通过 --cpu 使用 select(),则 添加支持相同指令集的新 CPU,即 select() 出现故障。但平台上的 select() 仍然是准确的。
  • 更简单的用户体验。所有项目都了解: --platforms=//:myplatform。无需使用多种语言版本 标志。
  • 语言设计更简单。所有语言使用相同的 API 来定义 工具链、使用工具链,以及为平台选择正确的工具链。
  • 您可在以下位置跳过目标: 构建和测试阶段(如果它们与目标平台不兼容)。

费用

  • 尚不支持平台的依赖项目可能无法自动运行 。
  • 使它们正常运行可能需要额外的临时维护
  • 新旧 API 共存需要更仔细的用户指导, 避免混淆
  • 常见属性的规范定义,例如 OSCPU 仍在发展中,可能需要额外的初始贡献。
  • 针对特定语言的工具链的规范定义仍然在不断演变, 可能需要额外的初始贡献。

API 审核

platform 是一系列 constraint_value 个目标

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value 是机器 属性。同一“kind”的值归到一个通用规则下 constraint_setting

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchainStarlark 规则。其 属性声明语言工具(例如 compiler = "//mytoolchain:custom_gcc")。其提供程序通行证 将这些信息传递给需要使用这些工具构建的规则。

工具链会声明它们可以运行的机器的 constraint_value 目标 (target_compatible_with = ["@platforms//os:linux"]) 以及他们的工具 运行位置 (exec_compatible_with = ["@platforms//os:mac"]).

构建 $ bazel build //:myproject --platforms=//:myplatform 时,Bazel 它会自动选择可以在构建机器上运行的工具链 针对 //:myplatform 的 build 二进制文件。这称为工具链解析。

您可以使用以下命令在 WORKSPACE 中注册这组可用工具链 register_toolchains或在 和 --extra_toolchains 搭配使用。

如需深入了解,请点击此处

状态

当前平台支持因语言而异。Bazel 的所有主要规则都是 迁移到平台但此过程需要一些时间。这主要有三个原因:

  1. 必须更新规则逻辑,才能从新的工具链中获取工具信息 API (ctx.toolchains) 并停止读取旧版设置,例如 --cpu--crosstool_top。这种方法相对简单。

  2. 工具链维护人员必须定义工具链,并使其可供 用户(在 GitHub 代码库和 WORKSPACE 条目中)。 这在技术上很简单,但必须巧妙地组织 保持轻松的用户体验

    还需要进行平台定义(除非您针对同一台机器构建 运行 Bazel)。通常,项目应定义自己的平台。

  3. 您必须迁移现有项目。select() 秒和 转场效果 已迁移。这是最大的挑战。对于企业来说 多语言项目(如果所有语言都无法读取,则可能会失败 --platforms)。

如果您要设计新的规则集,必须支持 开头。这样,您的规则就会自动与其他 随着平台 API 变得越来越完善, 更加普遍

通用平台属性

各个项目通用的平台属性(例如 OSCPU)应该 在标准的集中位置声明这样可以鼓励跨项目 和跨语言兼容性

例如,如果 MyAppconstraint_value 上有 select() @myapp//cpus:armSomeCommonLibselect() @commonlib//constraints:arm,它们会触发其“实验组”模式(具有不兼容的模式) 条件。

全局通用属性在 @platforms 代码库 (因此,上述示例的规范标签是 @platforms//cpu:arm)。 语言通用属性应在其各自对应的代码库中声明 语言。

默认平台

通常,项目所有者应定义明确的 平台来描述 各种机器的机器类型然后 --platforms

如果未设置 --platforms,则 Bazel 默认使用一个 platform 表示 本地构建机器。这是 @local_config_platform//:host 自动生成的 因此无需明确定义它会映射本地机器的 OS 以及 CPU(其中声明了 constraint_value@platforms

C++

在设置工具链时,Bazel 的 C++ 规则使用平台来选择工具链 --incompatible_enable_cc_toolchain_resolution (#7260)。

这意味着您可以用以下代码配置 C++ 项目:

bazel build //:my_cpp_project --platforms=//:myplatform

而不是旧版:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

如果您的项目是纯 C++ 项目,非 C++ 项目并不依赖于该项目,则可以使用 您的select转场效果是兼容的。请参阅 #7260 和 如需更多指导,请参阅配置 C++ 工具链

此模式默认处于停用状态。这是因为,Apple 项目 仍使用 --cpu--crosstool_top 配置 C++ 依赖项 (示例)。这取决于迁移到平台的 Apple 规则。

Java

Bazel 的 Java 规则使用平台。

这取代了旧版标志 --java_toolchain--host_java_toolchain--javabase--host_javabase

如需了解如何使用配置标志,请参阅 Bazel 和 Java 手册。 如需了解详情,请参阅设计文档

如果您仍在使用旧版标志,请按照问题 7849 中的迁移流程操作。

Android

在设置工具链时,Bazel 的 Android 规则会使用平台来选择工具链 --incompatible_enable_android_toolchain_resolution

默认情况下,此功能处于停用状态。不过,迁移工作正在进行之中。

Apple

Bazel 的 Apple 规则尚不支持用于选择 Apple 工具链的平台。

它们也不支持启用平台的 C++ 依赖项,因为它们使用 旧版 --crosstool_top 来设置 C++ 工具链。在迁移完成之前 可以将 Apple 项目、支持 Platom 的 C++ 和平台 映射示例)。

其他语言

如果您要为新语言设计规则,请使用平台 选择语言的工具链。请参阅 工具链文档,获取详细的演示。

select()

项目可以select() constraint_value 个目标,但尚未完成 平台。这是有意为之,以便 select() 支持尽可能多的 尽可能多地训练机器。包含 ARM 专用源代码的库应支持 所有ARM 提供支持的机器,除非有具体理由。

如需选择一个或多个 constraint_value,请使用以下命令:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

这相当于传统上在 --cpu 上进行选择:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

如需了解更多详情,请点击此处

--cpu--crosstool_top 等平台上的 select 无法识别 --platforms。时间 将项目迁移到平台时,您必须将其转换为 constraint_values 或使用平台映射来支持 在迁移窗口中选择这两种样式

转场效果

Starlark 过渡变更 对构建图的各个部分进行标记如果您的项目使用 设置 --cpu--crossstool_top 或其他旧版标志、规则 --platforms不会看到这些更改。

将项目迁移到平台时,您必须将更改(例如 return { "//command_line_option:cpu": "arm" }return { "//command_line_option:platforms": "//:my_arm_platform" }或使用平台 映射,以便在迁移过程中同时支持这两种样式 窗口。

当前如何使用平台

如果您只想构建或交叉编译项目,则应遵循 项目的官方文档。取决于语言和项目维护人员 确定与平台集成的方式和时机,以及集成的价值。

如果您是项目、语言或工具链维护人员,但构建 使用平台时,您有三种选择(除了等待 迁移):

  1. 翻转“使用平台”标记(如果 one),并进行所需的测试,看看您关注的项目是否 工作内容

  2. 如果您关心的项目仍然依赖于 --cpu--crosstool_top,请将这些内容与 --platforms 结合使用:

    bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
    

    这会有一些维护成本(您必须手动确保设置 匹配)。但在没有反派行为的情况下,这种方法应该有效 过渡

  3. 编写平台映射来同时支持这两种样式,具体做法如下: 将 --cpu 样式的设置映射到相应的平台,反之亦然。

平台映射

平台映射是一种临时 API,可让由平台提供支持的 通过在 build 中弃用后者,旧版驱动的逻辑在同一 build 中共存 窗口。

平台映射是 platform() 到 一组相应的旧版标志(反之亦然)。例如:

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin
  --apple_platform_type=macos
    //platforms:macos

Bazel 使用此 ID 来保证所有设置,包括基于平台的设置 在整个构建过程中始终适用,包括 过渡

默认情况下,Bazel 会从platform_mappings 工作区根目录。您还可以设置 --platform_mappings=//:my_custom_mapping

请参阅 此处 了解完整详情。

问题

如需获得常规支持或咨询有关迁移时间表的问题,请联系 bazel-discuss@googlegroups.com 或相应规则的所有者

有关平台/工具链 API 的设计和演变的讨论, 联系人 bazel-dev@googlegroups.com

另请参阅