@@ -34,16 +34,35 @@ pub enum Zig {
34
34
#[ clap( takes_value = true , multiple_values = true ) ]
35
35
args : Vec < String > ,
36
36
} ,
37
+ /// `zig ar` wrapper
38
+ #[ clap( name = "ar" , trailing_var_arg = true ) ]
39
+ Ar {
40
+ /// `zig ar` arguments
41
+ #[ clap( takes_value = true , multiple_values = true ) ]
42
+ args : Vec < String > ,
43
+ } ,
44
+ /// `zig ranlib` wrapper
45
+ #[ clap( name = "ranlib" , trailing_var_arg = true ) ]
46
+ Ranlib {
47
+ /// `zig ranlib` arguments
48
+ #[ clap( takes_value = true , multiple_values = true ) ]
49
+ args : Vec < String > ,
50
+ } ,
37
51
}
38
52
39
53
impl Zig {
40
54
/// Execute the underlying zig command
41
55
pub fn execute ( & self ) -> Result < ( ) > {
42
- let ( cmd, cmd_args) = match self {
43
- Zig :: Cc { args } => ( "cc" , args) ,
44
- Zig :: Cxx { args } => ( "c++" , args) ,
45
- } ;
56
+ match self {
57
+ Zig :: Cc { args } => self . execute_compiler ( "cc" , args) ,
58
+ Zig :: Cxx { args } => self . execute_compiler ( "c++" , args) ,
59
+ Zig :: Ar { args } => self . execute_tool ( "ar" , args) ,
60
+ Zig :: Ranlib { args } => self . execute_compiler ( "ranlib" , args) ,
61
+ }
62
+ }
46
63
64
+ /// Execute zig cc/c++ command
65
+ pub fn execute_compiler ( & self , cmd : & str , cmd_args : & [ String ] ) -> Result < ( ) > {
47
66
let target = cmd_args
48
67
. iter ( )
49
68
. position ( |x| x == "-target" )
@@ -198,6 +217,20 @@ impl Zig {
198
217
Ok ( ( ) )
199
218
}
200
219
220
+ /// Execute zig ar/ranlib command
221
+ pub fn execute_tool ( & self , cmd : & str , cmd_args : & [ String ] ) -> Result < ( ) > {
222
+ let mut child = Self :: command ( ) ?
223
+ . arg ( cmd)
224
+ . args ( cmd_args)
225
+ . spawn ( )
226
+ . with_context ( || format ! ( "Failed to run `zig {}`" , cmd) ) ?;
227
+ let status = child. wait ( ) . expect ( "Failed to wait on zig child process" ) ;
228
+ if !status. success ( ) {
229
+ process:: exit ( status. code ( ) . unwrap_or ( 1 ) ) ;
230
+ }
231
+ Ok ( ( ) )
232
+ }
233
+
201
234
/// Build the zig command line
202
235
pub fn command ( ) -> Result < Command > {
203
236
let ( zig, zig_args) = Self :: find_zig ( ) ?;
@@ -304,23 +337,28 @@ impl Zig {
304
337
let host_target = & rustc_meta. host ;
305
338
for ( parsed_target, raw_target) in rust_targets. iter ( ) . zip ( & cargo. target ) {
306
339
let env_target = parsed_target. replace ( '-' , "_" ) ;
307
- let ( zig_cc , zig_cxx ) = prepare_zig_linker ( raw_target) ?;
340
+ let zig_wrapper = prepare_zig_linker ( raw_target) ?;
308
341
if is_mingw_shell ( ) {
309
- let zig_cc = zig_cc . to_slash_lossy ( ) ;
342
+ let zig_cc = zig_wrapper . cc . to_slash_lossy ( ) ;
310
343
cmd. env ( format ! ( "CC_{}" , env_target) , & * zig_cc) ;
311
- cmd. env ( format ! ( "CXX_{}" , env_target) , & * zig_cxx. to_slash_lossy ( ) ) ;
344
+ cmd. env (
345
+ format ! ( "CXX_{}" , env_target) ,
346
+ & * zig_wrapper. cxx . to_slash_lossy ( ) ,
347
+ ) ;
312
348
cmd. env (
313
349
format ! ( "CARGO_TARGET_{}_LINKER" , env_target. to_uppercase( ) ) ,
314
350
& * zig_cc,
315
351
) ;
316
352
} else {
317
- cmd. env ( format ! ( "CC_{}" , env_target) , & zig_cc ) ;
318
- cmd. env ( format ! ( "CXX_{}" , env_target) , & zig_cxx ) ;
353
+ cmd. env ( format ! ( "CC_{}" , env_target) , & zig_wrapper . cc ) ;
354
+ cmd. env ( format ! ( "CXX_{}" , env_target) , & zig_wrapper . cxx ) ;
319
355
cmd. env (
320
356
format ! ( "CARGO_TARGET_{}_LINKER" , env_target. to_uppercase( ) ) ,
321
- & zig_cc ,
357
+ & zig_wrapper . cc ,
322
358
) ;
323
359
}
360
+ cmd. env ( format ! ( "AR_{}" , env_target) , & zig_wrapper. ar ) ;
361
+ cmd. env ( format ! ( "RANLIB_{}" , env_target) , & zig_wrapper. ranlib ) ;
324
362
325
363
Self :: setup_os_deps ( cargo) ?;
326
364
@@ -452,6 +490,15 @@ struct ZigEnv {
452
490
lib_dir : String ,
453
491
}
454
492
493
+ /// zig wrapper paths
494
+ #[ derive( Debug , Clone ) ]
495
+ pub struct ZigWrapper {
496
+ pub cc : PathBuf ,
497
+ pub cxx : PathBuf ,
498
+ pub ar : PathBuf ,
499
+ pub ranlib : PathBuf ,
500
+ }
501
+
455
502
/// Prepare wrapper scripts for `zig cc` and `zig c++` and returns their paths
456
503
///
457
504
/// We want to use `zig cc` as linker and c compiler. We want to call `python -m ziglang cc`, but
@@ -461,7 +508,7 @@ struct ZigEnv {
461
508
/// We create different files for different args because otherwise cargo might skip recompiling even
462
509
/// if the linker target changed
463
510
#[ allow( clippy:: blocks_in_if_conditions) ]
464
- pub fn prepare_zig_linker ( target : & str ) -> Result < ( PathBuf , PathBuf ) > {
511
+ pub fn prepare_zig_linker ( target : & str ) -> Result < ZigWrapper > {
465
512
let ( rust_target, abi_suffix) = target. split_once ( '.' ) . unwrap_or ( ( target, "" ) ) ;
466
513
let abi_suffix = if abi_suffix. is_empty ( ) {
467
514
String :: new ( )
@@ -566,7 +613,17 @@ pub fn prepare_zig_linker(target: &str) -> Result<(PathBuf, PathBuf)> {
566
613
write_linker_wrapper ( & zig_cc, "cc" , & cc_args) ?;
567
614
write_linker_wrapper ( & zig_cxx, "c++" , & cc_args) ?;
568
615
569
- Ok ( ( zig_cc, zig_cxx) )
616
+ let zig_ar = zig_linker_dir. join ( format ! ( "zigar.{}" , file_ext) ) ;
617
+ let zig_ranlib = zig_linker_dir. join ( format ! ( "zigranlib.{}" , file_ext) ) ;
618
+ write_linker_wrapper ( & zig_ar, "ar" , "" ) ?;
619
+ write_linker_wrapper ( & zig_ranlib, "ranlib" , "" ) ?;
620
+
621
+ Ok ( ZigWrapper {
622
+ cc : zig_cc,
623
+ cxx : zig_cxx,
624
+ ar : zig_ar,
625
+ ranlib : zig_ranlib,
626
+ } )
570
627
}
571
628
572
629
/// Write a zig cc wrapper batch script for unix
0 commit comments