Skip to content

Commit d1e7977

Browse files
committed
Add a cargo-zigbuild rustc subcommand
1 parent 6511aa1 commit d1e7977

File tree

3 files changed

+227
-0
lines changed

3 files changed

+227
-0
lines changed

src/bin/cargo-zigbuild.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use cargo_zigbuild::rustc::Rustc;
12
use cargo_zigbuild::{Build, Zig};
23
use clap::Parser;
34

@@ -11,6 +12,8 @@ use clap::Parser;
1112
pub enum Opt {
1213
#[clap(name = "zigbuild", alias = "build")]
1314
Build(Build),
15+
#[clap(name = "rustc")]
16+
Rustc(Rustc),
1417
#[clap(subcommand)]
1518
Zig(Zig),
1619
}
@@ -19,6 +22,7 @@ fn main() -> anyhow::Result<()> {
1922
let opt = Opt::parse();
2023
match opt {
2124
Opt::Build(build) => build.execute()?,
25+
Opt::Rustc(rustc) => rustc.execute()?,
2226
Opt::Zig(zig) => zig.execute()?,
2327
}
2428
Ok(())

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod build;
22
pub mod linux;
33
pub mod macos;
4+
pub mod rustc;
45
pub mod zig;
56

67
pub use build::Build;

src/rustc.rs

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
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

Comments
 (0)