Skip to content

Commit bfc9c00

Browse files
committed
fix(bootstrap): set rpath for rustc-main tests
Signed-off-by: HNO3Miracle <xiangao.or@isrc.iscas.ac.cn>
1 parent 2574810 commit bfc9c00

3 files changed

Lines changed: 65 additions & 3 deletions

File tree

src/bootstrap/src/bin/rustc.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use std::time::Instant;
2222

2323
use arg_file_command::ArgFileCommand;
2424
use shared_helpers::{
25-
dylib_path, dylib_path_var, exe, maybe_dump, parse_rustc_stage, parse_rustc_verbose,
26-
parse_value_from_args,
25+
dylib_path, dylib_path_var, exe, maybe_dump, parse_extern_path_from_args, parse_rustc_stage,
26+
parse_rustc_verbose, parse_value_from_args,
2727
};
2828

2929
#[path = "../utils/shared_helpers.rs"]
@@ -252,6 +252,19 @@ fn main() {
252252
}
253253

254254
let is_test = args.iter().any(|a| a == "--test");
255+
if is_test
256+
&& crate_name == Some("rustc_main")
257+
&& target == Some(host.as_str())
258+
&& supports_absolute_rpath(&host)
259+
&& let Some(rustc_driver) = parse_extern_path_from_args(&orig_args, "rustc_driver")
260+
&& let Some(rustc_driver_dir) = Path::new(rustc_driver).parent()
261+
{
262+
// This is a temporary test binary under Cargo's build directory, not the
263+
// staged rustc binary. Its runtime rpath needs to point to the actual
264+
// rustc_driver dylib that Cargo linked it against.
265+
cmd.arg(format!("-Clink-arg=-Wl,-rpath,{}", rustc_driver_dir.display()));
266+
}
267+
255268
if verbose > 2 {
256269
let rust_env_vars =
257270
env::vars().filter(|(k, _)| k.starts_with("RUST") || k.starts_with("CARGO"));
@@ -332,6 +345,14 @@ fn main() {
332345
}
333346
}
334347

348+
fn supports_absolute_rpath(target: &str) -> bool {
349+
!target.contains("windows")
350+
&& !target.contains("cygwin")
351+
&& !target.contains("apple")
352+
&& !target.contains("aix")
353+
&& !target.contains("xous")
354+
}
355+
335356
#[cfg(all(not(unix), not(windows)))]
336357
// In the future we can add this for more platforms
337358
fn format_rusage_data(_child: Child) -> Option<String> {

src/bootstrap/src/utils/shared_helpers.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,25 @@ pub fn parse_value_from_args<'a>(args: &'a [OsString], key: &str) -> Option<&'a
126126

127127
None
128128
}
129+
130+
/// Finds an `--extern crate=path` argument and returns its path.
131+
pub fn parse_extern_path_from_args<'a>(args: &'a [OsString], krate: &str) -> Option<&'a str> {
132+
let krate = format!("{krate}=");
133+
let mut args = args.iter();
134+
while let Some(arg) = args.next() {
135+
let arg = arg.to_str().unwrap();
136+
let value = if let Some(value) = arg.strip_prefix("--extern=") {
137+
value
138+
} else if arg == "--extern" {
139+
args.next()?.to_str().unwrap()
140+
} else {
141+
continue;
142+
};
143+
144+
if let Some(path) = value.strip_prefix(&krate) {
145+
return Some(path);
146+
}
147+
}
148+
149+
None
150+
}

src/bootstrap/src/utils/tests/shared_helpers_tests.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! To prevent tidy from complaining about this file not being named `tests.rs`, it lives inside a
66
//! submodule directory named `tests`.
77
8-
use crate::utils::shared_helpers::parse_value_from_args;
8+
use crate::utils::shared_helpers::{parse_extern_path_from_args, parse_value_from_args};
99

1010
#[test]
1111
fn test_parse_value_from_args() {
@@ -33,3 +33,22 @@ fn test_parse_value_from_args() {
3333
assert_eq!(parse_value_from_args(args.as_slice(), "--key").unwrap(), "value");
3434
assert_eq!(parse_value_from_args(args.as_slice(), "--sysroot").unwrap(), "/x/y/z");
3535
}
36+
37+
#[test]
38+
fn test_parse_extern_path_from_args() {
39+
let args = vec![
40+
"--extern".into(),
41+
"rustc_driver=/path/to/librustc_driver.so".into(),
42+
"--extern=rustc_ast=/path/to/librustc_ast.rlib".into(),
43+
];
44+
45+
assert_eq!(
46+
parse_extern_path_from_args(args.as_slice(), "rustc_driver").unwrap(),
47+
"/path/to/librustc_driver.so"
48+
);
49+
assert_eq!(
50+
parse_extern_path_from_args(args.as_slice(), "rustc_ast").unwrap(),
51+
"/path/to/librustc_ast.rlib"
52+
);
53+
assert!(parse_extern_path_from_args(args.as_slice(), "rustc_middle").is_none());
54+
}

0 commit comments

Comments
 (0)