如何将规则限制为 C++ 工具链的子集?

How to limit rule to a subset of cpp toolchains?

我有这样的规则

do_action = rule (
    implementation = _impl,
    attrs = {
        ...
        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
    },
    fragments = ["cpp"],
    toolchains = [
        "@bazel_tools//tools/cpp:toolchain_type",
        ],
)

我为自定义 cpu 定义自定义 cc_toolchain:

toolchain(
    name = "cc-toolchain-%{toolchain_name}",
    toolchain = ":cc-compiler-%{toolchain_name}",
    # can be run on this platform
    target_compatible_with = [
        "@platforms//os:windows",
        "@platforms//cpu:x86_64",
    ],
    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

cc_toolchain_suite(
    name = "toolchain",
    toolchains = {
        "%{cpu}": ":cc-compiler-%{toolchain_name}",
    },
)

我在需要时使用 --crostool_top 到 select 这个工具链。

我希望仅当 --crostool_top 与我的自定义工具链之一匹配时才允许调用我的自定义规则。如何做到这一点?

添加一个新的constraint_setting with a constraint_value,只有你的工具链是target_compatible_with,然后让所有使用你的规则的目标target_compatible_with它。

BUILD 文件中的类似内容:

constraint_setting(name = "is_my_toolchain")

constraint_value(
  name = "yes_my_toolchain",
  constraint_setting = ":is_my_toolchain",
)

然后在所有工具链上将 yes_my_toolchain 添加到 target_compatible_with

在每次使用规则时强制使用它的最简单方法是使用 macro。将实际规则重命名为 _do_action(因此它是私有的,不能直接从任何 BUILD 文件加载)并添加:

def do_action(target_compatible_with = [], **kwargs):
  _do_action(
    target_compatible_with = target_compatible_with + [
      "//your_package:yes_my_toolchain",
    ],
    **kwargs
  )