Skip to content

Commit

Permalink
Add platform_transition_binary rule
Browse files Browse the repository at this point in the history
  • Loading branch information
kormide committed Nov 22, 2022
1 parent b1ee367 commit a483864
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
21 changes: 21 additions & 0 deletions docs/transitions.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ bzl_library(
bzl_library(
name = "transitions",
srcs = ["transitions.bzl"],
deps = [
"@bazel_skylib//lib:paths",
],
)

bzl_library(
Expand Down
62 changes: 62 additions & 0 deletions lib/transitions.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"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)}

Expand Down Expand Up @@ -42,3 +44,63 @@ platform_transition_filegroup = rule(
},
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]

new_executable = None
files = default_info.files
original_executable = default_info.files_to_run.executable
data_runfiles = default_info.data_runfiles
default_runfiles = default_info.default_runfiles
if original_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])
data_runfiles = data_runfiles.merge(ctx.runfiles([new_executable]))
default_runfiles = default_runfiles.merge(ctx.runfiles([new_executable]))

result.append(
DefaultInfo(
files = files,
data_runfiles = data_runfiles,
default_runfiles = default_runfiles,
executable = new_executable,
),
)

return result

platform_transition_binary = rule(
implementation = _platform_transition_binary_impl,
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",
),
},
executable = True,
doc = "Transitions the binary to use the provided platform.",
)

0 comments on commit a483864

Please sign in to comment.