@@ -42,9 +42,11 @@ pub struct Context<'a, 'cfg: 'a> {
4242 target : Option < Layout > ,
4343 target_triple : String ,
4444 host_dylib : Option < ( String , String ) > ,
45+ host_staticlib : Option < ( String , String ) > ,
4546 host_exe : String ,
4647 package_set : & ' a PackageSet ,
4748 target_dylib : Option < ( String , String ) > ,
49+ target_staticlib : Option < ( String , String ) > ,
4850 target_exe : String ,
4951 profiles : & ' a Profiles ,
5052}
@@ -60,10 +62,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
6062 profiles : & ' a Profiles ) -> CargoResult < Context < ' a , ' cfg > > {
6163 let target = build_config. requested_target . clone ( ) ;
6264 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,
6466 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 ( ) )
6769 } else {
6870 try!( Context :: filename_parts ( None , config) )
6971 } ;
@@ -82,8 +84,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
8284 package_set : deps,
8385 config : config,
8486 target_dylib : target_dylib,
87+ target_staticlib : target_staticlib,
8588 target_exe : target_exe,
8689 host_dylib : host_dylib,
90+ host_staticlib : host_staticlib,
8791 host_exe : host_exe,
8892 compilation : Compilation :: new ( config) ,
8993 build_state : Arc :: new ( BuildState :: new ( & build_config, deps) ) ,
@@ -100,11 +104,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
100104 /// Run `rustc` to discover the dylib prefix/suffix for the target
101105 /// specified as well as the exe suffix
102106 fn filename_parts ( target : Option < & str > , cfg : & Config )
103- -> CargoResult < ( Option < ( String , String ) > , String ) > {
107+ -> CargoResult < ( Option < ( String , String ) > , Option < ( String , String ) > , String ) > {
104108 let mut process = util:: process ( cfg. rustc ( ) ) ;
105109 process. arg ( "-" )
106110 . arg ( "--crate-name" ) . arg ( "_" )
107111 . arg ( "--crate-type" ) . arg ( "dylib" )
112+ . arg ( "--crate-type" ) . arg ( "staticlib" )
108113 . arg ( "--crate-type" ) . arg ( "bin" )
109114 . arg ( "--print=file-names" )
110115 . env_remove ( "RUST_LOG" ) ;
@@ -117,6 +122,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
117122 let output = str:: from_utf8 ( & output. stdout ) . unwrap ( ) ;
118123 let mut lines = output. lines ( ) ;
119124 let nodylib = Regex :: new ( "unsupported crate type.*dylib" ) . unwrap ( ) ;
125+ let nostaticlib = Regex :: new ( "unsupported crate type.*staticlib" ) . unwrap ( ) ;
120126 let nobin = Regex :: new ( "unsupported crate type.*bin" ) . unwrap ( ) ;
121127 let dylib = if nodylib. is_match ( error) {
122128 None
@@ -127,14 +133,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
127133 "rustc --print-file-name output has changed" ) ;
128134 Some ( ( dylib_parts[ 0 ] . to_string ( ) , dylib_parts[ 1 ] . to_string ( ) ) )
129135 } ;
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+ } ;
130145
131146 let exe_suffix = if nobin. is_match ( error) {
132147 String :: new ( )
133148 } else {
134149 lines. next ( ) . unwrap ( ) . trim ( )
135150 . split ( '_' ) . skip ( 1 ) . next ( ) . unwrap ( ) . to_string ( )
136151 } ;
137- Ok ( ( dylib, exe_suffix) )
152+ Ok ( ( dylib, staticlib , exe_suffix) )
138153 }
139154
140155 /// Prepare this context, ensuring that all filesystem directories are in
@@ -202,6 +217,22 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
202217 }
203218 }
204219
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+
205236 /// Return the target triple which this context is targeting.
206237 pub fn target_triple ( & self ) -> & str {
207238 & self . target_triple
@@ -277,7 +308,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
277308 }
278309 LibKind :: Lib |
279310 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+ }
281316 }
282317 }
283318 }
0 commit comments