自動執行群組 (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。

如何啟用 AEGs?

--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,即可停用特定規則 (屬性的詳細資料)。

遷移至 AEGs 時出現錯誤訊息

無法判斷工具是否來自隱含依附元件或工具鍊。請設定工具鍊參數。如果未使用工具鍊,請設為「無」。

  • 在這種情況下,您會取得發生錯誤前的呼叫堆疊,並清楚瞭解哪個確切動作需要工具鍊參數。檢查動作使用的工具鍊,並使用 toolchain 參數設定。如果動作中沒有使用工具或可執行檔的工具鍊,請將其設為 None

為不存在的工具鍊「[toolchain_type]」宣告動作。

  • 也就是說,您已在動作中設定工具鍊參數,但未在規則中註冊該參數。註冊工具鍊,或在動作內設定 None

其他教材

詳情請參閱設計文件: Automatic exec groups for toolchains