9
9
// except according to those terms.
10
10
11
11
12
- use driver:: session:: Session ;
13
- use metadata:: cstore;
14
- use metadata:: filesearch;
15
- use util:: fs;
16
-
17
12
use std:: collections:: HashSet ;
18
13
use std:: os;
14
+ use std:: io:: IoError ;
19
15
use syntax:: abi;
20
-
21
- fn not_win32 ( os : abi:: Os ) -> bool {
22
- os != abi:: OsWin32
16
+ use syntax:: ast;
17
+
18
+ pub struct RPathConfig < ' a > {
19
+ pub os : abi:: Os ,
20
+ pub used_crates : Vec < ( ast:: CrateNum , Option < Path > ) > ,
21
+ pub out_filename : Path ,
22
+ pub get_install_prefix_lib_path : ||: ' a -> Path ,
23
+ pub realpath: |& Path |: ' a -> Result <Path , IoError >
23
24
}
24
25
25
- pub fn get_rpath_flags ( sess : & Session , out_filename : & Path ) -> Vec < String > {
26
- let os = sess. targ_cfg . os ;
26
+ pub fn get_rpath_flags( config: RPathConfig ) -> Vec < String > {
27
27
28
28
// No rpath on windows
29
- if os == abi:: OsWin32 {
29
+ if config . os == abi:: OsWin32 {
30
30
return Vec :: new ( ) ;
31
31
}
32
32
33
33
let mut flags = Vec :: new ( ) ;
34
34
35
- if sess . targ_cfg . os == abi:: OsFreebsd {
35
+ if config . os == abi:: OsFreebsd {
36
36
flags. push_all ( [ "-Wl,-rpath,/usr/local/lib/gcc46" . to_string ( ) ,
37
37
"-Wl,-rpath,/usr/local/lib/gcc44" . to_string ( ) ,
38
38
"-Wl,-z,origin" . to_string ( ) ] ) ;
39
39
}
40
40
41
41
debug ! ( "preparing the RPATH!" ) ;
42
42
43
- let sysroot = sess. sysroot ( ) ;
44
- let output = out_filename;
45
- let libs = sess. cstore . get_used_crates ( cstore:: RequireDynamic ) ;
43
+ let libs = config. used_crates . clone ( ) ;
46
44
let libs = libs. move_iter ( ) . filter_map ( |( _, l) | {
47
45
l. map ( |p| p. clone ( ) )
48
46
} ) . collect :: < Vec < _ > > ( ) ;
49
47
50
- let rpaths = get_rpaths ( os,
51
- sysroot,
52
- output,
53
- libs. as_slice ( ) ,
54
- sess. opts . target_triple . as_slice ( ) ) ;
48
+ let rpaths = get_rpaths ( config, libs. as_slice ( ) ) ;
55
49
flags. push_all ( rpaths_to_flags ( rpaths. as_slice ( ) ) . as_slice ( ) ) ;
56
50
flags
57
51
}
58
52
59
- pub fn rpaths_to_flags ( rpaths : & [ String ] ) -> Vec < String > {
53
+ fn rpaths_to_flags ( rpaths : & [ String ] ) -> Vec < String > {
60
54
let mut ret = Vec :: new ( ) ;
61
55
for rpath in rpaths. iter ( ) {
62
56
ret. push ( format ! ( "-Wl,-rpath,{}" , ( * rpath) . as_slice( ) ) ) ;
63
57
}
64
58
return ret;
65
59
}
66
60
67
- fn get_rpaths ( os : abi:: Os ,
68
- sysroot : & Path ,
69
- output : & Path ,
70
- libs : & [ Path ] ,
71
- target_triple : & str ) -> Vec < String > {
72
- debug ! ( "sysroot: {}" , sysroot. display( ) ) ;
73
- debug ! ( "output: {}" , output. display( ) ) ;
61
+ fn get_rpaths ( mut config : RPathConfig ,
62
+ libs : & [ Path ] ) -> Vec < String > {
63
+ debug ! ( "output: {}" , config. out_filename. display( ) ) ;
74
64
debug ! ( "libs:" ) ;
75
65
for libpath in libs. iter ( ) {
76
66
debug ! ( " {}" , libpath. display( ) ) ;
77
67
}
78
- debug ! ( "target_triple: {}" , target_triple) ;
79
68
80
69
// Use relative paths to the libraries. Binaries can be moved
81
70
// as long as they maintain the relative relationship to the
82
71
// crates they depend on.
83
- let rel_rpaths = get_rpaths_relative_to_output ( os , output , libs) ;
72
+ let rel_rpaths = get_rpaths_relative_to_output ( & mut config , libs) ;
84
73
85
74
// And a final backup rpath to the global library location.
86
- let fallback_rpaths = vec ! ( get_install_prefix_rpath( sysroot , target_triple ) ) ;
75
+ let fallback_rpaths = vec ! ( get_install_prefix_rpath( config ) ) ;
87
76
88
77
fn log_rpaths ( desc : & str , rpaths : & [ String ] ) {
89
78
debug ! ( "{} rpaths:" , desc) ;
@@ -103,31 +92,28 @@ fn get_rpaths(os: abi::Os,
103
92
return rpaths;
104
93
}
105
94
106
- fn get_rpaths_relative_to_output ( os : abi:: Os ,
107
- output : & Path ,
95
+ fn get_rpaths_relative_to_output ( config : & mut RPathConfig ,
108
96
libs : & [ Path ] ) -> Vec < String > {
109
- libs. iter ( ) . map ( |a| get_rpath_relative_to_output ( os , output , a) ) . collect ( )
97
+ libs. iter ( ) . map ( |a| get_rpath_relative_to_output ( config , a) ) . collect ( )
110
98
}
111
99
112
- pub fn get_rpath_relative_to_output ( os : abi:: Os ,
113
- output : & Path ,
114
- lib : & Path )
115
- -> String {
100
+ fn get_rpath_relative_to_output ( config : & mut RPathConfig ,
101
+ lib : & Path ) -> String {
116
102
use std:: os;
117
103
118
- assert ! ( not_win32 ( os ) ) ;
104
+ assert ! ( config . os != abi :: OsWin32 ) ;
119
105
120
106
// Mac doesn't appear to support $ORIGIN
121
- let prefix = match os {
107
+ let prefix = match config . os {
122
108
abi:: OsAndroid | abi:: OsLinux | abi:: OsFreebsd
123
109
=> "$ORIGIN" ,
124
110
abi:: OsMacos => "@loader_path" ,
125
111
abi:: OsWin32 | abi:: OsiOS => unreachable ! ( )
126
112
} ;
127
113
128
- let mut lib = fs :: realpath ( & os:: make_absolute ( lib) ) . unwrap ( ) ;
114
+ let mut lib = ( config . realpath ) ( & os:: make_absolute ( lib) ) . unwrap ( ) ;
129
115
lib. pop ( ) ;
130
- let mut output = fs :: realpath ( & os:: make_absolute ( output ) ) . unwrap ( ) ;
116
+ let mut output = ( config . realpath ) ( & os:: make_absolute ( & config . out_filename ) ) . unwrap ( ) ;
131
117
output. pop ( ) ;
132
118
let relative = lib. path_relative_from ( & output) ;
133
119
let relative = relative. expect ( "could not create rpath relative to output" ) ;
@@ -137,18 +123,14 @@ pub fn get_rpath_relative_to_output(os: abi::Os,
137
123
relative. as_str( ) . expect( "non-utf8 component in path" ) )
138
124
}
139
125
140
- pub fn get_install_prefix_rpath ( sysroot : & Path , target_triple : & str ) -> String {
141
- let install_prefix = option_env ! ( "CFG_PREFIX" ) . expect ( "CFG_PREFIX" ) ;
142
-
143
- let tlib = filesearch:: relative_target_lib_path ( sysroot, target_triple) ;
144
- let mut path = Path :: new ( install_prefix) ;
145
- path. push ( & tlib) ;
126
+ fn get_install_prefix_rpath ( config : RPathConfig ) -> String {
127
+ let path = ( config. get_install_prefix_lib_path ) ( ) ;
146
128
let path = os:: make_absolute ( & path) ;
147
129
// FIXME (#9639): This needs to handle non-utf8 paths
148
130
path. as_str ( ) . expect ( "non-utf8 component in rpath" ) . to_string ( )
149
131
}
150
132
151
- pub fn minimize_rpaths ( rpaths : & [ String ] ) -> Vec < String > {
133
+ fn minimize_rpaths ( rpaths : & [ String ] ) -> Vec < String > {
152
134
let mut set = HashSet :: new ( ) ;
153
135
let mut minimized = Vec :: new ( ) ;
154
136
for rpath in rpaths. iter ( ) {
@@ -161,10 +143,9 @@ pub fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
161
143
162
144
#[ cfg( unix, test) ]
163
145
mod test {
164
- use back :: rpath :: get_install_prefix_rpath ;
165
- use back :: rpath :: { minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output} ;
146
+ use super :: { RPathConfig } ;
147
+ use super :: { minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output} ;
166
148
use syntax:: abi;
167
- use metadata:: filesearch;
168
149
169
150
#[ test]
170
151
fn test_rpaths_to_flags ( ) {
@@ -177,27 +158,6 @@ mod test {
177
158
"-Wl,-rpath,path2" . to_string( ) ) ) ;
178
159
}
179
160
180
- #[ test]
181
- fn test_prefix_rpath ( ) {
182
- let sysroot = filesearch:: get_or_default_sysroot ( ) ;
183
- let res = get_install_prefix_rpath ( & sysroot, "triple" ) ;
184
- let mut d = Path :: new ( ( option_env ! ( "CFG_PREFIX" ) ) . expect ( "CFG_PREFIX" ) ) ;
185
- d. push ( "lib" ) ;
186
- d. push ( filesearch:: rustlibdir ( ) ) ;
187
- d. push ( "triple/lib" ) ;
188
- debug ! ( "test_prefix_path: {} vs. {}" ,
189
- res,
190
- d. display( ) ) ;
191
- assert ! ( res. as_bytes( ) . ends_with( d. as_vec( ) ) ) ;
192
- }
193
-
194
- #[ test]
195
- fn test_prefix_rpath_abs ( ) {
196
- let sysroot = filesearch:: get_or_default_sysroot ( ) ;
197
- let res = get_install_prefix_rpath ( & sysroot, "triple" ) ;
198
- assert ! ( Path :: new( res) . is_absolute( ) ) ;
199
- }
200
-
201
161
#[ test]
202
162
fn test_minimize1 ( ) {
203
163
let res = minimize_rpaths ( [
@@ -237,28 +197,42 @@ mod test {
237
197
#[ cfg( target_os = "linux" ) ]
238
198
#[ cfg( target_os = "android" ) ]
239
199
fn test_rpath_relative ( ) {
240
- let o = abi:: OsLinux ;
241
- let res = get_rpath_relative_to_output ( o,
242
- & Path :: new ( "bin/rustc" ) , & Path :: new ( "lib/libstd.so" ) ) ;
243
- assert_eq ! ( res. as_slice( ) , "$ORIGIN/../lib" ) ;
200
+ let config = & mut RPathConfig {
201
+ os : abi:: OsLinux ,
202
+ used_crates : Vec :: new ( ) ,
203
+ out_filename : Path :: new ( "bin/rustc" ) ,
204
+ get_install_prefix_lib_path : || fail ! ( ) ,
205
+ realpath : |p| Ok ( p. clone ( ) )
206
+ } ;
207
+ let res = get_rpath_relative_to_output ( config, & Path :: new ( "lib/libstd.so" ) ) ;
208
+ assert_eq ! ( res. as_slice( ) , "$ORIGIN/../lib" ) ;
244
209
}
245
210
246
211
#[ test]
247
212
#[ cfg( target_os = "freebsd" ) ]
248
213
fn test_rpath_relative ( ) {
249
- let o = abi:: OsFreebsd ;
250
- let res = get_rpath_relative_to_output ( o,
251
- & Path :: new ( "bin/rustc" ) , & Path :: new ( "lib/libstd.so" ) ) ;
214
+ let config = & mut RPathConfig {
215
+ os : abi:: OsFreebsd ,
216
+ used_crates : Vec :: new ( ) ,
217
+ out_filename : Path :: new ( "bin/rustc" ) ,
218
+ get_install_prefix_lib_path : || fail ! ( ) ,
219
+ realpath : |p| Ok ( p. clone ( ) )
220
+ } ;
221
+ let res = get_rpath_relative_to_output ( config, & Path :: new ( "lib/libstd.so" ) ) ;
252
222
assert_eq ! ( res. as_slice( ) , "$ORIGIN/../lib" ) ;
253
223
}
254
224
255
225
#[ test]
256
226
#[ cfg( target_os = "macos" ) ]
257
227
fn test_rpath_relative ( ) {
258
- let o = abi:: OsMacos ;
259
- let res = get_rpath_relative_to_output ( o,
260
- & Path :: new ( "bin/rustc" ) ,
261
- & Path :: new ( "lib/libstd.so" ) ) ;
228
+ let config = & mut RPathConfig {
229
+ os : abi:: OsMacos ,
230
+ used_crates : Vec :: new ( ) ,
231
+ out_filename : Path :: new ( "bin/rustc" ) ,
232
+ get_install_prefix_lib_path : || fail ! ( ) ,
233
+ realpath : |p| p. clone ( )
234
+ } ;
235
+ let res = get_rpath_relative_to_output ( config, & Path :: new ( "lib/libstd.so" ) ) ;
262
236
assert_eq ! ( res. as_slice( ) , "@loader_path/../lib" ) ;
263
237
}
264
238
}
0 commit comments