From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- src/tools/compiletest/Cargo.toml | 1 + src/tools/compiletest/src/common.rs | 23 ++- src/tools/compiletest/src/header.rs | 8 +- src/tools/compiletest/src/header/tests.rs | 1 + src/tools/compiletest/src/main.rs | 3 + src/tools/compiletest/src/runtest.rs | 310 +++++++++++++----------------- src/tools/compiletest/src/util.rs | 23 +++ 7 files changed, 184 insertions(+), 185 deletions(-) (limited to 'src/tools/compiletest') diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 41f97e432..1911f0f9c 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -8,6 +8,7 @@ colored = "2" diff = "0.1.10" unified-diff = "0.2.1" getopts = "0.2" +miropt-test-tools = { path = "../miropt-test-tools" } tracing = "0.1" tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } regex = "1.0" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 0260f6848..07b80b8ba 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -2,11 +2,12 @@ pub use self::Mode::*; use std::ffi::OsString; use std::fmt; +use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; -use crate::util::PathBufExt; +use crate::util::{add_dylib_path, PathBufExt}; use lazycell::LazyCell; use test::ColorConfig; @@ -229,6 +230,9 @@ pub struct Config { /// The directory where programs should be built pub build_base: PathBuf, + /// The directory containing the compiler sysroot + pub sysroot_base: PathBuf, + /// The name of the stage being built (stage1, etc) pub stage_id: String, @@ -385,8 +389,7 @@ impl Config { } fn target_cfg(&self) -> &TargetCfg { - self.target_cfg - .borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target, &self.target_rustcflags)) + self.target_cfg.borrow_with(|| TargetCfg::new(self)) } pub fn matches_arch(&self, arch: &str) -> bool { @@ -457,21 +460,23 @@ pub enum Endian { } impl TargetCfg { - fn new(rustc_path: &Path, target: &str, target_rustcflags: &Vec) -> TargetCfg { - let output = match Command::new(rustc_path) + fn new(config: &Config) -> TargetCfg { + let mut command = Command::new(&config.rustc_path); + add_dylib_path(&mut command, iter::once(&config.compile_lib_path)); + let output = match command .arg("--print=cfg") .arg("--target") - .arg(target) - .args(target_rustcflags) + .arg(&config.target) + .args(&config.target_rustcflags) .output() { Ok(output) => output, - Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path), + Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path), }; if !output.status.success() { panic!( "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}", - rustc_path, + config.rustc_path, String::from_utf8(output.stdout).unwrap(), String::from_utf8(output.stderr).unwrap(), ); diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 0d9a629e1..64d97e914 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -260,9 +260,9 @@ impl TestProps { props.load_from(testfile, cfg, config); match (props.pass_mode, props.fail_mode) { - (None, None) => props.fail_mode = Some(FailMode::Check), - (Some(_), None) | (None, Some(_)) => {} + (None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check), (Some(_), Some(_)) => panic!("cannot use a *-fail and *-pass mode together"), + _ => {} } props @@ -522,8 +522,8 @@ impl TestProps { } pub fn pass_mode(&self, config: &Config) -> Option { - if !self.ignore_pass && self.fail_mode.is_none() && config.mode == Mode::Ui { - if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) { + if !self.ignore_pass && self.fail_mode.is_none() { + if let mode @ Some(_) = config.force_pass_mode { return mode; } } diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index bcd222b5a..e42b8c524 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -46,6 +46,7 @@ fn config() -> Config { "--jsondocck-path=", "--src-base=", "--build-base=", + "--sysroot-base=", "--stage-id=stage2", "--cc=c", "--cxx=c++", diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 19cf54780..91c701a5d 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -69,6 +69,7 @@ pub fn parse_config(args: Vec) -> Config { .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR") .reqopt("", "src-base", "directory to scan for test files", "PATH") .reqopt("", "build-base", "directory to deposit test outputs", "PATH") + .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH") .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET") .reqopt( "", @@ -234,6 +235,7 @@ pub fn parse_config(args: Vec) -> Config { llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from), src_base, build_base: opt_path(matches, "build-base"), + sysroot_base: opt_path(matches, "sysroot-base"), stage_id: matches.opt_str("stage-id").unwrap(), mode, suite: matches.opt_str("suite").unwrap(), @@ -512,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { options: test::Options::new(), time_options: None, force_run_in_process: false, + fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(), } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8af5f1da6..1542b1c17 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -13,7 +13,7 @@ use crate::errors::{self, Error, ErrorKind}; use crate::header::TestProps; use crate::json; use crate::read2::read2_abbreviated; -use crate::util::{logv, PathBufExt}; +use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt}; use crate::ColorConfig; use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; @@ -26,6 +26,7 @@ use std::fs::{self, create_dir_all, File, OpenOptions}; use std::hash::{Hash, Hasher}; use std::io::prelude::*; use std::io::{self, BufReader}; +use std::iter; use std::path::{Path, PathBuf}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; @@ -72,19 +73,6 @@ fn disable_error_reporting R, R>(f: F) -> R { f() } -/// The name of the environment variable that holds dynamic library locations. -pub fn dylib_env_var() -> &'static str { - if cfg!(windows) { - "PATH" - } else if cfg!(target_os = "macos") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else { - "LD_LIBRARY_PATH" - } -} - /// The platform-specific library name pub fn get_lib_name(lib: &str, dylib: bool) -> String { // In some casess (e.g. MUSL), we build a static @@ -220,11 +208,13 @@ enum WillExecute { Disabled, } -/// Should `--emit metadata` be used? +/// What value should be passed to `--emit`? #[derive(Copy, Clone)] -enum EmitMetadata { - Yes, - No, +enum Emit { + None, + Metadata, + LlvmIr, + Asm, } impl<'test> TestCx<'test> { @@ -424,7 +414,7 @@ impl<'test> TestCx<'test> { } let should_run = self.run_if_enabled(); - let mut proc_res = self.compile_test(should_run, EmitMetadata::No); + let mut proc_res = self.compile_test(should_run, Emit::None); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -670,7 +660,7 @@ impl<'test> TestCx<'test> { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compile_result = self.compile_test(should_run, EmitMetadata::No); + let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { self.fatal_proc_rec("compilation failed!", &compile_result); } @@ -721,7 +711,7 @@ impl<'test> TestCx<'test> { script_str.push_str("\n"); } - script_str.push_str("\nqq\n"); // Quit the debugger (including remote debugger, if any) + script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any) // Write the script into a file debug!("script_str = {}", script_str); @@ -790,7 +780,7 @@ impl<'test> TestCx<'test> { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compiler_run_result = self.compile_test(should_run, EmitMetadata::No); + let compiler_run_result = self.compile_test(should_run, Emit::None); if !compiler_run_result.status.success() { self.fatal_proc_rec("compilation failed!", &compiler_run_result); } @@ -1022,7 +1012,7 @@ impl<'test> TestCx<'test> { fn run_debuginfo_lldb_test_no_opt(&self) { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compile_result = self.compile_test(should_run, EmitMetadata::No); + let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { self.fatal_proc_rec("compilation failed!", &compile_result); } @@ -1438,21 +1428,21 @@ impl<'test> TestCx<'test> { } } - fn should_emit_metadata(&self, pm: Option) -> EmitMetadata { + fn should_emit_metadata(&self, pm: Option) -> Emit { match (pm, self.props.fail_mode, self.config.mode) { - (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => EmitMetadata::Yes, - _ => EmitMetadata::No, + (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => Emit::Metadata, + _ => Emit::None, } } - fn compile_test(&self, will_execute: WillExecute, emit_metadata: EmitMetadata) -> ProcRes { - self.compile_test_general(will_execute, emit_metadata, self.props.local_pass_mode()) + fn compile_test(&self, will_execute: WillExecute, emit: Emit) -> ProcRes { + self.compile_test_general(will_execute, emit, self.props.local_pass_mode()) } fn compile_test_general( &self, will_execute: WillExecute, - emit_metadata: EmitMetadata, + emit: Emit, local_pm: Option, ) -> ProcRes { // Only use `make_exe_name` when the test ends up being executed. @@ -1484,10 +1474,13 @@ impl<'test> TestCx<'test> { _ => AllowUnused::No, }; - let mut rustc = - self.make_compile_args(&self.testpaths.file, output_file, emit_metadata, allow_unused); - - rustc.arg("-L").arg(&self.aux_output_dir_name()); + let rustc = self.make_compile_args( + &self.testpaths.file, + output_file, + emit, + allow_unused, + LinkToAux::Yes, + ); self.compose_and_run_compiler(rustc, None) } @@ -1714,8 +1707,13 @@ impl<'test> TestCx<'test> { // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); let input_file = &aux_testpaths.file; - let mut aux_rustc = - aux_cx.make_compile_args(input_file, aux_output, EmitMetadata::No, AllowUnused::No); + let mut aux_rustc = aux_cx.make_compile_args( + input_file, + aux_output, + Emit::None, + AllowUnused::No, + LinkToAux::No, + ); for key in &aux_props.unset_rustc_env { aux_rustc.env_remove(key); @@ -1811,16 +1809,7 @@ impl<'test> TestCx<'test> { // Need to be sure to put both the lib_path and the aux path in the dylib // search path for the child. - let mut path = - env::split_paths(&env::var_os(dylib_env_var()).unwrap_or_default()).collect::>(); - if let Some(p) = aux_path { - path.insert(0, PathBuf::from(p)) - } - path.insert(0, PathBuf::from(lib_path)); - - // Add the new dylib search path var - let newpath = env::join_paths(&path).unwrap(); - command.env(dylib_env_var(), newpath); + add_dylib_path(&mut command, iter::once(lib_path).chain(aux_path)); let mut child = disable_error_reporting(|| command.spawn()) .unwrap_or_else(|_| panic!("failed to exec `{:?}`", &command)); @@ -1852,8 +1841,9 @@ impl<'test> TestCx<'test> { &self, input_file: &Path, output_file: TargetLocation, - emit_metadata: EmitMetadata, + emit: Emit, allow_unused: AllowUnused, + link_to_aux: LinkToAux, ) -> Command { let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary"); let is_rustdoc = self.is_rustdoc() && !is_aux; @@ -1968,8 +1958,18 @@ impl<'test> TestCx<'test> { } } - if let (false, EmitMetadata::Yes) = (is_rustdoc, emit_metadata) { - rustc.args(&["--emit", "metadata"]); + match emit { + Emit::None => {} + Emit::Metadata if is_rustdoc => {} + Emit::Metadata => { + rustc.args(&["--emit", "metadata"]); + } + Emit::LlvmIr => { + rustc.args(&["--emit", "llvm-ir"]); + } + Emit::Asm => { + rustc.args(&["--emit", "asm"]); + } } if !is_rustdoc { @@ -2035,6 +2035,10 @@ impl<'test> TestCx<'test> { rustc.arg("-Ctarget-feature=-crt-static"); } + if let LinkToAux::Yes = link_to_aux { + rustc.arg("-L").arg(self.aux_output_dir_name()); + } + rustc.args(&self.props.compile_flags); rustc @@ -2226,13 +2230,15 @@ impl<'test> TestCx<'test> { // codegen tests (using FileCheck) fn compile_test_and_save_ir(&self) -> ProcRes { - let aux_dir = self.aux_output_dir_name(); - let output_file = TargetLocation::ThisDirectory(self.output_base_dir()); let input_file = &self.testpaths.file; - let mut rustc = - self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No); - rustc.arg("-L").arg(aux_dir).arg("--emit=llvm-ir"); + let rustc = self.make_compile_args( + input_file, + output_file, + Emit::LlvmIr, + AllowUnused::No, + LinkToAux::Yes, + ); self.compose_and_run_compiler(rustc, None) } @@ -2244,14 +2250,11 @@ impl<'test> TestCx<'test> { let output_file = TargetLocation::ThisFile(output_path.clone()); let input_file = &self.testpaths.file; - let mut rustc = - self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No); - - rustc.arg("-L").arg(self.aux_output_dir_name()); + let mut emit = Emit::None; match self.props.assembly_output.as_ref().map(AsRef::as_ref) { Some("emit-asm") => { - rustc.arg("--emit=asm"); + emit = Emit::Asm; } Some("ptx-linker") => { @@ -2262,6 +2265,9 @@ impl<'test> TestCx<'test> { None => self.fatal("missing 'assembly-output' header"), } + let rustc = + self.make_compile_args(input_file, output_file, emit, AllowUnused::No, LinkToAux::Yes); + (self.compose_and_run_compiler(rustc, None), output_path) } @@ -2386,10 +2392,10 @@ impl<'test> TestCx<'test> { let mut rustc = new_rustdoc.make_compile_args( &new_rustdoc.testpaths.file, output_file, - EmitMetadata::No, + Emit::None, AllowUnused::Yes, + LinkToAux::Yes, ); - rustc.arg("-L").arg(&new_rustdoc.aux_output_dir_name()); new_rustdoc.build_all_auxiliary(&mut rustc); let proc_res = new_rustdoc.document(&compare_dir); @@ -2662,7 +2668,7 @@ impl<'test> TestCx<'test> { fn run_codegen_units_test(&self) { assert!(self.revision.is_none(), "revisions not relevant here"); - let proc_res = self.compile_test(WillExecute::No, EmitMetadata::No); + let proc_res = self.compile_test(WillExecute::No, Emit::None); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -2981,6 +2987,10 @@ impl<'test> TestCx<'test> { cmd.env("LLVM_BIN_DIR", llvm_bin_dir); } + if let Some(ref remote_test_client) = self.config.remote_test_client { + cmd.env("REMOTE_TEST_CLIENT", remote_test_client); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); @@ -3175,7 +3185,7 @@ impl<'test> TestCx<'test> { if let Some(FailMode::Build) = self.props.fail_mode { // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck). let pm = Some(PassMode::Check); - let proc_res = self.compile_test_general(WillExecute::No, EmitMetadata::Yes, pm); + let proc_res = self.compile_test_general(WillExecute::No, Emit::Metadata, pm); self.check_if_test_should_compile(&proc_res, pm); } @@ -3333,13 +3343,13 @@ impl<'test> TestCx<'test> { if self.props.run_rustfix && self.config.compare_mode.is_none() { // And finally, compile the fixed code and make sure it both // succeeds and has no diagnostics. - let mut rustc = self.make_compile_args( + let rustc = self.make_compile_args( &self.testpaths.file.with_extension(UI_FIXED), TargetLocation::ThisFile(self.make_exe_name()), emit_metadata, AllowUnused::No, + LinkToAux::Yes, ); - rustc.arg("-L").arg(&self.aux_output_dir_name()); let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); @@ -3399,103 +3409,49 @@ impl<'test> TestCx<'test> { } } - for l in test_file_contents.lines() { - if l.starts_with("// EMIT_MIR ") { - let test_name = l.trim_start_matches("// EMIT_MIR ").trim(); - let mut test_names = test_name.split(' '); - // sometimes we specify two files so that we get a diff between the two files - let test_name = test_names.next().unwrap(); - let mut expected_file; - let from_file; - let to_file; - - if test_name.ends_with(".diff") { - let trimmed = test_name.trim_end_matches(".diff"); - let test_against = format!("{}.after.mir", trimmed); - from_file = format!("{}.before.mir", trimmed); - expected_file = format!("{}{}.diff", trimmed, bit_width); - assert!( - test_names.next().is_none(), - "two mir pass names specified for MIR diff" - ); - to_file = Some(test_against); - } else if let Some(first_pass) = test_names.next() { - let second_pass = test_names.next().unwrap(); - assert!( - test_names.next().is_none(), - "three mir pass names specified for MIR diff" - ); - expected_file = - format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); - let second_file = format!("{}.{}.mir", test_name, second_pass); - from_file = format!("{}.{}.mir", test_name, first_pass); - to_file = Some(second_file); - } else { - let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap(); - let cap = ext_re - .captures_iter(test_name) - .next() - .expect("test_name has an invalid extension"); - let extension = cap.get(1).unwrap().as_str(); - expected_file = format!( - "{}{}{}", - test_name.trim_end_matches(extension), - bit_width, - extension, - ); - from_file = test_name.to_string(); - assert!( - test_names.next().is_none(), - "two mir pass names specified for MIR dump" + let files = miropt_test_tools::files_for_miropt_test( + &self.testpaths.file, + self.config.get_pointer_width(), + ); + + for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files { + let dumped_string = if let Some(after) = to_file { + self.diff_mir_files(from_file.into(), after.into()) + } else { + let mut output_file = PathBuf::new(); + output_file.push(self.get_mir_dump_dir()); + output_file.push(&from_file); + debug!( + "comparing the contents of: {} with {}", + output_file.display(), + expected_file.display() + ); + if !output_file.exists() { + panic!( + "Output file `{}` from test does not exist, available files are in `{}`", + output_file.display(), + output_file.parent().unwrap().display() ); - to_file = None; - }; - if !expected_file.starts_with(&test_crate) { - expected_file = format!("{}.{}", test_crate, expected_file); } - let expected_file = test_dir.join(expected_file); + self.check_mir_test_timestamp(&from_file, &output_file); + let dumped_string = fs::read_to_string(&output_file).unwrap(); + self.normalize_output(&dumped_string, &[]) + }; - let dumped_string = if let Some(after) = to_file { - self.diff_mir_files(from_file.into(), after.into()) - } else { - let mut output_file = PathBuf::new(); - output_file.push(self.get_mir_dump_dir()); - output_file.push(&from_file); - debug!( - "comparing the contents of: {} with {}", - output_file.display(), + if self.config.bless { + let _ = std::fs::remove_file(&expected_file); + std::fs::write(expected_file, dumped_string.as_bytes()).unwrap(); + } else { + if !expected_file.exists() { + panic!("Output file `{}` from test does not exist", expected_file.display()); + } + let expected_string = fs::read_to_string(&expected_file).unwrap(); + if dumped_string != expected_string { + print!("{}", write_diff(&expected_string, &dumped_string, 3)); + panic!( + "Actual MIR output differs from expected MIR output {}", expected_file.display() ); - if !output_file.exists() { - panic!( - "Output file `{}` from test does not exist, available files are in `{}`", - output_file.display(), - output_file.parent().unwrap().display() - ); - } - self.check_mir_test_timestamp(&from_file, &output_file); - let dumped_string = fs::read_to_string(&output_file).unwrap(); - self.normalize_output(&dumped_string, &[]) - }; - - if self.config.bless { - let _ = std::fs::remove_file(&expected_file); - std::fs::write(expected_file, dumped_string.as_bytes()).unwrap(); - } else { - if !expected_file.exists() { - panic!( - "Output file `{}` from test does not exist", - expected_file.display() - ); - } - let expected_string = fs::read_to_string(&expected_file).unwrap(); - if dumped_string != expected_string { - print!("{}", write_diff(&expected_string, &dumped_string, 3)); - panic!( - "Actual MIR output differs from expected MIR output {}", - expected_file.display() - ); - } } } } @@ -3577,22 +3533,27 @@ impl<'test> TestCx<'test> { let parent_dir = self.testpaths.file.parent().unwrap(); normalize_path(parent_dir, "$DIR"); - // Paths into the libstd/libcore - let base_dir = self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap(); - let src_dir = base_dir.join("library"); - normalize_path(&src_dir, "$SRC_DIR"); - - // `ui-fulldeps` tests can show paths to the compiler source when testing macros from - // `rustc_macros` - // eg. /home/user/rust/compiler - let compiler_src_dir = base_dir.join("compiler"); - normalize_path(&compiler_src_dir, "$COMPILER_DIR"); - - if let Some(virtual_rust_source_base_dir) = - option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from) - { - normalize_path(&virtual_rust_source_base_dir.join("library"), "$SRC_DIR"); - normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$COMPILER_DIR"); + let source_bases = &[ + // Source base on the current filesystem (calculated as parent of `src/test/$suite`): + Some(self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap().into()), + // Source base on the sysroot (from the src components downloaded by `download-rustc`): + Some(self.config.sysroot_base.join("lib").join("rustlib").join("src").join("rust")), + // Virtual `/rustc/$sha` remapped paths (if `remap-debuginfo` is enabled): + option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from), + // Virtual `/rustc/$sha` coming from download-rustc: + std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from), + // Tests using -Zsimulate-remapped-rust-src-base should use this fake path + Some("/rustc/FAKE_PREFIX".into()), + ]; + for base_dir in source_bases { + if let Some(base_dir) = base_dir { + // Paths into the libstd/libcore + normalize_path(&base_dir.join("library"), "$SRC_DIR"); + // `ui-fulldeps` tests can show paths to the compiler source when testing macros from + // `rustc_macros` + // eg. /home/user/rust/compiler + normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR"); + } } // Paths into the build directory @@ -3927,3 +3888,8 @@ enum AllowUnused { Yes, No, } + +enum LinkToAux { + Yes, + No, +} diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index e5ff0906b..ec36f1e4f 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -2,6 +2,7 @@ use crate::common::Config; use std::env; use std::ffi::OsStr; use std::path::PathBuf; +use std::process::Command; use tracing::*; @@ -111,3 +112,25 @@ impl PathBufExt for PathBuf { } } } + +/// The name of the environment variable that holds dynamic library locations. +pub fn dylib_env_var() -> &'static str { + if cfg!(windows) { + "PATH" + } else if cfg!(target_os = "macos") { + "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" + } else { + "LD_LIBRARY_PATH" + } +} + +/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. +/// If the dylib_path_var is already set for this cmd, the old value will be overwritten! +pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator>) { + let path_env = env::var_os(dylib_env_var()); + let old_paths = path_env.as_ref().map(env::split_paths); + let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten()); + cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap()); +} -- cgit v1.2.3