Skip to content

Commit a2c755c

Browse files
committed
Add support for experimental_output_paths
1 parent c70eb85 commit a2c755c

12 files changed

Lines changed: 770 additions & 328 deletions

File tree

.bazelci/presubmit.yml

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -377,43 +377,104 @@ tasks:
377377
platform: ubuntu2204
378378
run_targets:
379379
- "//test/rustfmt:rustfmt_failure_tester"
380-
rust_analyzer_tests_linux:
381-
name: Rust-Analyzer Linux Tests
380+
ide_integration_tests_linux:
381+
name: IDE VSCode Tests
382382
platform: ubuntu2204
383383
run_targets:
384+
- "//tools/vscode:gen_launch_json"
385+
- "//test/vscode:vscode_test"
384386
- "//tools/rust_analyzer:gen_rust_project"
385387
- "//tools/rust_analyzer:discover_bazel_rust_project"
386388
- "//test/rust_analyzer:rust_analyzer_test"
387-
rust_analyzer_tests_macos:
388-
name: Rust-Analyzer Macos Tests
389+
ide_integration_tests_macos:
390+
name: IDE VSCode Tests
389391
platform: macos_arm64
390392
run_targets:
393+
- "//tools/vscode:gen_launch_json"
394+
- "//test/vscode:vscode_test"
391395
- "//tools/rust_analyzer:gen_rust_project"
392396
- "//tools/rust_analyzer:discover_bazel_rust_project"
393397
- "//test/rust_analyzer:rust_analyzer_test"
394-
rust_analyzer_tests_windows:
395-
name: Rust-Analyzer Windows Tests
398+
ide_integration_tests_windows:
399+
name: IDE VSCode Tests
396400
platform: windows
397401
run_targets:
402+
- "//tools/vscode:gen_launch_json"
398403
- "//tools/rust_analyzer:gen_rust_project"
399404
- "//tools/rust_analyzer:discover_bazel_rust_project"
400-
ide_integration_vscode_tests_linux:
401-
name: IDE VSCode Tests
405+
- "//test/rust_analyzer:rust_analyzer_test"
406+
407+
path_mapping_ubuntu2204:
408+
name: Path Mapping Linux
402409
platform: ubuntu2204
403-
run_targets:
404-
- "//tools/vscode:gen_launch_json"
405-
- "//test/vscode:vscode_test"
406-
ide_integration_vscode_tests_macos:
407-
name: IDE VSCode Tests
410+
build_flags:
411+
- --config=clippy
412+
- --config=rustfmt
413+
- --experimental_output_paths=strip
414+
- --//rust/settings:experimental_path_mapping=True
415+
test_flags:
416+
- --config=clippy
417+
- --config=rustfmt
418+
- --experimental_output_paths=strip
419+
- --//rust/settings:experimental_path_mapping=True
420+
build_targets: *default_linux_targets
421+
test_targets: *default_linux_targets
422+
coverage_targets: *default_linux_targets
423+
post_shell_commands: *coverage_validation_post_shell_commands
424+
path_mapping_rbe_ubuntu2204:
425+
name: Path Mapping RBE
426+
platform: rbe_ubuntu2204
427+
shell_commands:
428+
- sed -i 's/^# load("@bazel_ci_rules/load("@bazel_ci_rules/' WORKSPACE.bazel
429+
- sed -i 's/^# rbe_preconfig/rbe_preconfig/' WORKSPACE.bazel
430+
build_flags:
431+
- --config=clippy
432+
- --config=rustfmt
433+
- --experimental_output_paths=strip
434+
- --//rust/settings:experimental_path_mapping=True
435+
test_flags:
436+
- --config=clippy
437+
- --config=rustfmt
438+
- --experimental_output_paths=strip
439+
- --//rust/settings:experimental_path_mapping=True
440+
build_targets: *default_rbe_targets
441+
test_targets: *default_rbe_targets
442+
coverage_targets: *default_rbe_targets
443+
coverage_flags: *rbe_coverage_flags
444+
post_shell_commands: *coverage_validation_post_shell_commands
445+
path_mapping_macos:
446+
name: Path Mapping MacOS
408447
platform: macos_arm64
409-
run_targets:
410-
- "//tools/vscode:gen_launch_json"
411-
- "//test/vscode:vscode_test"
412-
ide_integration_vscode_tests_windows:
413-
name: IDE VSCode Tests
448+
build_flags:
449+
- --config=clippy
450+
- --config=rustfmt
451+
- --experimental_output_paths=strip
452+
- --//rust/settings:experimental_path_mapping=True
453+
test_flags:
454+
- --config=clippy
455+
- --config=rustfmt
456+
- --experimental_output_paths=strip
457+
- --//rust/settings:experimental_path_mapping=True
458+
build_targets: *default_macos_targets
459+
test_targets: *default_macos_targets
460+
coverage_targets: *default_macos_targets
461+
post_shell_commands: *coverage_validation_post_shell_commands
462+
path_mapping_windows:
463+
name: Path Mapping Windows
414464
platform: windows
415-
run_targets:
416-
- "//tools/vscode:gen_launch_json"
465+
build_flags:
466+
- --config=clippy
467+
- --config=rustfmt
468+
- --experimental_output_paths=strip
469+
- --//rust/settings:experimental_path_mapping=True
470+
test_flags:
471+
- --config=clippy
472+
- --config=rustfmt
473+
- --experimental_output_paths=strip
474+
- --//rust/settings:experimental_path_mapping=True
475+
build_targets: *default_windows_targets
476+
test_targets: *default_windows_targets
477+
417478
###########################################################################
418479
# C R A T E U N I V E R S E I N T E G R A T I O N T E S T S
419480
###########################################################################

cargo/private/cargo_build_script_runner/bin.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn run_buildrs() -> Result<(), String> {
5353

5454
cargo_manifest_maker.create_runfiles_dir().unwrap();
5555

56-
let out_dir_abs = exec_root.join(out_dir);
56+
let out_dir_abs = exec_root.join(&out_dir);
5757
// For some reason Google's RBE does not create the output directory, force create it.
5858
create_dir_all(&out_dir_abs)
5959
.unwrap_or_else(|_| panic!("Failed to make output directory: {:?}", out_dir_abs));
@@ -176,7 +176,7 @@ fn run_buildrs() -> Result<(), String> {
176176

177177
write(
178178
&env_file,
179-
BuildScriptOutput::outputs_to_env(&buildrs_outputs, &exec_root.to_string_lossy())
179+
BuildScriptOutput::outputs_to_env(&buildrs_outputs, &exec_root.to_string_lossy(), &out_dir)
180180
.as_bytes(),
181181
)
182182
.unwrap_or_else(|e| panic!("Unable to write file {:?}: {:#?}", env_file, e));
@@ -186,6 +186,7 @@ fn run_buildrs() -> Result<(), String> {
186186
&buildrs_outputs,
187187
&crate_links,
188188
&exec_root.to_string_lossy(),
189+
&out_dir,
189190
)
190191
.as_bytes(),
191192
)
@@ -204,7 +205,11 @@ fn run_buildrs() -> Result<(), String> {
204205
compile_flags,
205206
link_flags,
206207
link_search_paths,
207-
} = BuildScriptOutput::outputs_to_flags(&buildrs_outputs, &exec_root.to_string_lossy());
208+
} = BuildScriptOutput::outputs_to_flags(
209+
&buildrs_outputs,
210+
&exec_root.to_string_lossy(),
211+
&out_dir,
212+
);
208213

209214
write(&compile_flags_file, compile_flags.as_bytes())
210215
.unwrap_or_else(|e| panic!("Unable to write file {:?}: {:#?}", compile_flags_file, e));

cargo/private/cargo_build_script_runner/lib.rs

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,17 @@ impl BuildScriptOutput {
158158
}
159159

160160
/// Convert a vector of [BuildScriptOutput] into a list of environment variables.
161-
pub fn outputs_to_env(outputs: &[BuildScriptOutput], exec_root: &str) -> String {
161+
pub fn outputs_to_env(
162+
outputs: &[BuildScriptOutput],
163+
exec_root: &str,
164+
out_dir: &str,
165+
) -> String {
162166
outputs
163167
.iter()
164168
.filter_map(|x| {
165169
if let BuildScriptOutput::Env(env) = x {
166-
Some(Self::escape_for_serializing(Self::redact_exec_root(
167-
env, exec_root,
170+
Some(Self::escape_for_serializing(Self::redact_paths(
171+
env, exec_root, out_dir,
168172
)))
169173
} else {
170174
None
@@ -179,6 +183,7 @@ impl BuildScriptOutput {
179183
outputs: &[BuildScriptOutput],
180184
crate_links: &str,
181185
exec_root: &str,
186+
out_dir: &str,
182187
) -> String {
183188
let prefix = format!("DEP_{}_", crate_links.replace('-', "_").to_uppercase());
184189
outputs
@@ -188,7 +193,7 @@ impl BuildScriptOutput {
188193
Some(format!(
189194
"{}{}",
190195
prefix,
191-
Self::escape_for_serializing(Self::redact_exec_root(env, exec_root))
196+
Self::escape_for_serializing(Self::redact_paths(env, exec_root, out_dir))
192197
))
193198
} else {
194199
None
@@ -199,7 +204,11 @@ impl BuildScriptOutput {
199204
}
200205

201206
/// Convert a vector of [BuildScriptOutput] into a flagfile.
202-
pub fn outputs_to_flags(outputs: &[BuildScriptOutput], exec_root: &str) -> CompileAndLinkFlags {
207+
pub fn outputs_to_flags(
208+
outputs: &[BuildScriptOutput],
209+
exec_root: &str,
210+
out_dir: &str,
211+
) -> CompileAndLinkFlags {
203212
let mut compile_flags = Vec::new();
204213
let mut link_flags = Vec::new();
205214
let mut link_search_paths = Vec::new();
@@ -217,13 +226,34 @@ impl BuildScriptOutput {
217226

218227
CompileAndLinkFlags {
219228
compile_flags: compile_flags.join("\n"),
220-
link_flags: Self::redact_exec_root(&link_flags.join("\n"), exec_root),
221-
link_search_paths: Self::redact_exec_root(&link_search_paths.join("\n"), exec_root),
229+
link_flags: Self::redact_paths(&link_flags.join("\n"), exec_root, out_dir),
230+
link_search_paths: Self::redact_paths(&link_search_paths.join("\n"), exec_root, out_dir),
222231
}
223232
}
224233

225-
fn redact_exec_root(value: &str, exec_root: &str) -> String {
226-
value.replace(exec_root, "${pwd}")
234+
/// Replace the absolute exec-root with `${pwd}` and the relative
235+
/// configuration-dependent `out_dir` path (e.g.
236+
/// `bazel-out/<config>/bin/.../_bs.out_dir`) with `${out_dir}`.
237+
///
238+
/// Both tokens are substituted by `process_wrapper` at action
239+
/// execution time. Routing the `out_dir` portion through
240+
/// `${out_dir}` lets Bazel's path mapping
241+
/// (`--experimental_output_paths=strip`) rewrite it: the consumer
242+
/// `Rustc` action passes the directory to `process_wrapper` via
243+
/// `--out-dir <File>` from a `File`-typed `Args` entry, so the value
244+
/// is the mapped `bazel-out/cfg/bin/...` path under path mapping and
245+
/// the un-mapped path otherwise. Without this redaction,
246+
/// build-script-emitted env vars (e.g. `cargo::rustc-env=FOO=$OUT_DIR/bar`)
247+
/// would carry the un-mapped path through the `_bs.env` file and
248+
/// cause the path-mapped Rustc action to look in the wrong location
249+
/// at runtime.
250+
fn redact_paths(value: &str, exec_root: &str, out_dir: &str) -> String {
251+
let with_pwd = value.replace(exec_root, "${pwd}");
252+
if out_dir.is_empty() {
253+
with_pwd
254+
} else {
255+
with_pwd.replace(out_dir, "${out_dir}")
256+
}
227257
}
228258

229259
// The process-wrapper treats trailing backslashes as escapes for following newlines.
@@ -283,15 +313,15 @@ mod tests {
283313
BuildScriptOutput::Env("no_trailing_newline=true".to_owned())
284314
);
285315
assert_eq!(
286-
BuildScriptOutput::outputs_to_dep_env(&result, "ssh2", "/some/absolute/path"),
316+
BuildScriptOutput::outputs_to_dep_env(&result, "ssh2", "/some/absolute/path", ""),
287317
"DEP_SSH2_VERSION=123\nDEP_SSH2_VERSION_NUMBER=1010107f\nDEP_SSH2_INCLUDE_PATH=${pwd}/include".to_owned()
288318
);
289319
assert_eq!(
290-
BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path"),
320+
BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path", ""),
291321
"FOO=BAR\nBAR=FOO\nSOME_PATH=${pwd}/beep\nno_trailing_newline=true".to_owned()
292322
);
293323
assert_eq!(
294-
BuildScriptOutput::outputs_to_flags(&result, "/some/absolute/path"),
324+
BuildScriptOutput::outputs_to_flags(&result, "/some/absolute/path", ""),
295325
CompileAndLinkFlags {
296326
// -Lblah was output as a rustc-flags, so even though it probably _should_ be a link
297327
// flag, we don't treat it like one.
@@ -366,7 +396,7 @@ cargo::rustc-env=valid2=2
366396
let result = BuildScriptOutput::outputs_from_reader(reader);
367397
assert_eq!(result.len(), 2);
368398
assert_eq!(
369-
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path"),
399+
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path", ""),
370400
"valid1=1\nvalid2=2"
371401
);
372402
}
@@ -385,7 +415,7 @@ cargo:rustc-env=valid2=2
385415
let result = BuildScriptOutput::outputs_from_reader(reader);
386416
assert_eq!(result.len(), 2);
387417
assert_eq!(
388-
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path"),
418+
&BuildScriptOutput::outputs_to_env(&result, "/some/absolute/path", ""),
389419
"valid1=1\nvalid2=2"
390420
);
391421
}
@@ -399,4 +429,32 @@ cargo:rustc-env=valid2=2
399429
vec![BuildScriptOutput::DepEnv("VERSION_1_10_0=1".to_owned())]
400430
);
401431
}
432+
433+
/// Verify that a build-script-emitted env var that references the
434+
/// `out_dir` (e.g. `cargo::rustc-env=FOO=$OUT_DIR/bar`) is rewritten
435+
/// to use the `${out_dir}` substitution token. `process_wrapper`
436+
/// substitutes the token at action execution time using the value
437+
/// from its `--out-dir` arg, which is sourced from a `File`-typed
438+
/// `Args` entry on the rules_rust side and therefore picks up Bazel
439+
/// path mapping (`--experimental_output_paths=strip`) when the
440+
/// consumer Rustc action advertises `supports-path-mapping`.
441+
#[test]
442+
fn out_dir_in_env_value_is_redacted_to_substitution_token() {
443+
let buff = Cursor::new(
444+
"
445+
cargo::rustc-env=FOO=/abs/exec_root/bazel-out/cfg/bin/_bs.out_dir/op.rs
446+
cargo::rustc-env=BAR=/abs/exec_root/elsewhere/file.rs
447+
",
448+
);
449+
let reader = BufReader::new(buff);
450+
let result = BuildScriptOutput::outputs_from_reader(reader);
451+
assert_eq!(
452+
BuildScriptOutput::outputs_to_env(
453+
&result,
454+
"/abs/exec_root",
455+
"bazel-out/cfg/bin/_bs.out_dir",
456+
),
457+
"FOO=${pwd}/${out_dir}/op.rs\nBAR=${pwd}/elsewhere/file.rs"
458+
);
459+
}
402460
}

0 commit comments

Comments
 (0)