根据config_setting

时间:2017-10-08 21:24:58

标签: cross-platform bazel

简介

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

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

输出不是常规可执行文件,每个规则都有一组完全不同的操作要执行。因此,将它们全部组合成通用规则是没有意义的(仅用于比较,您永远不会将win32的{​​{1}}和机器人exe的实际构建组合在一起。同样的规则)。

问题

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

当前(坏)解决方案

到目前为止,我有一个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) 文件,以便定义她/他的平台,这使得它成为一个糟糕且不直观的解决方案。

问题

config_setting似乎是一个很好的解决方案。问题是,当您知道要拨打的规则时,您只能使用select。这里不是这种情况。

  • 有哪种方法可以根据.bzl创建规则?
  • 我做得对吗?你有另一个想法吗?

对于这个冗长的问题感到抱歉,我想通过回答所有读者问题来节省一些时间。

1 个答案:

答案 0 :(得分:4)

您正确,选择用于属性而不是规则。您可以获得类似于您想要使用别名规则的行为,并在其"实际"上应用选择。参数。

例如,以下宏创建一个别名规则,该规则指向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的加载阶段将失败。