執行群組

回報問題 查看來源

執行群組允許單一目標中的多個執行平台。每個執行群組都有自己的工具鍊依附元件,並執行自己的工具鍊解析

背景

執行群組可讓規則作者定義動作組合,每個動作的執行平台可能都大不相同。多個執行平台可以允許以不同方式執行動作,例如編譯遠端 (linux) 工作站上的 iOS 應用程式,然後在本機 mac 工作站上連結/程式碼簽署。

能夠定義動作群組,也有助於減少將動作助詞做為指定動作的 Proxy。Mnemonics 未保證是唯一,且只能參照單一動作。這能在將額外資源分配到特定記憶體和處理大量操作 (例如 C++ 建構作業中連結) 時特別有幫助,而無需將額外資源分配給較不費力的工作。

定義執行群組

在規則定義期間,規則作者可以宣告一組執行群組。在每個執行群組中,規則作者可以指定為該執行群組選取執行平台所需的所有項目,包括透過 exec_compatible_with 設下的任何限制,以及透過 toolchain 的工具鍊類型。

# foo.bzl
my_rule = rule(
    _impl,
    exec_groups = {
        “link”: exec_group(
            exec_compatible_with = [ "@platforms//os:linux" ]
            toolchains = ["//foo:toolchain_type"],
        ),
        “test”: exec_group(
            toolchains = ["//foo_tools:toolchain_type"],
        ),
    },
    attrs = {
        "_compiler": attr.label(cfg = config.exec("link"))
    },
)

在上方的程式碼片段中,您可以看到工具依附元件也可以使用 cfg 屬性參數和 config 模組,指定執行群組的轉換。模組會公開 exec 函式,該函式會使用單一字串參數,也就是應建構依附元件的執行群組名稱。

與原生規則一樣,Starlark 測試規則中預設會顯示 test 執行群組。

存取執行群組

在規則實作中,您可以宣告動作應在執行群組的執行平台上執行。方法是使用動作產生方法的 exec_group 參數,特別是 ctx.actions.runctx.actions.run_shell

# foo.bzl
def _impl(ctx):
  ctx.actions.run(
     inputs = [ctx.attr._some_tool, ctx.srcs[0]]
     exec_group = "compile",
     # ...
  )

規則作者也可以存取執行群組的解析工具鍊,類似存取目標已解析工具鍊的方式:

# foo.bzl
def _impl(ctx):
  foo_info = ctx.exec_groups["link"].toolchains["//foo:toolchain_type"].fooinfo
  ctx.actions.run(
     inputs = [foo_info, ctx.srcs[0]]
     exec_group = "link",
     # ...
  )

使用執行群組設定執行屬性

執行群組會與每個規則上的 exec_properties 屬性整合,並允許目標寫入者指定屬性的字串字典,然後傳送至執行機器。舉例來說,如要針對目標設定一些屬性 (例如記憶體) 並為某些動作提供更高的記憶體配置,則應使用執行群組評估索引鍵編寫 exec_properties 項目,例如:

# BUILD
my_rule(
    name = 'my_target',
    exec_properties = {
        'mem': '12g',
        'link.mem': '16g'
    }
    …
)

所有具有 exec_group = "link" 的操作都會看到執行屬性字典為 {"mem": "16g"}。如您所見,執行群組層級設定會覆寫目標層級設定。

原生規則的執行群組

下列執行群組適用於原生規則定義的動作:

  • test:測試執行工具動作。
  • cpp_link:C++ 連結動作。

執行群組與平台執行屬性

您可以為平台目標上的任意執行群組定義 exec_properties (與直接在目標上設定的 exec_properties 不同,其中不明執行群組的屬性會遭到拒絕)。目標會繼承執行平台的 exec_properties,這會影響預設執行群組和任何其他相關的執行群組。

舉例來說,假設執行 C++ 測試需要部分資源可供使用,但不需要編譯和連結資源;您可以用以下方式建立 C++ 測試:

constraint_setting(name = "resource")
constraint_value(name = "has_resource", constraint_setting = ":resource")

platform(
    name = "platform_with_resource",
    constraint_values = [":has_resource"],
    exec_properties = {
        "test.resource": "...",
    },
)

cc_test(
    name = "my_test",
    srcs = ["my_test.cc"],
    exec_compatible_with = [":has_resource"],
)

目標上直接定義的 exec_properties 的優先順序高於從執行平台沿用的目標。