cli_xtask/subcommand/
dist_build_bin.rs

1use crate::{cargo, config::Config, Result, Run};
2
3/// Arguments definition of the `dist-build-bin` subcommand.
4#[cfg_attr(doc, doc = include_str!("../../doc/cargo-xtask-dist-build-bin.md"))]
5#[derive(Debug, Clone, Default, clap::Args)]
6#[non_exhaustive]
7pub struct DistBuildBin {
8    /// Target triple for the build
9    #[clap(long = "target")]
10    pub target_triple: Option<String>,
11    /// Use cross tool to build
12    #[clap(long)]
13    pub use_cross: bool,
14    /// Use cross if target is different from default target
15    #[clap(long)]
16    pub use_cross_if_needed: bool,
17}
18
19impl Run for DistBuildBin {
20    fn run(&self, config: &Config) -> Result<()> {
21        self.run(config)
22    }
23}
24
25impl DistBuildBin {
26    /// Runs the `dist-build-bin` subcommand.
27    #[tracing::instrument(name = "dist-build-bin", skip_all, err)]
28    pub fn run(&self, config: &Config) -> Result<()> {
29        tracing::info!("Building executables...");
30
31        let Self {
32            target_triple,
33            use_cross,
34            use_cross_if_needed,
35        } = self;
36        let config = config.dist()?;
37
38        let default_target = env!("DEFAULT_TARGET");
39        let target_triple = target_triple.as_deref();
40        let use_cross = *use_cross
41            || (*use_cross_if_needed
42                && target_triple.map(|t| t != default_target).unwrap_or(false));
43
44        let bin_dir = config.dist_working_directory(Some(target_triple.unwrap_or(default_target)));
45        crate::fs::create_or_cleanup_dir(&bin_dir)?;
46
47        let common_build_options = config.cargo_build_options();
48        for package in config.packages() {
49            let package_build_options = package.cargo_build_options();
50            for target in package.targets() {
51                let target_build_options = target.cargo_build_options();
52                let build_options = common_build_options
53                    .iter()
54                    .chain(package_build_options.iter())
55                    .chain(target_build_options.iter())
56                    .map(|s| s.as_str());
57                let artifacts = cargo::build(
58                    config.metadata(),
59                    Some(package.metadata()),
60                    Some(target.metadata()),
61                    Some("release"),
62                    build_options,
63                    use_cross,
64                    target_triple,
65                )?;
66                for src in artifacts {
67                    let src = src?;
68                    let dest = bin_dir.join(src.file_name().unwrap());
69                    crate::fs::copy(&src, dest)?;
70                }
71            }
72        }
73
74        Ok(())
75    }
76}