1
1
use pathdiff:: diff_paths;
2
2
use rustc_data_structures:: fx:: FxHashSet ;
3
3
use std:: env;
4
+ use std:: ffi:: OsString ;
4
5
use std:: fs;
5
6
use std:: path:: { Path , PathBuf } ;
6
7
@@ -12,7 +13,7 @@ pub struct RPathConfig<'a> {
12
13
pub linker_is_gnu : bool ,
13
14
}
14
15
15
- pub fn get_rpath_flags ( config : & mut RPathConfig < ' _ > ) -> Vec < String > {
16
+ pub fn get_rpath_flags ( config : & mut RPathConfig < ' _ > ) -> Vec < OsString > {
16
17
// No rpath on windows
17
18
if !config. has_rpath {
18
19
return Vec :: new ( ) ;
@@ -21,36 +22,38 @@ pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String> {
21
22
debug ! ( "preparing the RPATH!" ) ;
22
23
23
24
let rpaths = get_rpaths ( config) ;
24
- let mut flags = rpaths_to_flags ( & rpaths) ;
25
+ let mut flags = rpaths_to_flags ( rpaths) ;
25
26
26
27
if config. linker_is_gnu {
27
28
// 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 ( ) ) ;
29
30
30
31
// Set DF_ORIGIN for substitute $ORIGIN
31
- flags. push ( "-Wl,-z,origin" . to_owned ( ) ) ;
32
+ flags. push ( "-Wl,-z,origin" . into ( ) ) ;
32
33
}
33
34
34
35
flags
35
36
}
36
37
37
- fn rpaths_to_flags ( rpaths : & [ String ] ) -> Vec < String > {
38
+ fn rpaths_to_flags ( rpaths : Vec < OsString > ) -> Vec < OsString > {
38
39
let mut ret = Vec :: with_capacity ( rpaths. len ( ) ) ; // the minimum needed capacity
39
40
40
41
for rpath in rpaths {
41
- if rpath. contains ( ',' ) {
42
+ if rpath. to_string_lossy ( ) . contains ( ',' ) {
42
43
ret. push ( "-Wl,-rpath" . into ( ) ) ;
43
44
ret. push ( "-Xlinker" . into ( ) ) ;
44
- ret. push ( rpath. clone ( ) ) ;
45
+ ret. push ( rpath) ;
45
46
} 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) ;
47
50
}
48
51
}
49
52
50
53
ret
51
54
}
52
55
53
- fn get_rpaths ( config : & mut RPathConfig < ' _ > ) -> Vec < String > {
56
+ fn get_rpaths ( config : & mut RPathConfig < ' _ > ) -> Vec < OsString > {
54
57
debug ! ( "output: {:?}" , config. out_filename. display( ) ) ;
55
58
debug ! ( "libs:" ) ;
56
59
for libpath in config. libs {
@@ -64,18 +67,18 @@ fn get_rpaths(config: &mut RPathConfig<'_>) -> Vec<String> {
64
67
65
68
debug ! ( "rpaths:" ) ;
66
69
for rpath in & rpaths {
67
- debug ! ( " {}" , rpath) ;
70
+ debug ! ( " {:? }" , rpath) ;
68
71
}
69
72
70
73
// Remove duplicates
71
74
minimize_rpaths ( & rpaths)
72
75
}
73
76
74
- fn get_rpaths_relative_to_output ( config : & mut RPathConfig < ' _ > ) -> Vec < String > {
77
+ fn get_rpaths_relative_to_output ( config : & mut RPathConfig < ' _ > ) -> Vec < OsString > {
75
78
config. libs . iter ( ) . map ( |a| get_rpath_relative_to_output ( config, a) ) . collect ( )
76
79
}
77
80
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 {
79
82
// Mac doesn't appear to support $ORIGIN
80
83
let prefix = if config. is_like_osx { "@loader_path" } else { "$ORIGIN" } ;
81
84
@@ -87,8 +90,11 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> Str
87
90
let output = fs:: canonicalize ( & output) . unwrap_or ( output) ;
88
91
let relative = path_relative_from ( & lib, & output)
89
92
. 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
92
98
}
93
99
94
100
// 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> {
99
105
diff_paths ( path, base)
100
106
}
101
107
102
- fn minimize_rpaths ( rpaths : & [ String ] ) -> Vec < String > {
108
+ fn minimize_rpaths ( rpaths : & [ OsString ] ) -> Vec < OsString > {
103
109
let mut set = FxHashSet :: default ( ) ;
104
110
let mut minimized = Vec :: new ( ) ;
105
111
for rpath in rpaths {
0 commit comments