Skip to main content

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    /// Minimum macOS version, overrides `MACOSX_DEPLOYMENT_TARGET`
28    #[arg(skip)]
29    pub macosx_deployment_target: Option<String>,
30}
31
32impl Install {
33    /// Create a new install
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    /// Execute `cargo install` command with zig as the linker
39    pub fn execute(&self) -> Result<()> {
40        let mut build = self.build_command()?;
41        let mut child = build.spawn().context("Failed to run cargo install")?;
42        let status = child
43            .wait()
44            .expect("Failed to wait on cargo install process");
45        if !status.success() {
46            process::exit(status.code().unwrap_or(1));
47        }
48        Ok(())
49    }
50
51    /// Generate cargo subcommand
52    pub fn build_command(&self) -> Result<Command> {
53        let mut install = self.cargo.command();
54        if !self.disable_zig_linker {
55            Zig::apply_command_env(
56                None,
57                !self.debug,
58                &self.cargo.common,
59                &mut install,
60                self.enable_zig_ar,
61                self.macosx_deployment_target.as_deref(),
62            )?;
63        }
64
65        Ok(install)
66    }
67}
68
69impl Deref for Install {
70    type Target = cargo_options::Install;
71
72    fn deref(&self) -> &Self::Target {
73        &self.cargo
74    }
75}
76
77impl DerefMut for Install {
78    fn deref_mut(&mut self) -> &mut Self::Target {
79        &mut self.cargo
80    }
81}
82
83impl From<cargo_options::Install> for Install {
84    fn from(cargo: cargo_options::Install) -> Self {
85        Self {
86            cargo,
87            ..Default::default()
88        }
89    }
90}