|
| 1 | +use std::path::PathBuf; |
| 2 | +use std::process; |
| 3 | + |
| 4 | +use anyhow::{Context, Result}; |
| 5 | +use clap::Parser; |
| 6 | + |
| 7 | +use crate::build::Build; |
| 8 | + |
| 9 | +/// Compile a package, and pass extra options to the compiler |
| 10 | +/// with zig as the linker |
| 11 | +#[derive(Clone, Debug, Default, Parser)] |
| 12 | +#[clap( |
| 13 | + setting = clap::AppSettings::DeriveDisplayOrder, |
| 14 | + trailing_var_arg = true, |
| 15 | + after_help = "Run `cargo help rustc` for more detailed information." |
| 16 | +)] |
| 17 | +pub struct Rustc { |
| 18 | + /// Do not print cargo log messages |
| 19 | + #[clap(short = 'q', long)] |
| 20 | + pub quiet: bool, |
| 21 | + |
| 22 | + /// Package to build (see `cargo help pkgid`) |
| 23 | + #[clap(short = 'p', long = "package", value_name = "SPEC")] |
| 24 | + pub packages: Vec<String>, |
| 25 | + |
| 26 | + /// Number of parallel jobs, defaults to # of CPUs |
| 27 | + #[clap(short = 'j', long, value_name = "N")] |
| 28 | + pub jobs: Option<usize>, |
| 29 | + |
| 30 | + /// Build only this package's library |
| 31 | + #[clap(long)] |
| 32 | + pub lib: bool, |
| 33 | + |
| 34 | + /// Build only the specified binary |
| 35 | + #[clap(long, value_name = "NAME", multiple_values = true)] |
| 36 | + pub bin: Vec<String>, |
| 37 | + |
| 38 | + /// Build all binaries |
| 39 | + #[clap(long)] |
| 40 | + pub bins: bool, |
| 41 | + |
| 42 | + /// Build only the specified example |
| 43 | + #[clap(long, value_name = "NAME", multiple_values = true)] |
| 44 | + pub example: Vec<String>, |
| 45 | + |
| 46 | + /// Build all examples |
| 47 | + #[clap(long)] |
| 48 | + pub examples: bool, |
| 49 | + |
| 50 | + /// Build only the specified test target |
| 51 | + #[clap(long, value_name = "NAME", multiple_values = true)] |
| 52 | + pub test: Vec<String>, |
| 53 | + |
| 54 | + /// Build all tests |
| 55 | + #[clap(long)] |
| 56 | + pub tests: bool, |
| 57 | + |
| 58 | + /// Build only the specified bench target |
| 59 | + #[clap(long, value_name = "NAME", multiple_values = true)] |
| 60 | + pub bench: Vec<String>, |
| 61 | + |
| 62 | + /// Build all benches |
| 63 | + #[clap(long)] |
| 64 | + pub benches: bool, |
| 65 | + |
| 66 | + /// Build all targets |
| 67 | + #[clap(long)] |
| 68 | + pub all_targets: bool, |
| 69 | + |
| 70 | + /// Build artifacts in release mode, with optimizations |
| 71 | + #[clap(short = 'r', long)] |
| 72 | + pub release: bool, |
| 73 | + |
| 74 | + /// Build artifacts with the specified Cargo profile |
| 75 | + #[clap(long, value_name = "PROFILE-NAME")] |
| 76 | + pub profile: Option<String>, |
| 77 | + |
| 78 | + /// Space or comma separated list of features to activate |
| 79 | + #[clap(long, multiple_values = true)] |
| 80 | + pub features: Vec<String>, |
| 81 | + |
| 82 | + /// Activate all available features |
| 83 | + #[clap(long)] |
| 84 | + pub all_features: bool, |
| 85 | + |
| 86 | + /// Do not activate the `default` feature |
| 87 | + #[clap(long)] |
| 88 | + pub no_default_features: bool, |
| 89 | + |
| 90 | + /// Build for the target triple |
| 91 | + #[clap(long, value_name = "TRIPLE", env = "CARGO_BUILD_TARGET")] |
| 92 | + pub target: Option<String>, |
| 93 | + |
| 94 | + /// Output compiler information without compiling |
| 95 | + #[clap(long, value_name = "INFO")] |
| 96 | + pub print: Option<String>, |
| 97 | + |
| 98 | + /// Comma separated list of types of crates for the compiler to emit (unstable) |
| 99 | + #[clap( |
| 100 | + long, |
| 101 | + value_name = "CRATE-TYPE", |
| 102 | + use_value_delimiter = true, |
| 103 | + multiple_values = true |
| 104 | + )] |
| 105 | + pub crate_type: Vec<String>, |
| 106 | + |
| 107 | + /// Directory for all generated artifacts |
| 108 | + #[clap(long, value_name = "DIRECTORY", parse(from_os_str))] |
| 109 | + pub target_dir: Option<PathBuf>, |
| 110 | + |
| 111 | + /// Path to Cargo.toml |
| 112 | + #[clap(long, value_name = "PATH", parse(from_os_str))] |
| 113 | + pub manifest_path: Option<PathBuf>, |
| 114 | + |
| 115 | + /// Ignore `rust-version` specification in packages |
| 116 | + #[clap(long)] |
| 117 | + pub ignore_rust_version: bool, |
| 118 | + |
| 119 | + /// Error format |
| 120 | + #[clap(long, value_name = "FMT", multiple_values = true)] |
| 121 | + pub message_format: Vec<String>, |
| 122 | + |
| 123 | + /// Output build graph in JSON (unstable) |
| 124 | + #[clap(long)] |
| 125 | + pub unit_graph: bool, |
| 126 | + |
| 127 | + /// Outputs a future incompatibility report at the end of the build (unstable) |
| 128 | + #[clap(long)] |
| 129 | + pub future_incompat_report: bool, |
| 130 | + |
| 131 | + /// Use verbose output (-vv very verbose/build.rs output) |
| 132 | + #[clap(short = 'v', long, parse(from_occurrences), max_occurrences = 2)] |
| 133 | + pub verbose: usize, |
| 134 | + |
| 135 | + /// Coloring: auto, always, never |
| 136 | + #[clap(long, value_name = "WHEN")] |
| 137 | + pub color: Option<String>, |
| 138 | + |
| 139 | + /// Require Cargo.lock and cache are up to date |
| 140 | + #[clap(long)] |
| 141 | + pub frozen: bool, |
| 142 | + |
| 143 | + /// Require Cargo.lock is up to date |
| 144 | + #[clap(long)] |
| 145 | + pub locked: bool, |
| 146 | + |
| 147 | + /// Run without accessing the network |
| 148 | + #[clap(long)] |
| 149 | + pub offline: bool, |
| 150 | + |
| 151 | + /// Override a configuration value (unstable) |
| 152 | + #[clap(long, value_name = "KEY=VALUE", multiple_values = true)] |
| 153 | + pub config: Vec<String>, |
| 154 | + |
| 155 | + /// Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details |
| 156 | + #[clap(short = 'Z', value_name = "FLAG", multiple_values = true)] |
| 157 | + pub unstable_flags: Vec<String>, |
| 158 | + |
| 159 | + /// Rustc flags |
| 160 | + #[clap(takes_value = true, multiple_values = true)] |
| 161 | + pub args: Vec<String>, |
| 162 | +} |
| 163 | + |
| 164 | +impl Rustc { |
| 165 | + /// Execute `cargo rustc` command with zig as the linker |
| 166 | + pub fn execute(&self) -> Result<()> { |
| 167 | + let build = Build { |
| 168 | + quiet: self.quiet, |
| 169 | + packages: self.packages.clone(), |
| 170 | + jobs: self.jobs, |
| 171 | + lib: self.lib, |
| 172 | + bin: self.bin.clone(), |
| 173 | + bins: self.bins, |
| 174 | + example: self.example.clone(), |
| 175 | + examples: self.examples, |
| 176 | + test: self.test.clone(), |
| 177 | + tests: self.tests, |
| 178 | + bench: self.bench.clone(), |
| 179 | + benches: self.benches, |
| 180 | + all_targets: self.all_targets, |
| 181 | + release: self.release, |
| 182 | + profile: self.profile.clone(), |
| 183 | + features: self.features.clone(), |
| 184 | + all_features: self.all_features, |
| 185 | + no_default_features: self.no_default_features, |
| 186 | + target: self.target.clone(), |
| 187 | + target_dir: self.target_dir.clone(), |
| 188 | + manifest_path: self.manifest_path.clone(), |
| 189 | + ignore_rust_version: self.ignore_rust_version, |
| 190 | + message_format: self.message_format.clone(), |
| 191 | + unit_graph: self.unit_graph, |
| 192 | + future_incompat_report: self.future_incompat_report, |
| 193 | + verbose: self.verbose, |
| 194 | + color: self.color.clone(), |
| 195 | + frozen: self.frozen, |
| 196 | + locked: self.locked, |
| 197 | + offline: self.offline, |
| 198 | + config: self.config.clone(), |
| 199 | + unstable_flags: self.unstable_flags.clone(), |
| 200 | + ..Default::default() |
| 201 | + }; |
| 202 | + |
| 203 | + let mut rustc = build.build_command("rustc")?; |
| 204 | + |
| 205 | + if let Some(print) = self.print.as_ref() { |
| 206 | + rustc.arg("--print").arg(print); |
| 207 | + } |
| 208 | + if !self.crate_type.is_empty() { |
| 209 | + rustc.arg("--crate-type").arg(self.crate_type.join(",")); |
| 210 | + } |
| 211 | + if !self.args.is_empty() { |
| 212 | + rustc.arg("--").args(&self.args); |
| 213 | + } |
| 214 | + |
| 215 | + let mut child = rustc.spawn().context("Failed to run cargo rustc")?; |
| 216 | + let status = child.wait().expect("Failed to wait on cargo build process"); |
| 217 | + if !status.success() { |
| 218 | + process::exit(status.code().unwrap_or(1)); |
| 219 | + } |
| 220 | + Ok(()) |
| 221 | + } |
| 222 | +} |
0 commit comments