| "Rules for working with transitions." |
| |
| load("@bazel_skylib//lib:paths.bzl", "paths") |
| |
| def _transition_platform_impl(_, attr): |
| return {"//command_line_option:platforms": str(attr.target_platform)} |
| |
| # Transition from any input configuration to one that includes the |
| # --platforms command-line flag. |
| _transition_platform = transition( |
| implementation = _transition_platform_impl, |
| inputs = [], |
| outputs = ["//command_line_option:platforms"], |
| ) |
| |
| def _platform_transition_filegroup_impl(ctx): |
| files = [] |
| runfiles = ctx.runfiles() |
| for src in ctx.attr.srcs: |
| files.append(src[DefaultInfo].files) |
| |
| runfiles = runfiles.merge_all([src[DefaultInfo].default_runfiles for src in ctx.attr.srcs]) |
| return [DefaultInfo( |
| files = depset(transitive = files), |
| runfiles = runfiles, |
| )] |
| |
| platform_transition_filegroup = rule( |
| _platform_transition_filegroup_impl, |
| attrs = { |
| # Required to Opt-in to the transitions feature. |
| "_allowlist_function_transition": attr.label( |
| default = "@bazel_tools//tools/allowlists/function_transition_allowlist", |
| ), |
| "target_platform": attr.label( |
| doc = "The target platform to transition the srcs.", |
| mandatory = True, |
| ), |
| "srcs": attr.label_list( |
| allow_empty = False, |
| cfg = _transition_platform, |
| doc = "The input to be transitioned to the target platform.", |
| ), |
| }, |
| doc = "Transitions the srcs to use the provided platform. The filegroup will contain artifacts for the target platform.", |
| ) |
| |
| def _platform_transition_binary_impl(ctx): |
| # We need to forward the DefaultInfo provider from the underlying rule. |
| # Unfortunately, we can't do this directly, because Bazel requires that the executable to run |
| # is actually generated by this rule, so we need to symlink to it, and generate a synthetic |
| # forwarding DefaultInfo. |
| |
| result = [] |
| binary = ctx.attr.binary[0] |
| |
| default_info = binary[DefaultInfo] |
| files = default_info.files |
| new_executable = None |
| original_executable = default_info.files_to_run.executable |
| runfiles = default_info.default_runfiles |
| |
| if not original_executable: |
| fail("Cannot transition a 'binary' that is not executable") |
| |
| new_executable_name = ctx.attr.basename if ctx.attr.basename else original_executable.basename |
| |
| # In order for the symlink to have the same basename as the original |
| # executable (important in the case of proto plugins), put it in a |
| # subdirectory named after the label to prevent collisions. |
| new_executable = ctx.actions.declare_file(paths.join(ctx.label.name, new_executable_name)) |
| ctx.actions.symlink( |
| output = new_executable, |
| target_file = original_executable, |
| is_executable = True, |
| ) |
| files = depset(direct = [new_executable], transitive = [files]) |
| runfiles = runfiles.merge(ctx.runfiles([new_executable])) |
| |
| result.append( |
| DefaultInfo( |
| files = files, |
| runfiles = runfiles, |
| executable = new_executable, |
| ), |
| ) |
| |
| return result |
| |
| _platform_transition_attrs = { |
| "basename": attr.string(), |
| "binary": attr.label(allow_files = True, cfg = _transition_platform), |
| "target_platform": attr.label( |
| doc = "The target platform to transition the binary.", |
| mandatory = True, |
| ), |
| "_allowlist_function_transition": attr.label( |
| default = "@bazel_tools//tools/allowlists/function_transition_allowlist", |
| ), |
| } |
| |
| platform_transition_binary = rule( |
| implementation = _platform_transition_binary_impl, |
| attrs = _platform_transition_attrs, |
| executable = True, |
| doc = "Transitions the binary to use the provided platform.", |
| ) |
| |
| platform_transition_test = rule( |
| implementation = _platform_transition_binary_impl, |
| attrs = _platform_transition_attrs, |
| test = True, |
| doc = "Transitions the test to use the provided platform.", |
| ) |