Skip to content

Create internal rust_binary rule instead of using transitions #1187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,33 @@ rust_binary = rule(
"""),
)

def _fake_out_process_wrapper(attrs):
new_attr = dict(attrs.items())
new_attr["_process_wrapper"] = attr.label(
default = None,
executable = True,
allow_single_file = True,
cfg = "exec",
)
return new_attr

# Provides an internal rust_binary to use that we can use to build the process
# wrapper, this breaks the dependency of rust_binary on the process wrapper by
# setting it to None, which the functions in rustc detect and build accordingly.
rust_binary_without_process_wrapper = rule(
implementation = _rust_binary_impl,
provides = _common_providers,
attrs = dict(_fake_out_process_wrapper(_common_attrs).items() + _rust_binary_attrs.items()),
executable = True,
fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = [
str(Label("//rust:toolchain")),
"@bazel_tools//tools/cpp:toolchain_type",
],
incompatible_use_toolchain_transition = True,
)

rust_test = rule(
implementation = _rust_test_impl,
provides = _common_providers,
Expand Down
3 changes: 1 addition & 2 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,7 @@ def rustc_compile_action(
dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM")
action_outputs.append(dsym_folder)

# This uses startswith as on windows the basename will be process_wrapper_fake.exe.
if not ctx.executable._process_wrapper.basename.startswith("process_wrapper_fake"):
if ctx.executable._process_wrapper:
# Run as normal
ctx.actions.run(
executable = ctx.executable._process_wrapper,
Expand Down
45 changes: 0 additions & 45 deletions rust/private/transitions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -64,48 +64,3 @@ with_import_macro_bootstrapping_mode = rule(
),
},
)

def _without_process_wrapper_transition_impl(_settings, _attr):
"""This transition allows rust_* rules to invoke rustc without process_wrapper."""
return {
"//rust/settings:use_process_wrapper": False,
}

without_process_wrapper_transition = transition(
implementation = _without_process_wrapper_transition_impl,
inputs = [],
outputs = ["//rust/settings:use_process_wrapper"],
)

def _without_process_wrapper_impl(ctx):
executable = ctx.executable.target
link_name = ctx.label.name

# Append .exe if on windows
if executable.extension:
link_name = link_name + "." + executable.extension
link = ctx.actions.declare_file(link_name)
ctx.actions.symlink(
output = link,
target_file = executable,
)
return [
DefaultInfo(
executable = link,
),
]

without_process_wrapper = rule(
implementation = _without_process_wrapper_impl,
attrs = {
"target": attr.label(
cfg = without_process_wrapper_transition,
allow_single_file = True,
mandatory = True,
executable = True,
),
"_allowlist_function_transition": attr.label(
default = Label("//tools/allowlists/function_transition_allowlist"),
),
},
)
40 changes: 5 additions & 35 deletions util/process_wrapper/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,45 +1,15 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//rust:defs.bzl", "rust_binary", "rust_test")
load("//rust:defs.bzl", "rust_test")

# buildifier: disable=bzl-visibility
load("//rust/private:transitions.bzl", "without_process_wrapper")
load("//rust/private:rust.bzl", "rust_binary_without_process_wrapper")

alias(
rust_binary_without_process_wrapper(
name = "process_wrapper",
actual = select({
# This will never get used, it's only here to break the circular dependency to allow building process_wrapper
":use_fake_process_wrapper": ":process_wrapper_fake",
"//conditions:default": ":process_wrapper_impl",
}),
visibility = ["//visibility:public"],
)

cc_binary(
name = "process_wrapper_fake",
srcs = ["fake.cc"],
)

config_setting(
name = "use_fake_process_wrapper",
flag_values = {
"//rust/settings:use_process_wrapper": "False",
},
)

# Changing the name of this rule requires a corresponding
# change in //rust/private/rustc.bzl:925
without_process_wrapper(
name = "process_wrapper_impl",
target = ":process_wrapper_bin",
visibility = ["//visibility:public"],
)

rust_binary(
name = "process_wrapper_bin",
srcs = glob(["*.rs"]),
visibility = ["//visibility:public"],
)

rust_test(
name = "process_wrapper_test",
crate = ":process_wrapper_bin",
crate = ":process_wrapper",
)