| load("@bazel_skylib//lib:paths.bzl", "paths") |
| |
| def _build_with_tag_transition_impl(settings, attr): |
| """ |
| Transition that enables pure, static build of Go binaries. |
| """ |
| tags = settings["@io_bazel_rules_go//go/config:tags"] |
| |
| return { |
| "@io_bazel_rules_go//go/config:tags": tags + attr.gotags, |
| } |
| |
| build_with_tag_transition = transition( |
| implementation = _build_with_tag_transition_impl, |
| inputs = [ |
| "@io_bazel_rules_go//go/config:tags", |
| ], |
| outputs = [ |
| "@io_bazel_rules_go//go/config:tags", |
| ], |
| ) |
| |
| def _go_binary_with_tag_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 |
| original_executable = default_info.files_to_run.executable |
| |
| if not original_executable: |
| fail("Cannot transition a 'binary' that is not executable") |
| |
| # 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, original_executable.basename)) |
| ctx.actions.symlink( |
| output = new_executable, |
| target_file = original_executable, |
| is_executable = True, |
| ) |
| |
| result.append( |
| DefaultInfo( |
| files = depset(direct = [new_executable]), |
| executable = new_executable, |
| ), |
| ) |
| |
| return result |
| |
| go_binary_with_tag = rule( |
| implementation = _go_binary_with_tag_impl, |
| attrs = { |
| "binary": attr.label( |
| mandatory = True, |
| cfg = build_with_tag_transition, |
| ), |
| "gotags": attr.string_list(), |
| }, |
| ) |