根据 config_setting 创建不同的规则

Creating different rules according to a config_setting

简介

我正在使用自定义构建过程为跨平台 API 实施构建系统。对于每个平台,我都有一个构建目标的规则,例如:

build_for_linux = rule(...)
build_for_windows = rule(...)
build_for_mac = rule(...)

输出不是常规的可执行文件,每个规则都有一组完全不同的操作要执行。因此,将它们全部组合成一个通用规则是没有意义的(只是为了比较,你永远不会在同一个规则中组合 win32's exe and an androids' apk 的实际构建)。

问题

我需要让用户决定他们想要输出的平台。换句话说,我需要找到一种方法来根据输入调用这些函数中的每一个。

当前的(坏的)解决方案

到目前为止,我有一个 config.bzl 文件,其中包含要构建的平台,然后我采用该值并相应地调用了正确的规则:

config.bzl:

platform_to_build_to = 'Linux' 

platform_build.bzl:

platform_rules_dict = {
    'Linux': build_for_linux,
}

def redirect_to_platform_rule(**args):
   build_for_x = platform_rules_dict[platform_to_build_to]
   build_for_x (**args)

问题是用户需要编辑我的私人(例如由我创建).bzl 文件以定义 her/his 平台,这使它成为一个糟糕且不直观的解决方案。

问题

config_setting seems to be a good solution. The problem is that you can only use select 当您知道要调用哪个规则时。这不是这里的情况。

抱歉这个问题太长了,我想通过回答所有 reader 个问题来节省您一些时间。

你是对的,select 用于属性而不是规则。您可以使用别名规则并在其 "actual" 参数上应用 select 来获得您想要的行为。

例如,以下宏创建了一个别名规则,该规则指向 Mac 上的 py_binary 但所有其他平台上的 sh_binary

def sh_or_py_binary(name, **kwargs):
  native.sh_binary(
      name = name + "_sh",
      **kwargs
  )
  native.py_binary(
      name = name + "_py",
      **kwargs
  )
  native.alias(
      name = name,
      actual = select({
          "@bazel_tools//src:darwin": name + "_py",
          "//conditions:default": name + "_sh",
      }),
  )

请注意,这种方法过于简单,因为我们使用相同的参数创建了 sh_binary 和 py_binary,因此参数必须对两者通用,否则 Bazel 的加载阶段将失败.