Skip to content

Commit 95cc7f3

Browse files
committed
Fix issues causing the Rustc process wrapper to be built non-deterministically
1 parent 1557205 commit 95cc7f3

File tree

6 files changed

+118
-3
lines changed

6 files changed

+118
-3
lines changed

rust/private/rust.bzl

+7
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,13 @@ def _common_attrs_for_binary_without_process_wrapper(attrs):
10601060
cfg = "exec",
10611061
)
10621062

1063+
new_attr["_bootstrap_process_wrapper"] = attr.label(
1064+
default = Label("//util/process_wrapper:bootstrap_process_wrapper"),
1065+
executable = True,
1066+
allow_single_file = True,
1067+
cfg = "exec",
1068+
)
1069+
10631070
# fix stamp = 0
10641071
new_attr["stamp"] = attr.int(
10651072
doc = dedent("""\

rust/private/rustc.bzl

+5-3
Original file line numberDiff line numberDiff line change
@@ -1300,16 +1300,16 @@ def rustc_compile_action(
13001300
),
13011301
toolchain = "@rules_rust//rust:toolchain_type",
13021302
)
1303-
else:
1303+
elif hasattr(ctx.executable, "_bootstrap_process_wrapper"):
13041304
# Run without process_wrapper
13051305
if build_env_files or build_flags_files or stamp or build_metadata:
13061306
fail("build_env_files, build_flags_files, stamp, build_metadata are not supported when building without process_wrapper")
13071307
ctx.actions.run(
1308-
executable = toolchain.rustc,
1308+
executable = ctx.executable._bootstrap_process_wrapper,
13091309
inputs = compile_inputs,
13101310
outputs = action_outputs,
13111311
env = env,
1312-
arguments = [args.rustc_flags],
1312+
arguments = [args.rustc_path, args.rustc_flags],
13131313
mnemonic = "Rustc",
13141314
progress_message = "Compiling Rust (without process_wrapper) {} {}{} ({} files)".format(
13151315
crate_info.type,
@@ -1319,6 +1319,8 @@ def rustc_compile_action(
13191319
),
13201320
toolchain = "@rules_rust//rust:toolchain_type",
13211321
)
1322+
else:
1323+
fail("No process wrapper was defined for {}".format(ctx.label))
13221324

13231325
if experimental_use_cc_common_link:
13241326
# Wrap the main `.o` file into a compilation output suitable for

util/process_wrapper/BUILD.bazel

+46
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,45 @@
1+
load("@bazel_skylib//lib:selects.bzl", "selects")
2+
load("@bazel_skylib//rules:native_binary.bzl", "native_binary")
13
load("//rust:defs.bzl", "rust_test")
24

35
# buildifier: disable=bzl-visibility
46
load("//rust/private:rust.bzl", "rust_binary_without_process_wrapper")
57

8+
config_setting(
9+
name = "compilation_mode_opt",
10+
values = {"compilation_mode": "opt"},
11+
)
12+
13+
selects.config_setting_group(
14+
name = "opt_linux",
15+
match_all = [
16+
":compilation_mode_opt",
17+
"@platforms//os:linux",
18+
],
19+
visibility = ["@rules_rust_tinyjson//:__pkg__"],
20+
)
21+
22+
selects.config_setting_group(
23+
name = "opt_macos",
24+
match_all = [
25+
":compilation_mode_opt",
26+
"@platforms//os:macos",
27+
],
28+
visibility = ["@rules_rust_tinyjson//:__pkg__"],
29+
)
30+
631
rust_binary_without_process_wrapper(
732
name = "process_wrapper",
833
srcs = glob(["*.rs"]),
934
edition = "2018",
35+
# To ensure the process wrapper is produced deterministically
36+
# debug info, which is known to sometimes have host specific
37+
# paths embedded in this section, is stripped out.
38+
rustc_flags = select({
39+
":opt_linux": ["-Cstrip=debuginfo"],
40+
":opt_macos": ["-Cstrip=debuginfo"],
41+
"//conditions:default": [],
42+
}),
1043
visibility = ["//visibility:public"],
1144
deps = [
1245
"@rules_rust_tinyjson//:tinyjson",
@@ -18,3 +51,16 @@ rust_test(
1851
crate = ":process_wrapper",
1952
edition = "2018",
2053
)
54+
55+
native_binary(
56+
name = "bootstrap_process_wrapper",
57+
src = select({
58+
"@platforms//os:windows": "process_wrapper.bat",
59+
"//conditions:default": "process_wrapper.sh",
60+
}),
61+
out = select({
62+
"@platforms//os:windows": "process_wrapper.bat",
63+
"//conditions:default": "process_wrapper.sh",
64+
}),
65+
visibility = ["//visibility:public"],
66+
)

util/process_wrapper/BUILD.tinyjson.bazel

+8
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,13 @@ rust_library_without_process_wrapper(
55
name = "tinyjson",
66
srcs = glob(["src/*.rs"]),
77
edition = "2018",
8+
# To ensure the process wrapper is produced deterministically
9+
# debug info, which is known to sometimes have host specific
10+
# paths embedded in this section, is stripped out.
11+
rustc_flags = select({
12+
"@rules_rust//util/process_wrapper:opt_linux": ["-Cstrip=debuginfo"],
13+
"@rules_rust//util/process_wrapper:opt_macos": ["-Cstrip=debuginfo"],
14+
"//conditions:default": [],
15+
}),
816
visibility = ["@rules_rust//util/process_wrapper:__pkg__"],
917
)
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@ECHO OFF
2+
SETLOCAL enabledelayedexpansion
3+
4+
:: The first argument is expected to be `--`, this must be skipped
5+
SET "skip_first_arg=1"
6+
7+
:: Initialize a counter to track arguments
8+
SET "arg_count=1"
9+
10+
:: Pass the arguments to the provided command, modifying the second argument
11+
for %%A in (%*) do (
12+
if !skip_first_arg! equ 1 (
13+
SET "skip_first_arg=0"
14+
) else if !arg_count! equ 2 (
15+
:: Ensure the rustc.exe path is executable by sanitizing any `/` to `\`
16+
SET "arg=%%~A"
17+
SET "arg=!arg:/=\!"
18+
SET "command_args=!command_args! !arg!"
19+
) else (
20+
:: Account for any arguments which contain `${pwd}` (a place holder for the current working directiron)
21+
set "arg=%%~A"
22+
set "arg=!arg:${pwd}=%CD%!"
23+
set "command_args=!command_args! !arg!"
24+
)
25+
SET /a "arg_count+=1"
26+
)
27+
28+
:: append "--remap-path-prefix" with the current working directory
29+
SET "command_args=!command_args! "--remap-path-prefix=%CD%="
30+
31+
:: Execute the provided command with arguments
32+
%command_args%
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# Skip the first argument which is expected to be `--`
6+
shift
7+
8+
args=()
9+
10+
for arg in "$@"; do
11+
# Check if the argument contains "${PWD}" and replace it with the actual value of PWD
12+
if [[ "${arg}" == *'${pwd}'* ]]; then
13+
arg="${arg//\$\{pwd\}/$PWD}"
14+
fi
15+
args+=("${arg}")
16+
done
17+
18+
set -x
19+
20+
exec "${args[@]}"

0 commit comments

Comments
 (0)