xref: /aosp_15_r20/external/bazelbuild-rules_rust/examples/nix_cross_compiling/bazel/transitions.bzl (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1"""
2https://github.com/aspect-build/bazel-lib/blob/main/lib/transitions.bzl
3
4Rules for working with transitions.
5"""
6
7load("@bazel_skylib//lib:paths.bzl", "paths")
8
9def _transition_platform_impl(_, attr):
10    return {"//command_line_option:platforms": str(attr.target_platform)}
11
12# Transition from any input configuration to one that includes the
13# --platforms command-line flag.
14_transition_platform = transition(
15    implementation = _transition_platform_impl,
16    inputs = [],
17    outputs = ["//command_line_option:platforms"],
18)
19
20def _platform_transition_binary_impl(ctx):
21    # We need to forward the DefaultInfo provider from the underlying rule.
22    # Unfortunately, we can't do this directly, because Bazel requires that the executable to run
23    # is actually generated by this rule, so we need to symlink to it, and generate a synthetic
24    # forwarding DefaultInfo.
25
26    result = []
27    binary = ctx.attr.binary[0]
28
29    default_info = binary[DefaultInfo]
30    files = default_info.files
31    new_executable = None
32    original_executable = default_info.files_to_run.executable
33    runfiles = default_info.default_runfiles
34
35    if not original_executable:
36        fail("Cannot transition a 'binary' that is not executable")
37
38    new_executable_name = original_executable.basename
39
40    # In order for the symlink to have the same basename as the original
41    # executable (important in the case of proto plugins), put it in a
42    # subdirectory named after the label to prevent collisions.
43    new_executable = ctx.actions.declare_file(paths.join(ctx.label.name, new_executable_name))
44    ctx.actions.symlink(
45        output = new_executable,
46        target_file = original_executable,
47        is_executable = True,
48    )
49    files = depset(direct = [new_executable], transitive = [files])
50    runfiles = runfiles.merge(ctx.runfiles([new_executable]))
51
52    result.append(
53        DefaultInfo(
54            files = files,
55            runfiles = runfiles,
56            executable = new_executable,
57        ),
58    )
59
60    return result
61
62platform_transition_binary = rule(
63    doc = "Transitions the binary to use the provided platform.",
64    implementation = _platform_transition_binary_impl,
65    attrs = {
66        "binary": attr.label(
67            doc = "The target to transition.",
68            allow_files = True,
69            cfg = _transition_platform,
70            mandatory = True,
71        ),
72        "target_platform": attr.label(
73            doc = "The target platform to transition the binary.",
74            mandatory = True,
75        ),
76        "_allowlist_function_transition": attr.label(
77            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
78        ),
79    },
80    executable = True,
81)
82