自动执行组会为每种工具链类型选择一个执行平台 。换句话说,一个目标可以有多个执行平台,而无需定义执行组。
快速摘要
自动执行组与工具链密切相关。如果您使用的是工具链,则需要通过添加 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 注册了两种工具链类型。这意味着,Toolchain
Resolution 过去用于查找同时支持这两种工具链类型的执行平台。除非使用
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_group。在所有其他情况下,都无需定义自定义 exec_group。例如:
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 参数进行设置。如果操作中没有为工具或可执行文件使用任何工具链,请将其设置为
None。
为不存在的工具链“[toolchain_type]”声明的操作。
- 这意味着您已在操作中设置了 toolchain 参数,但未在规则中注册该参数。在操作中注册工具链或设置
None。
其他资料
如需了解详情,请参阅设计文档: Automatic exec groups for toolchains。