Rollup merge of #114427 - Enselic:rustc_codegen_ssa-fixme, r=Nilstrieb
Handle non-utf8 rpaths (fix FIXME) Removes a FIXME for #9639 which is closed since long ago. Part of #44366 which is E-help-wanted. (Also see https://github.com/rust-lang/rust/pull/114377)
This commit is contained in:
commit
4fb44e59c4
@ -1,6 +1,7 @@
|
|||||||
use pathdiff::diff_paths;
|
use pathdiff::diff_paths;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ pub struct RPathConfig<'a> {
|
|||||||
pub linker_is_gnu: bool,
|
pub linker_is_gnu: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String> {
|
pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<OsString> {
|
||||||
// No rpath on windows
|
// No rpath on windows
|
||||||
if !config.has_rpath {
|
if !config.has_rpath {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@ -21,36 +22,38 @@ pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String> {
|
|||||||
debug!("preparing the RPATH!");
|
debug!("preparing the RPATH!");
|
||||||
|
|
||||||
let rpaths = get_rpaths(config);
|
let rpaths = get_rpaths(config);
|
||||||
let mut flags = rpaths_to_flags(&rpaths);
|
let mut flags = rpaths_to_flags(rpaths);
|
||||||
|
|
||||||
if config.linker_is_gnu {
|
if config.linker_is_gnu {
|
||||||
// Use DT_RUNPATH instead of DT_RPATH if available
|
// Use DT_RUNPATH instead of DT_RPATH if available
|
||||||
flags.push("-Wl,--enable-new-dtags".to_owned());
|
flags.push("-Wl,--enable-new-dtags".into());
|
||||||
|
|
||||||
// Set DF_ORIGIN for substitute $ORIGIN
|
// Set DF_ORIGIN for substitute $ORIGIN
|
||||||
flags.push("-Wl,-z,origin".to_owned());
|
flags.push("-Wl,-z,origin".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
|
fn rpaths_to_flags(rpaths: Vec<OsString>) -> Vec<OsString> {
|
||||||
let mut ret = Vec::with_capacity(rpaths.len()); // the minimum needed capacity
|
let mut ret = Vec::with_capacity(rpaths.len()); // the minimum needed capacity
|
||||||
|
|
||||||
for rpath in rpaths {
|
for rpath in rpaths {
|
||||||
if rpath.contains(',') {
|
if rpath.to_string_lossy().contains(',') {
|
||||||
ret.push("-Wl,-rpath".into());
|
ret.push("-Wl,-rpath".into());
|
||||||
ret.push("-Xlinker".into());
|
ret.push("-Xlinker".into());
|
||||||
ret.push(rpath.clone());
|
ret.push(rpath);
|
||||||
} else {
|
} else {
|
||||||
ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
|
let mut single_arg = OsString::from("-Wl,-rpath,");
|
||||||
|
single_arg.push(rpath);
|
||||||
|
ret.push(single_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<String> {
|
fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<OsString> {
|
||||||
debug!("output: {:?}", config.out_filename.display());
|
debug!("output: {:?}", config.out_filename.display());
|
||||||
debug!("libs:");
|
debug!("libs:");
|
||||||
for libpath in config.libs {
|
for libpath in config.libs {
|
||||||
@ -64,18 +67,18 @@ fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<String> {
|
|||||||
|
|
||||||
debug!("rpaths:");
|
debug!("rpaths:");
|
||||||
for rpath in &rpaths {
|
for rpath in &rpaths {
|
||||||
debug!(" {}", rpath);
|
debug!(" {:?}", rpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
minimize_rpaths(&rpaths)
|
minimize_rpaths(&rpaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>) -> Vec<String> {
|
fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>) -> Vec<OsString> {
|
||||||
config.libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
|
config.libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> String {
|
fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> OsString {
|
||||||
// Mac doesn't appear to support $ORIGIN
|
// Mac doesn't appear to support $ORIGIN
|
||||||
let prefix = if config.is_like_osx { "@loader_path" } else { "$ORIGIN" };
|
let prefix = if config.is_like_osx { "@loader_path" } else { "$ORIGIN" };
|
||||||
|
|
||||||
@ -87,8 +90,11 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> Str
|
|||||||
let output = fs::canonicalize(&output).unwrap_or(output);
|
let output = fs::canonicalize(&output).unwrap_or(output);
|
||||||
let relative = path_relative_from(&lib, &output)
|
let relative = path_relative_from(&lib, &output)
|
||||||
.unwrap_or_else(|| panic!("couldn't create relative path from {output:?} to {lib:?}"));
|
.unwrap_or_else(|| panic!("couldn't create relative path from {output:?} to {lib:?}"));
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
|
||||||
format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path"))
|
let mut rpath = OsString::from(prefix);
|
||||||
|
rpath.push("/");
|
||||||
|
rpath.push(relative);
|
||||||
|
rpath
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine is adapted from the *old* Path's `path_relative_from`
|
// 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> {
|
|||||||
diff_paths(path, base)
|
diff_paths(path, base)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
|
fn minimize_rpaths(rpaths: &[OsString]) -> Vec<OsString> {
|
||||||
let mut set = FxHashSet::default();
|
let mut set = FxHashSet::default();
|
||||||
let mut minimized = Vec::new();
|
let mut minimized = Vec::new();
|
||||||
for rpath in rpaths {
|
for rpath in rpaths {
|
||||||
|
@ -1,32 +1,33 @@
|
|||||||
use super::RPathConfig;
|
use super::RPathConfig;
|
||||||
use super::{get_rpath_relative_to_output, minimize_rpaths, rpaths_to_flags};
|
use super::{get_rpath_relative_to_output, minimize_rpaths, rpaths_to_flags};
|
||||||
|
use std::ffi::OsString;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rpaths_to_flags() {
|
fn test_rpaths_to_flags() {
|
||||||
let flags = rpaths_to_flags(&["path1".to_string(), "path2".to_string()]);
|
let flags = rpaths_to_flags(vec!["path1".into(), "path2".into()]);
|
||||||
assert_eq!(flags, ["-Wl,-rpath,path1", "-Wl,-rpath,path2"]);
|
assert_eq!(flags, ["-Wl,-rpath,path1", "-Wl,-rpath,path2"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_minimize1() {
|
fn test_minimize1() {
|
||||||
let res = minimize_rpaths(&["rpath1".to_string(), "rpath2".to_string(), "rpath1".to_string()]);
|
let res = minimize_rpaths(&["rpath1".into(), "rpath2".into(), "rpath1".into()]);
|
||||||
assert!(res == ["rpath1", "rpath2",]);
|
assert!(res == ["rpath1", "rpath2",]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_minimize2() {
|
fn test_minimize2() {
|
||||||
let res = minimize_rpaths(&[
|
let res = minimize_rpaths(&[
|
||||||
"1a".to_string(),
|
"1a".into(),
|
||||||
"2".to_string(),
|
"2".into(),
|
||||||
"2".to_string(),
|
"2".into(),
|
||||||
"1a".to_string(),
|
"1a".into(),
|
||||||
"4a".to_string(),
|
"4a".into(),
|
||||||
"1a".to_string(),
|
"1a".into(),
|
||||||
"2".to_string(),
|
"2".into(),
|
||||||
"3".to_string(),
|
"3".into(),
|
||||||
"4a".to_string(),
|
"4a".into(),
|
||||||
"3".to_string(),
|
"3".into(),
|
||||||
]);
|
]);
|
||||||
assert!(res == ["1a", "2", "4a", "3",]);
|
assert!(res == ["1a", "2", "4a", "3",]);
|
||||||
}
|
}
|
||||||
@ -58,15 +59,15 @@ fn test_rpath_relative() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_xlinker() {
|
fn test_xlinker() {
|
||||||
let args = rpaths_to_flags(&["a/normal/path".to_string(), "a,comma,path".to_string()]);
|
let args = rpaths_to_flags(vec!["a/normal/path".into(), "a,comma,path".into()]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
args,
|
args,
|
||||||
vec![
|
vec![
|
||||||
"-Wl,-rpath,a/normal/path".to_string(),
|
OsString::from("-Wl,-rpath,a/normal/path"),
|
||||||
"-Wl,-rpath".to_string(),
|
OsString::from("-Wl,-rpath"),
|
||||||
"-Xlinker".to_string(),
|
OsString::from("-Xlinker"),
|
||||||
"a,comma,path".to_string()
|
OsString::from("a,comma,path")
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user