Skip to content
Open
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
74 changes: 64 additions & 10 deletions cargo/Cargo.lock

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

4 changes: 2 additions & 2 deletions extensions/prost/private/prost.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def _compile_rust(
prefix = "lib",
name = crate_name,
lib_hash = output_hash,
extension = ".rmeta",
extension = "_meta.rlib",
)

lib = ctx.actions.declare_file(lib_name)
Expand All @@ -193,7 +193,7 @@ def _compile_rust(
prefix = "lib",
name = crate_name,
lib_hash = output_hash,
extension = ".rmeta",
extension = "_meta.rlib",
)
rmeta = ctx.actions.declare_file(rmeta_name)
rustc_rmeta_output = generate_output_diagnostics(ctx, rmeta)
Expand Down
2 changes: 1 addition & 1 deletion rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
out_dir = out_dir,
build_env_files = build_env_files,
build_flags_files = build_flags_files,
emit = ["dep-info", "metadata"],
emit = ["metadata"],
skip_expanding_rustc_env = True,
use_json_output = bool(clippy_diagnostics_file),
error_format = error_format,
Expand Down
8 changes: 4 additions & 4 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def _rust_library_common(ctx, crate_type):
disable_pipelining = getattr(ctx.attr, "disable_pipelining", False),
):
rust_metadata = ctx.actions.declare_file(
paths.replace_extension(rust_lib_name, ".rmeta"),
paths.replace_extension(rust_lib_name, "_meta.rlib"),
sibling = rust_lib,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
Expand Down Expand Up @@ -279,7 +279,7 @@ def _rust_binary_impl(ctx):
rustc_rmeta_output = None
if can_build_metadata(toolchain, ctx, ctx.attr.crate_type):
rust_metadata = ctx.actions.declare_file(
paths.replace_extension("lib" + crate_name, ".rmeta"),
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
Expand Down Expand Up @@ -381,7 +381,7 @@ def _rust_test_impl(ctx):
rustc_rmeta_output = None
if can_build_metadata(toolchain, ctx, crate_type):
rust_metadata = ctx.actions.declare_file(
paths.replace_extension("lib" + crate_name, ".rmeta"),
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
Expand Down Expand Up @@ -451,7 +451,7 @@ def _rust_test_impl(ctx):
rustc_rmeta_output = None
if can_build_metadata(toolchain, ctx, crate_type):
rust_metadata = ctx.actions.declare_file(
paths.replace_extension("lib" + crate_name, ".rmeta"),
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
sibling = output,
)
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
Expand Down
37 changes: 23 additions & 14 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ def construct_arguments(
out_dir,
build_env_files,
build_flags_files,
emit = ["dep-info", "link"],
emit = ["link"],
force_all_deps_direct = False,
add_flags_for_binary = False,
include_link_flags = True,
Expand Down Expand Up @@ -1045,8 +1045,11 @@ def construct_arguments(
error_format = "json"

if build_metadata:
# Configure process_wrapper to terminate rustc when metadata are emitted
process_wrapper_flags.add("--rustc-quit-on-rmeta", "true")
# Build a hollow rlib (metadata-full, Buck2 equivalent) using -Zno-codegen.
# This produces an rlib with metadata but no object code, allowing downstream
# crates to start compiling without waiting for codegen.
# RUSTC_BOOTSTRAP=1 must be set in the action env for this unstable flag.
rustc_flags.add("-Zno-codegen")
if crate_info.rustc_rmeta_output:
process_wrapper_flags.add("--output-file", crate_info.rustc_rmeta_output.path)
elif crate_info.rustc_output:
Expand Down Expand Up @@ -1079,7 +1082,12 @@ def construct_arguments(

emit_without_paths = []
for kind in emit:
if kind == "link" and crate_info.type == "bin" and crate_info.output != None:
if kind == "link" and build_metadata and crate_info.metadata != None:
# Redirect hollow rlib output to the declared metadata file path,
# since -Zno-codegen --emit=link would otherwise write lib<name>.rlib
# which collides with the full action's output.
rustc_flags.add(crate_info.metadata, format = "--emit=link=%s")
elif kind == "link" and crate_info.type == "bin" and crate_info.output != None:
rustc_flags.add(crate_info.output, format = "--emit=link=%s")
else:
emit_without_paths.append(kind)
Expand Down Expand Up @@ -1377,17 +1385,12 @@ def rustc_compile_action(
experimental_use_cc_common_link = experimental_use_cc_common_link,
)

compile_inputs_metadata = compile_inputs

# The types of rustc outputs to emit.
# If we build metadata, we need to keep the command line of the two invocations
# (rlib and rmeta) as similar as possible, otherwise rustc rejects the rmeta as
# a candidate.
# Because of that we need to add emit=metadata to both the rlib and rmeta invocation.
#
# When cc_common linking is enabled, emit a `.o` file, which is later
# passed to the cc_common.link action.
emit = ["dep-info", "link"]
if build_metadata:
emit.append("metadata")
emit = ["link"]
if experimental_use_cc_common_link:
emit = ["obj"]

Expand Down Expand Up @@ -1435,7 +1438,7 @@ def rustc_compile_action(
toolchain = toolchain,
tool_path = toolchain.rustc.path,
cc_toolchain = cc_toolchain,
emit = emit,
emit = ["link"],
feature_configuration = feature_configuration,
crate_info = crate_info,
dep_info = dep_info,
Expand All @@ -1458,6 +1461,12 @@ def rustc_compile_action(
# this is the final list of env vars
env.update(env_from_args)

if build_metadata:
# RUSTC_BOOTSTRAP=1 is required for -Zno-codegen on stable rustc, and must
# be set on both the metadata and full actions for SVH compatibility (since
# RUSTC_BOOTSTRAP affects the crate hash).
env["RUSTC_BOOTSTRAP"] = "1"

if hasattr(attr, "version") and attr.version != "0.0.0":
formatted_version = " v{}".format(attr.version)
else:
Expand Down Expand Up @@ -1529,7 +1538,7 @@ def rustc_compile_action(
if args_metadata:
ctx.actions.run(
executable = ctx.executable._process_wrapper,
inputs = compile_inputs,
inputs = compile_inputs_metadata,
outputs = [build_metadata] + [x for x in [rustc_rmeta_output] if x],
env = env,
arguments = args_metadata.all,
Expand Down
2 changes: 1 addition & 1 deletion rust/private/unpretty.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def _rust_unpretty_aspect_impl(target, ctx):
out_dir = out_dir,
build_env_files = build_env_files,
build_flags_files = build_flags_files,
emit = ["dep-info", "metadata"],
emit = ["metadata"],
skip_expanding_rustc_env = True,
)

Expand Down
11 changes: 8 additions & 3 deletions rust/settings/settings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,15 @@ def use_real_import_macro():
)

def pipelined_compilation():
"""When set, this flag causes rustc to emit `*.rmeta` files and use them for `rlib -> rlib` dependencies.
"""When set, this flag enables pipelined compilation for `rlib -> rlib` dependencies.

While this involves one extra (short) rustc invocation to build the rmeta file,
it allows library dependencies to be unlocked much sooner, increasing parallelism during compilation.
For each library target, a second RustcMetadata action is created that runs rustc with
`-Zno-codegen --emit=link` to produce a hollow rlib (metadata & MIR, no object code).
Downstream library compilations can start as soon as this hollow rlib is available,
increasing parallelism during compilation.

Requires RUSTC_BOOTSTRAP=1, which is set automatically on both the metadata and full
actions for pipelined targets.
"""
bool_flag(
name = "pipelined_compilation",
Expand Down
4 changes: 2 additions & 2 deletions test/process_wrapper/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ rust_binary(
)

rust_test(
name = "rustc_quit_on_rmeta",
srcs = ["rustc_quit_on_rmeta.rs"],
name = "rustc_output_format",
srcs = ["rustc_output_format.rs"],
data = [
":fake_rustc",
"//util/process_wrapper",
Expand Down
Loading