blob: ee5947d13c35ce6d19ea9453f35435c72bf11f8a [file] [log] [blame]
# A transition in Bazel is a way to force changes to the way the build is
# evaluated for all dependencies of a given rule.
#
# Imagine the following simple dependency graph:
#
# ->: depends on
# a -> b -> c
#
# Normally, if you set `defines` on a, they couldn't apply to b or c because
# they are dependencies of a. There's no way for b or c to know about a's
# settings, because they don't even know a exists!
#
# We can fix this via a transition! If we put a transition in front of `a`
# that sets --copts=-DFOO=42, we're telling Bazel to build a and all of its
# dependencies under that configuration.
#
# Note: Flags must be referenced as e.g. `//command_line_option:copt` in
# transitions.
#
# `declare_transition()` eliminates the frustrating amount of boilerplate. All
# you need to do is provide a set of attrs, and then a `flag_overrides`
# dictionary that tells `declare_transition()` which attrs to pull flag values
# from. The common `src` attr tells the transition which build rule to apply
# the transition to.
def declare_transtion(attrs, flag_overrides, executable = True):
def _flag_override_impl(settings, attrs):
return {
key: str(getattr(attrs, value))
for key, value in flag_overrides.items()
}
_transition = transition(
implementation = _flag_override_impl,
inputs = [],
outputs = flag_overrides.keys(),
)
def _symlink_artifact_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name)
if executable:
ctx.actions.symlink(output = out, target_file = ctx.executable.src)
return [DefaultInfo(files = depset([out]), executable = out)]
ctx.actions.symlink(
output = out,
target_file = ctx.attr.src[0][DefaultInfo].files.to_list()[0],
)
return [DefaultInfo(files = depset([out]))]
return rule(
implementation = _symlink_artifact_impl,
executable = executable,
attrs = {
"src": attr.label(
cfg = _transition,
executable = executable,
mandatory = True,
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
} | attrs,
)
rp2040_bootloader_binary = declare_transtion(
attrs = {
"_malloc": attr.label(default = "//src/rp2_common/boot_stage2:no_malloc"),
"_bootloader_platform": attr.label(default = "//bazel/platform:rp2040_bootloader"),
},
flag_overrides = {
"//command_line_option:platforms": "_bootloader_platform",
# We don't want --custom_malloc to ever apply to the bootloader, so
# always explicitly override it here.
"//command_line_option:custom_malloc": "_malloc",
},
)