自动执行组 (AEG)

报告问题 查看来源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

自动执行组会为每种工具链类型选择一个执行平台。换句话说,一个目标可以有多个执行平台,而无需定义执行组。

快速摘要

自动执行组与工具链密切相关。如果您使用的是工具链,则需要通过添加 toolchain 参数在受影响的操作(使用可执行文件或工具链中的工具的操作)中设置工具链。例如:

ctx.actions.run(
    ...,
    executable = ctx.toolchain['@bazel_tools//tools/jdk:toolchain_type'].tool,
    ...,
    toolchain = '@bazel_tools//tools/jdk:toolchain_type',
)

如果操作未使用工具链中的工具或可执行文件,并且 Blaze 未检测到这一点(系统会引发错误),您可以设置 toolchain = None

如果您需要在单个执行平台(某个操作使用来自两个或更多工具链的可执行文件或工具)上使用多个工具链,则需要手动定义 exec_groups(请参阅何时应使用自定义 exec_group?部分)。

历史记录

在推出 AEG 之前,执行平台是在规则级别选择的。例如:

my_rule = rule(
    _impl,
    toolchains = ['//tools:toolchain_type_1', '//tools:toolchain_type_2'],
)

规则 my_rule 注册了两种工具链类型。这意味着,用于查找同时支持这两种工具链类型的执行平台的工具链解析。除非使用 exec_groups 另行指定,否则所选的执行平台将用于规则内的每个已注册的操作。换句话说,规则中的所有操作过去都使用单个执行平台,即使它们使用了来自不同工具链的工具也是如此(为每个目标选择执行平台)。如果执行平台不支持所有工具链,就会导致失败。

当前状态

借助 AEG,可以为每种工具链类型选择执行平台。之前示例中的实现函数 my_rule 如下所示:

def _impl(ctx):
    ctx.actions.run(
      mnemonic = "First action",
      executable = ctx.toolchain['//tools:toolchain_type_1'].tool,
      toolchain = '//tools:toolchain_type_1',
    )

    ctx.actions.run(
      mnemonic = "Second action",
      executable = ctx.toolchain['//tools:toolchain_type_2'].tool,
      toolchain = '//tools:toolchain_type_2',
    )

此规则创建了两个操作,即使用来自 //tools:toolchain_type_1 的可执行文件的 First action 和使用来自 //tools:toolchain_type_2 的可执行文件的 Second action。在推出 AEG 之前,这两个操作都会在支持这两种工具链类型的单个执行平台上执行。借助 AEG,通过在操作中添加 toolchain 参数,每个操作都会在提供工具链的执行平台上执行。操作可能会在不同的执行平台上执行。

ctx.actions.run_shell 也是如此,当 tools 来自工具链时,应添加 toolchain 参数。

自定义执行组与自动执行组之间的区别

顾名思义,AEG 是为规则上注册的每种工具链类型自动创建的执行组。与“经典”执行组不同,您无需手动指定它们。此外,AEG 的名称会自动设置为其工具链类型(例如 //tools:toolchain_type_1)。

何时应使用自定义 exec_group?

只有在需要在单个执行平台上执行多个工具链的情况下,才需要自定义 exec_groups。在所有其他情况下,无需定义自定义 exec_groups。例如:

def _impl(ctx):
    ctx.actions.run(
      ...,
      executable = ctx.toolchain['//tools:toolchain_type_1'].tool,
      tools = [ctx.toolchain['//tools:toolchain_type_2'].tool],
      exec_group = 'two_toolchains',
    )
my_rule = rule(
    _impl,
    exec_groups = {
        "two_toolchains": exec_group(
            toolchains = ['//tools:toolchain_type_1', '//tools:toolchain_type_2'],
        ),
    }
)

AEG 的迁移

在 Google3 内部,Blaze 已经在使用 AEG。 对于 Bazel,外部迁移正在进行中。有些规则已在使用此功能(例如 Java 和 C++ 规则)。

哪些 Bazel 版本支持此迁移?

从 Bazel 7 开始,完全支持 AEG。

如何启用 AEG?

--incompatible_auto_exec_groups 设置为 true。如需详细了解该标志,请参阅此 GitHub 问题

如何在特定规则内启用 AEG?

为规则设置 _use_auto_exec_groups 属性。

my_rule = rule(
    _impl,
    attrs = {
      "_use_auto_exec_groups": attr.bool(default = True),
    }
)

这仅在 my_rule 中启用 AEG,并且在选择执行平台时,其操作开始使用新逻辑。不兼容的标志会被此属性替换。

如果出现错误,如何停用 AEG?

--incompatible_auto_exec_groups 设置为 false 可完全停用项目中的 AEG(标志的 GitHub 问题),或者通过将 _use_auto_exec_groups 属性设置为 False 来停用特定规则(有关该属性的更多详情)。

迁移到 AEG 期间的错误消息

无法确定工具是来自隐式依赖项还是工具链。请设置工具链参数。如果您未使用工具链,请将其设置为“无”。

  • 在这种情况下,您会获得错误发生前的一系列调用,并且可以清楚地看到哪个确切的操作需要工具链参数。检查该操作所用的工具链,并使用 toolchain 参数进行设置。如果操作中没有针对工具或可执行文件的工具链,请将其设置为 None

为不存在的工具链“[toolchain_type]”声明了操作。

  • 这意味着您已在操作中设置了工具链参数,但未在规则中注册该参数。注册工具链或在操作中设置 None

其他资料

如需了解详情,请参阅设计文档:Automatic exec groups for toolchains