我正在使用自定义构建过程为跨平台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
创建规则?对于这个冗长的问题感到抱歉,我想通过回答所有读者问题来节省一些时间。
答案 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的加载阶段将失败。