Skip to content

process_wrapper: replace C++ implementation with rust. #1159

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 1 commit into from
Mar 9, 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
49 changes: 35 additions & 14 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -922,20 +922,41 @@ def rustc_compile_action(
dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM")
action_outputs.append(dsym_folder)

ctx.actions.run(
executable = ctx.executable._process_wrapper,
inputs = compile_inputs,
outputs = action_outputs,
env = env,
arguments = args.all,
mnemonic = "Rustc",
progress_message = "Compiling Rust {} {}{} ({} files)".format(
crate_info.type,
ctx.label.name,
formatted_version,
len(crate_info.srcs.to_list()),
),
)
# 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"):
# Run as normal
ctx.actions.run(
executable = ctx.executable._process_wrapper,
inputs = compile_inputs,
outputs = action_outputs,
env = env,
arguments = args.all,
mnemonic = "Rustc",
progress_message = "Compiling Rust {} {}{} ({} files)".format(
crate_info.type,
ctx.label.name,
formatted_version,
len(crate_info.srcs.to_list()),
),
)
else:
# Run without process_wrapper
if build_env_files or build_flags_files or stamp:
fail("build_env_files, build_flags_files, stamp are not supported if use_process_wrapper is False")
ctx.actions.run(
executable = toolchain.rustc,
inputs = compile_inputs,
outputs = action_outputs,
env = env,
arguments = [args.rustc_flags],
mnemonic = "Rustc",
progress_message = "Compiling Rust (without process_wrapper) {} {}{} ({} files)".format(
crate_info.type,
ctx.label.name,
formatted_version,
len(crate_info.srcs.to_list()),
),
)

runfiles = ctx.runfiles(
files = getattr(ctx.files, "data", []),
Expand Down
45 changes: 45 additions & 0 deletions rust/private/transitions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,48 @@ 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("@bazel_tools//tools/allowlists/function_transition_allowlist"),
),
},
)
7 changes: 7 additions & 0 deletions rust/settings/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ bool_flag(
build_setting_default = False,
)

# A flag that enables/disables the use of process_wrapper when invoking rustc.
# This is useful for building process_wrapper itself without causing dependency cycles.
bool_flag(
name = "use_process_wrapper",
build_setting_default = True,
)

bzl_library(
name = "bzl_lib",
srcs = glob(["**/*.bzl"]),
Expand Down
59 changes: 39 additions & 20 deletions util/process_wrapper/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//rust:defs.bzl", "rust_binary", "rust_test")

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

alias(
name = "process_wrapper",
srcs = [
"process_wrapper.cc",
"system.h",
"utils.h",
"utils.cc",
] + select({
"@bazel_tools//src/conditions:host_windows": [
"system_windows.cc",
],
"//conditions:default": [
"system_posix.cc",
],
}),
defines = [] + select({
"@bazel_tools//src/conditions:host_windows": [
"UNICODE",
"_UNICODE",
],
"//conditions:default": [],
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"]),
)

rust_test(
name = "process_wrapper_test",
crate = ":process_wrapper_bin",
)
4 changes: 4 additions & 0 deletions util/process_wrapper/fake.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int main() {
// Noop on purpose.
return 0;
}
Loading