Cross platform 根据配置设置创建不同的规则 介绍

Cross platform 根据配置设置创建不同的规则 介绍,cross-platform,bazel,Cross Platform,Bazel,我正在实现一个带有定制构建过程的跨平台API构建系统。对于每个平台,我都有一个构建目标的规则,例如: build_for_linux = rule(...) build_for_windows = rule(...) build_for_mac = rule(...) 输出不是常规的可执行文件,每个规则都有一组完全不同的操作要执行。因此,将它们全部合并到一个通用规则中是没有意义的(只是为了进行比较,您永远不会将win32的exe和android的apk的实际构建合并到同一个规则中) 问题 我需

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

build_for_linux = rule(...)
build_for_windows = rule(...)
build_for_mac = rule(...)
输出不是常规的可执行文件,每个规则都有一组完全不同的操作要执行。因此,将它们全部合并到一个通用规则中是没有意义的(只是为了进行比较,您永远不会将
win32
exe
和android的
apk
的实际构建合并到同一个规则中)

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

当前(坏的)解决方案 到目前为止,我有一个
config.bzl
文件,其中包含要构建的平台,然后我取这个值并相应地调用了正确的规则:

config.bzl

platform_to_build_to = 'Linux' 
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)
platform\u build.bzl

platform_to_build_to = 'Linux' 
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
以定义她/他的平台,这使其成为一个糟糕且不直观的解决方案

问题 这似乎是一个很好的解决办法。问题是,只有当您知道要调用哪个规则时,才能使用。这里的情况并非如此

  • 是否有一种根据
    config\u设置创建规则的方法
  • 我做得对吗?你还有别的想法吗

很抱歉回答了这么长的问题,我想通过回答所有读者的问题来为您节省一些时间。

您是对的,select用于属性而不是规则。您可以通过使用别名规则并对其“实际”参数应用select来获得所需的行为

例如,以下宏创建一个别名规则,该规则指向Mac上的py_二进制文件,但指向所有其他平台上的sh_二进制文件

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_二进制文件和一个py_二进制文件,因此这两个参数必须是公共的,否则Bazel的加载阶段将失败