執行群組

回報問題 查看來源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

目前狀態

針對某些原生宣告的動作 (例如 CppLink),執行群組可用於 exec_properties 內,設定每個動作和每個目標的執行需求。詳情請參閱「預設執行群組」一節。

背景

規則作者可透過執行群組定義一組動作,每個動作可能都有不同的執行平台。多個執行平台可讓動作以不同方式執行,例如在遠端 (Linux) 工作站編譯 iOS 應用程式,然後在本機 Mac 工作站連結/程式碼簽署。

定義動作群組也有助於減輕動作助記符的使用,因為動作助記符是指定動作的替代方式。助記符不保證是唯一的,且只能參照單一動作。這項功能特別有助於將額外資源分配給特定記憶體和處理密集型動作,例如在 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 函式,該函式會採用單一字串參數,也就是應建構依附元件的 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"}。如您所見,執行群組層級的設定會覆寫目標層級的設定。

使用執行群組設定平台限制

執行群組也與每個規則上的 exec_compatible_withexec_group_compatible_with 屬性整合,讓目標撰寫者指定其他限制,這些限制必須由為目標動作選取的執行平台滿足。

舉例來說,如果規則 my_test 除了預設和 test 執行群組外,還定義了 link 執行群組,則下列屬性用法會在 CPU 數量較多的平台上,於預設執行群組中執行動作;在 Linux 上執行測試動作;在預設執行平台上執行連結動作:

# BUILD
constraint_setting(name = "cpu")
constraint_value(name = "high_cpu", constraint_setting = ":cpu")

platform(
  name = "high_cpu_platform",
  constraint_values = [":high_cpu"],
  exec_properties = {
    "cpu": "256",
  },
)

my_test(
  name = "my_test",
  exec_compatible_with = ["//constraints:high_cpu"],
  exec_group_compatible_with = {
    "test": ["@platforms//os:linux"],
  },
  ...
)

原生規則的執行群組

對於原生規則定義的動作,可使用下列執行群組:

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

執行群組和平台執行屬性

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

舉例來說,假設在 exec 平台上執行測試時需要使用某項資源,但編譯和連結時則不需要,這時可以按照下列方式建立模型:

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直接在目標上定義的優先順序,會高於從執行平台繼承的優先順序。