Skip to content

Commit e470d22

Browse files
Switch pipelined compilation from --rustc-quit-on-rmeta to -Zno-codegen
Replace the process wrapper's rmeta-interception approach (kill rustc after metadata emission) with rustc's -Zno-codegen flag, which produces a hollow rlib containing metadata and MIR but no object code. This is the same approach used by Buck2. Key changes: - Metadata action uses `rustc -Zno-codegen --emit=link=<path>` to produce a hollow rlib (_meta.rlib) instead of raw .rmeta files - Remove --rustc-quit-on-rmeta flag, LineOutput::Terminate, and all associated kill logic from the process wrapper - Full action emits only --emit=link (no longer includes metadata) - Set RUSTC_BOOTSTRAP=1 on both metadata and full actions for SVH compatibility (required for the unstable -Zno-codegen flag)
1 parent ee57fdc commit e470d22

File tree

17 files changed

+202
-275
lines changed

17 files changed

+202
-275
lines changed

cargo/Cargo.lock

Lines changed: 64 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/prost/private/prost.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def _compile_rust(
180180
prefix = "lib",
181181
name = crate_name,
182182
lib_hash = output_hash,
183-
extension = ".rmeta",
183+
extension = "_meta.rlib",
184184
)
185185

186186
lib = ctx.actions.declare_file(lib_name)
@@ -193,7 +193,7 @@ def _compile_rust(
193193
prefix = "lib",
194194
name = crate_name,
195195
lib_hash = output_hash,
196-
extension = ".rmeta",
196+
extension = "_meta.rlib",
197197
)
198198
rmeta = ctx.actions.declare_file(rmeta_name)
199199
rustc_rmeta_output = generate_output_diagnostics(ctx, rmeta)

rust/private/clippy.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
177177
out_dir = out_dir,
178178
build_env_files = build_env_files,
179179
build_flags_files = build_flags_files,
180-
emit = ["dep-info", "metadata"],
180+
emit = ["metadata"],
181181
skip_expanding_rustc_env = True,
182182
use_json_output = bool(clippy_diagnostics_file),
183183
error_format = error_format,

rust/private/rust.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def _rust_library_common(ctx, crate_type):
206206
disable_pipelining = getattr(ctx.attr, "disable_pipelining", False),
207207
):
208208
rust_metadata = ctx.actions.declare_file(
209-
paths.replace_extension(rust_lib_name, ".rmeta"),
209+
paths.replace_extension(rust_lib_name, "_meta.rlib"),
210210
sibling = rust_lib,
211211
)
212212
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
@@ -279,7 +279,7 @@ def _rust_binary_impl(ctx):
279279
rustc_rmeta_output = None
280280
if can_build_metadata(toolchain, ctx, ctx.attr.crate_type):
281281
rust_metadata = ctx.actions.declare_file(
282-
paths.replace_extension("lib" + crate_name, ".rmeta"),
282+
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
283283
sibling = output,
284284
)
285285
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
@@ -381,7 +381,7 @@ def _rust_test_impl(ctx):
381381
rustc_rmeta_output = None
382382
if can_build_metadata(toolchain, ctx, crate_type):
383383
rust_metadata = ctx.actions.declare_file(
384-
paths.replace_extension("lib" + crate_name, ".rmeta"),
384+
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
385385
sibling = output,
386386
)
387387
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)
@@ -451,7 +451,7 @@ def _rust_test_impl(ctx):
451451
rustc_rmeta_output = None
452452
if can_build_metadata(toolchain, ctx, crate_type):
453453
rust_metadata = ctx.actions.declare_file(
454-
paths.replace_extension("lib" + crate_name, ".rmeta"),
454+
paths.replace_extension("lib" + crate_name, "_meta.rlib"),
455455
sibling = output,
456456
)
457457
rustc_rmeta_output = generate_output_diagnostics(ctx, rust_metadata)

rust/private/rustc.bzl

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ def construct_arguments(
901901
out_dir,
902902
build_env_files,
903903
build_flags_files,
904-
emit = ["dep-info", "link"],
904+
emit = ["link"],
905905
force_all_deps_direct = False,
906906
add_flags_for_binary = False,
907907
include_link_flags = True,
@@ -1045,8 +1045,11 @@ def construct_arguments(
10451045
error_format = "json"
10461046

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

10801083
emit_without_paths = []
10811084
for kind in emit:
1082-
if kind == "link" and crate_info.type == "bin" and crate_info.output != None:
1085+
if kind == "link" and build_metadata and crate_info.metadata != None:
1086+
# Redirect hollow rlib output to the declared metadata file path,
1087+
# since -Zno-codegen --emit=link would otherwise write lib<name>.rlib
1088+
# which collides with the full action's output.
1089+
rustc_flags.add(crate_info.metadata, format = "--emit=link=%s")
1090+
elif kind == "link" and crate_info.type == "bin" and crate_info.output != None:
10831091
rustc_flags.add(crate_info.output, format = "--emit=link=%s")
10841092
else:
10851093
emit_without_paths.append(kind)
@@ -1377,17 +1385,12 @@ def rustc_compile_action(
13771385
experimental_use_cc_common_link = experimental_use_cc_common_link,
13781386
)
13791387

1388+
compile_inputs_metadata = compile_inputs
1389+
13801390
# The types of rustc outputs to emit.
1381-
# If we build metadata, we need to keep the command line of the two invocations
1382-
# (rlib and rmeta) as similar as possible, otherwise rustc rejects the rmeta as
1383-
# a candidate.
1384-
# Because of that we need to add emit=metadata to both the rlib and rmeta invocation.
1385-
#
13861391
# When cc_common linking is enabled, emit a `.o` file, which is later
13871392
# passed to the cc_common.link action.
1388-
emit = ["dep-info", "link"]
1389-
if build_metadata:
1390-
emit.append("metadata")
1393+
emit = ["link"]
13911394
if experimental_use_cc_common_link:
13921395
emit = ["obj"]
13931396

@@ -1435,7 +1438,7 @@ def rustc_compile_action(
14351438
toolchain = toolchain,
14361439
tool_path = toolchain.rustc.path,
14371440
cc_toolchain = cc_toolchain,
1438-
emit = emit,
1441+
emit = ["link"],
14391442
feature_configuration = feature_configuration,
14401443
crate_info = crate_info,
14411444
dep_info = dep_info,
@@ -1458,6 +1461,12 @@ def rustc_compile_action(
14581461
# this is the final list of env vars
14591462
env.update(env_from_args)
14601463

1464+
if build_metadata:
1465+
# RUSTC_BOOTSTRAP=1 is required for -Zno-codegen on stable rustc, and must
1466+
# be set on both the metadata and full actions for SVH compatibility (since
1467+
# RUSTC_BOOTSTRAP affects the crate hash).
1468+
env["RUSTC_BOOTSTRAP"] = "1"
1469+
14611470
if hasattr(attr, "version") and attr.version != "0.0.0":
14621471
formatted_version = " v{}".format(attr.version)
14631472
else:
@@ -1529,7 +1538,7 @@ def rustc_compile_action(
15291538
if args_metadata:
15301539
ctx.actions.run(
15311540
executable = ctx.executable._process_wrapper,
1532-
inputs = compile_inputs,
1541+
inputs = compile_inputs_metadata,
15331542
outputs = [build_metadata] + [x for x in [rustc_rmeta_output] if x],
15341543
env = env,
15351544
arguments = args_metadata.all,

rust/private/unpretty.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def _rust_unpretty_aspect_impl(target, ctx):
202202
out_dir = out_dir,
203203
build_env_files = build_env_files,
204204
build_flags_files = build_flags_files,
205-
emit = ["dep-info", "metadata"],
205+
emit = ["metadata"],
206206
skip_expanding_rustc_env = True,
207207
)
208208

rust/settings/settings.bzl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,15 @@ def use_real_import_macro():
112112
)
113113

114114
def pipelined_compilation():
115-
"""When set, this flag causes rustc to emit `*.rmeta` files and use them for `rlib -> rlib` dependencies.
115+
"""When set, this flag enables pipelined compilation for `rlib -> rlib` dependencies.
116116
117-
While this involves one extra (short) rustc invocation to build the rmeta file,
118-
it allows library dependencies to be unlocked much sooner, increasing parallelism during compilation.
117+
For each library target, a second RustcMetadata action is created that runs rustc with
118+
`-Zno-codegen --emit=link` to produce a hollow rlib (metadata & MIR, no object code).
119+
Downstream library compilations can start as soon as this hollow rlib is available,
120+
increasing parallelism during compilation.
121+
122+
Requires RUSTC_BOOTSTRAP=1, which is set automatically on both the metadata and full
123+
actions for pipelined targets.
119124
"""
120125
bool_flag(
121126
name = "pipelined_compilation",

test/process_wrapper/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ rust_binary(
157157
)
158158

159159
rust_test(
160-
name = "rustc_quit_on_rmeta",
161-
srcs = ["rustc_quit_on_rmeta.rs"],
160+
name = "rustc_output_format",
161+
srcs = ["rustc_output_format.rs"],
162162
data = [
163163
":fake_rustc",
164164
"//util/process_wrapper",

0 commit comments

Comments
 (0)