@@ -42,9 +42,11 @@ pub struct Context<'a, 'cfg: 'a> {
42
42
target : Option < Layout > ,
43
43
target_triple : String ,
44
44
host_dylib : Option < ( String , String ) > ,
45
+ host_staticlib : Option < ( String , String ) > ,
45
46
host_exe : String ,
46
47
package_set : & ' a PackageSet ,
47
48
target_dylib : Option < ( String , String ) > ,
49
+ target_staticlib : Option < ( String , String ) > ,
48
50
target_exe : String ,
49
51
profiles : & ' a Profiles ,
50
52
}
@@ -60,10 +62,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
60
62
profiles : & ' a Profiles ) -> CargoResult < Context < ' a , ' cfg > > {
61
63
let target = build_config. requested_target . clone ( ) ;
62
64
let target = target. as_ref ( ) . map ( |s| & s[ ..] ) ;
63
- let ( target_dylib, target_exe) = try!( Context :: filename_parts ( target,
65
+ let ( target_dylib, target_staticlib , target_exe) = try!( Context :: filename_parts ( target,
64
66
config) ) ;
65
- let ( host_dylib, host_exe) = if build_config. requested_target . is_none ( ) {
66
- ( target_dylib. clone ( ) , target_exe. clone ( ) )
67
+ let ( host_dylib, host_staticlib , host_exe) = if build_config. requested_target . is_none ( ) {
68
+ ( target_dylib. clone ( ) , target_staticlib . clone ( ) , target_exe. clone ( ) )
67
69
} else {
68
70
try!( Context :: filename_parts ( None , config) )
69
71
} ;
@@ -82,8 +84,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
82
84
package_set : deps,
83
85
config : config,
84
86
target_dylib : target_dylib,
87
+ target_staticlib : target_staticlib,
85
88
target_exe : target_exe,
86
89
host_dylib : host_dylib,
90
+ host_staticlib : host_staticlib,
87
91
host_exe : host_exe,
88
92
compilation : Compilation :: new ( config) ,
89
93
build_state : Arc :: new ( BuildState :: new ( & build_config, deps) ) ,
@@ -100,11 +104,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
100
104
/// Run `rustc` to discover the dylib prefix/suffix for the target
101
105
/// specified as well as the exe suffix
102
106
fn filename_parts ( target : Option < & str > , cfg : & Config )
103
- -> CargoResult < ( Option < ( String , String ) > , String ) > {
107
+ -> CargoResult < ( Option < ( String , String ) > , Option < ( String , String ) > , String ) > {
104
108
let mut process = util:: process ( cfg. rustc ( ) ) ;
105
109
process. arg ( "-" )
106
110
. arg ( "--crate-name" ) . arg ( "_" )
107
111
. arg ( "--crate-type" ) . arg ( "dylib" )
112
+ . arg ( "--crate-type" ) . arg ( "staticlib" )
108
113
. arg ( "--crate-type" ) . arg ( "bin" )
109
114
. arg ( "--print=file-names" )
110
115
. env_remove ( "RUST_LOG" ) ;
@@ -117,6 +122,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
117
122
let output = str:: from_utf8 ( & output. stdout ) . unwrap ( ) ;
118
123
let mut lines = output. lines ( ) ;
119
124
let nodylib = Regex :: new ( "unsupported crate type.*dylib" ) . unwrap ( ) ;
125
+ let nostaticlib = Regex :: new ( "unsupported crate type.*staticlib" ) . unwrap ( ) ;
120
126
let nobin = Regex :: new ( "unsupported crate type.*bin" ) . unwrap ( ) ;
121
127
let dylib = if nodylib. is_match ( error) {
122
128
None
@@ -127,14 +133,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
127
133
"rustc --print-file-name output has changed" ) ;
128
134
Some ( ( dylib_parts[ 0 ] . to_string ( ) , dylib_parts[ 1 ] . to_string ( ) ) )
129
135
} ;
136
+ let staticlib = if nostaticlib. is_match ( error) {
137
+ None
138
+ } else {
139
+ let staticlib_parts: Vec < & str > = lines. next ( ) . unwrap ( ) . trim ( )
140
+ . split ( '_' ) . collect ( ) ;
141
+ assert ! ( staticlib_parts. len( ) == 2 ,
142
+ "rustc --print-file-name output has changed" ) ;
143
+ Some ( ( staticlib_parts[ 0 ] . to_string ( ) , staticlib_parts[ 1 ] . to_string ( ) ) )
144
+ } ;
130
145
131
146
let exe_suffix = if nobin. is_match ( error) {
132
147
String :: new ( )
133
148
} else {
134
149
lines. next ( ) . unwrap ( ) . trim ( )
135
150
. split ( '_' ) . skip ( 1 ) . next ( ) . unwrap ( ) . to_string ( )
136
151
} ;
137
- Ok ( ( dylib, exe_suffix) )
152
+ Ok ( ( dylib, staticlib , exe_suffix) )
138
153
}
139
154
140
155
/// Prepare this context, ensuring that all filesystem directories are in
@@ -202,6 +217,22 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
202
217
}
203
218
}
204
219
220
+ /// Return the (prefix, suffix) pair for static libraries.
221
+ ///
222
+ /// If `plugin` is true, the pair corresponds to the host platform,
223
+ /// otherwise it corresponds to the target platform.
224
+ fn staticlib ( & self , kind : Kind ) -> CargoResult < ( & str , & str ) > {
225
+ let ( triple, pair) = if kind == Kind :: Host {
226
+ ( & self . config . rustc_info ( ) . host , & self . host_staticlib )
227
+ } else {
228
+ ( & self . target_triple , & self . target_staticlib )
229
+ } ;
230
+ match * pair {
231
+ None => bail ! ( "staticlib outputs are not supported for {}" , triple) ,
232
+ Some ( ( ref s1, ref s2) ) => Ok ( ( s1, s2) ) ,
233
+ }
234
+ }
235
+
205
236
/// Return the target triple which this context is targeting.
206
237
pub fn target_triple ( & self ) -> & str {
207
238
& self . target_triple
@@ -277,7 +308,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
277
308
}
278
309
LibKind :: Lib |
279
310
LibKind :: Rlib => ret. push ( format ! ( "lib{}.rlib" , stem) ) ,
280
- LibKind :: StaticLib => ret. push ( format ! ( "lib{}.a" , stem) ) ,
311
+ LibKind :: StaticLib => {
312
+ if let Ok ( ( prefix, suffix) ) = self . staticlib ( unit. kind ) {
313
+ ret. push ( format ! ( "{}{}{}" , prefix, stem, suffix) ) ;
314
+ }
315
+ }
281
316
}
282
317
}
283
318
}
0 commit comments