Skip to content

Commit b1e492b

Browse files
authored
Merge pull request #53 from messense/ar-ranlib
Add wrappers for `zig ar` and `zig ranlib`
2 parents dbbc593 + 9442761 commit b1e492b

File tree

1 file changed

+69
-12
lines changed

1 file changed

+69
-12
lines changed

src/zig.rs

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,35 @@ pub enum Zig {
3434
#[clap(takes_value = true, multiple_values = true)]
3535
args: Vec<String>,
3636
},
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+
},
3751
}
3852

3953
impl Zig {
4054
/// Execute the underlying zig command
4155
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+
}
4663

64+
/// Execute zig cc/c++ command
65+
pub fn execute_compiler(&self, cmd: &str, cmd_args: &[String]) -> Result<()> {
4766
let target = cmd_args
4867
.iter()
4968
.position(|x| x == "-target")
@@ -198,6 +217,20 @@ impl Zig {
198217
Ok(())
199218
}
200219

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+
201234
/// Build the zig command line
202235
pub fn command() -> Result<Command> {
203236
let (zig, zig_args) = Self::find_zig()?;
@@ -304,23 +337,28 @@ impl Zig {
304337
let host_target = &rustc_meta.host;
305338
for (parsed_target, raw_target) in rust_targets.iter().zip(&cargo.target) {
306339
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)?;
308341
if is_mingw_shell() {
309-
let zig_cc = zig_cc.to_slash_lossy();
342+
let zig_cc = zig_wrapper.cc.to_slash_lossy();
310343
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+
);
312348
cmd.env(
313349
format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()),
314350
&*zig_cc,
315351
);
316352
} 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);
319355
cmd.env(
320356
format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()),
321-
&zig_cc,
357+
&zig_wrapper.cc,
322358
);
323359
}
360+
cmd.env(format!("AR_{}", env_target), &zig_wrapper.ar);
361+
cmd.env(format!("RANLIB_{}", env_target), &zig_wrapper.ranlib);
324362

325363
Self::setup_os_deps(cargo)?;
326364

@@ -452,6 +490,15 @@ struct ZigEnv {
452490
lib_dir: String,
453491
}
454492

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+
455502
/// Prepare wrapper scripts for `zig cc` and `zig c++` and returns their paths
456503
///
457504
/// 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 {
461508
/// We create different files for different args because otherwise cargo might skip recompiling even
462509
/// if the linker target changed
463510
#[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> {
465512
let (rust_target, abi_suffix) = target.split_once('.').unwrap_or((target, ""));
466513
let abi_suffix = if abi_suffix.is_empty() {
467514
String::new()
@@ -566,7 +613,17 @@ pub fn prepare_zig_linker(target: &str) -> Result<(PathBuf, PathBuf)> {
566613
write_linker_wrapper(&zig_cc, "cc", &cc_args)?;
567614
write_linker_wrapper(&zig_cxx, "c++", &cc_args)?;
568615

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+
})
570627
}
571628

572629
/// Write a zig cc wrapper batch script for unix

0 commit comments

Comments
 (0)