Published: 2020-11-05
Bazel started on Linux and Mac OS, and most people use Bazel on these platforms exclusively, but Bazel can execute on Windows as well. However, Windows has enough idiosynchatic differences that writing a single, operating-system agnostic rule that executes on both Windows and Linux/Mac is quite hard. Often it is easiest to have the rule detect whether it is running on Windows and execute different behavior.
A rule can detect whether it is running on Windows is by using
configurable attributes, a.k.a. the select() statement.
This can be made automatic by wrapping your custom rule in a macro that
generates the select() statement for you automatically:
# my_rule.bzl
def _impl(ctx):
if ctx.attr.private_is_windows:
# Do windows specific things
...
my_rule_def = rule(
attrs = {
'private_is_windows': attr.bool(mandatory = True),
...
},
implementation = _impl
)
# All users of the rule should use the below `my_rule` wrapper
# not the rule definition above
def my_rule(name, **kwargs):
my_rule_def(
name = name,
private_is_windows = select({
"@bazel_tools//src/conditions:host_windows": True,
"//conditions:default": False,
}),
**kwargs
)
# BUILD
load('my_rule.bzl', 'my_rule')
my_rule(
name = "my_rule",
...
)