cargo_zigbuild/
install.rs

1use std::ops::{Deref, DerefMut};
2use std::process::{self, Command};
3
4use anyhow::{Context, Result};
5use clap::Parser;
6
7use crate::zig::Zig;
8
9/// Install a Rust binary using zig as the linker. Default location is $HOME/.cargo/bin
10#[derive(Clone, Debug, Default, Parser)]
11#[command(
12    after_help = "Run `cargo help install` for more detailed information.",
13    display_order = 1
14)]
15pub struct Install {
16    #[command(flatten)]
17    pub cargo: cargo_options::Install,
18
19    /// Disable zig linker
20    #[arg(skip)]
21    pub disable_zig_linker: bool,
22
23    /// Enable zig ar
24    #[arg(skip)]
25    pub enable_zig_ar: bool,
26}
27
28impl Install {
29    /// Create a new install
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    /// Execute `cargo install` command with zig as the linker
35    pub fn execute(&self) -> Result<()> {
36        let mut build = self.build_command()?;
37        let mut child = build.spawn().context("Failed to run cargo install")?;
38        let status = child
39            .wait()
40            .expect("Failed to wait on cargo install process");
41        if !status.success() {
42            process::exit(status.code().unwrap_or(1));
43        }
44        Ok(())
45    }
46
47    /// Generate cargo subcommand
48    pub fn build_command(&self) -> Result<Command> {
49        let mut install = self.cargo.command();
50        if !self.disable_zig_linker {
51            Zig::apply_command_env(
52                None,
53                !self.debug,
54                &self.cargo.common,
55                &mut install,
56                self.enable_zig_ar,
57            )?;
58        }
59
60        Ok(install)
61    }
62}
63
64impl Deref for Install {
65    type Target = cargo_options::Install;
66
67    fn deref(&self) -> &Self::Target {
68        &self.cargo
69    }
70}
71
72impl DerefMut for Install {
73    fn deref_mut(&mut self) -> &mut Self::Target {
74        &mut self.cargo
75    }
76}
77
78impl From<cargo_options::Install> for Install {
79    fn from(cargo: cargo_options::Install) -> Self {
80        Self {
81            cargo,
82            ..Default::default()
83        }
84    }
85}