11use pathdiff::diff_paths;
22use rustc_data_structures::fx::FxHashSet;
33use std::env;
4+ use std::ffi::OsString;
45use std::fs;
56use std::path::{Path, PathBuf};
67
@@ -12,7 +13,7 @@ pub struct RPathConfig<'a> {
1213 pub linker_is_gnu: bool,
1314}
1415
15- pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String > {
16+ pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<OsString > {
1617 // No rpath on windows
1718 if !config.has_rpath {
1819 return Vec::new();
@@ -21,36 +22,38 @@ pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String> {
2122 debug!("preparing the RPATH!");
2223
2324 let rpaths = get_rpaths(config);
24- let mut flags = rpaths_to_flags(& rpaths);
25+ let mut flags = rpaths_to_flags(rpaths);
2526
2627 if config.linker_is_gnu {
2728 // Use DT_RUNPATH instead of DT_RPATH if available
28- flags.push("-Wl,--enable-new-dtags".to_owned ());
29+ flags.push("-Wl,--enable-new-dtags".into ());
2930
3031 // Set DF_ORIGIN for substitute $ORIGIN
31- flags.push("-Wl,-z,origin".to_owned ());
32+ flags.push("-Wl,-z,origin".into ());
3233 }
3334
3435 flags
3536}
3637
37- fn rpaths_to_flags(rpaths: &[String] ) -> Vec<String > {
38+ fn rpaths_to_flags(rpaths: Vec<OsString> ) -> Vec<OsString > {
3839 let mut ret = Vec::with_capacity(rpaths.len()); // the minimum needed capacity
3940
4041 for rpath in rpaths {
41- if rpath.contains(',') {
42+ if rpath.to_string_lossy(). contains(',') {
4243 ret.push("-Wl,-rpath".into());
4344 ret.push("-Xlinker".into());
44- ret.push(rpath.clone() );
45+ ret.push(rpath);
4546 } else {
46- ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
47+ let mut single_arg = OsString::from("-Wl,-rpath,");
48+ single_arg.push(rpath);
49+ ret.push(single_arg);
4750 }
4851 }
4952
5053 ret
5154}
5255
53- fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<String > {
56+ fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<OsString > {
5457 debug!("output: {:?}", config.out_filename.display());
5558 debug!("libs:");
5659 for libpath in config.libs {
@@ -64,18 +67,18 @@ fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<String> {
6467
6568 debug!("rpaths:");
6669 for rpath in &rpaths {
67- debug!(" {}", rpath);
70+ debug!(" {:? }", rpath);
6871 }
6972
7073 // Remove duplicates
7174 minimize_rpaths(&rpaths)
7275}
7376
74- fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>) -> Vec<String > {
77+ fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>) -> Vec<OsString > {
7578 config.libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
7679}
7780
78- fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> String {
81+ fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> OsString {
7982 // Mac doesn't appear to support $ORIGIN
8083 let prefix = if config.is_like_osx { "@loader_path" } else { "$ORIGIN" };
8184
@@ -87,8 +90,11 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> Str
8790 let output = fs::canonicalize(&output).unwrap_or(output);
8891 let relative = path_relative_from(&lib, &output)
8992 .unwrap_or_else(|| panic!("couldn't create relative path from {output:?} to {lib:?}"));
90- // FIXME (#9639): This needs to handle non-utf8 paths
91- format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path"))
93+
94+ let mut rpath = OsString::from(prefix);
95+ rpath.push("/");
96+ rpath.push(relative);
97+ rpath
9298}
9399
94100// This routine is adapted from the *old* Path's `path_relative_from`
@@ -99,7 +105,7 @@ fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
99105 diff_paths(path, base)
100106}
101107
102- fn minimize_rpaths(rpaths: &[String ]) -> Vec<String > {
108+ fn minimize_rpaths(rpaths: &[OsString ]) -> Vec<OsString > {
103109 let mut set = FxHashSet::default();
104110 let mut minimized = Vec::new();
105111 for rpath in rpaths {
0 commit comments