use command::Command;
use std::ffi::{OsStr, OsString};
use std::path::Path;
use crate::{command, cwd, env_var, set_host_rpath};
#[track_caller]
pub fn rustc() -> Rustc {
Rustc::new()
}
#[track_caller]
pub fn bare_rustc() -> Rustc {
Rustc::bare()
}
#[track_caller]
pub fn aux_build() -> Rustc {
Rustc::new_aux_build()
}
#[derive(Debug)]
#[must_use]
pub struct Rustc {
cmd: Command,
}
crate::impl_common_helpers!(Rustc);
#[track_caller]
fn setup_common() -> Command {
let rustc = env_var("RUSTC");
let mut cmd = Command::new(rustc);
set_host_rpath(&mut cmd);
cmd
}
impl Rustc {
#[track_caller]
pub fn new() -> Self {
let mut cmd = setup_common();
cmd.arg("-L").arg(cwd());
Self { cmd }
}
#[track_caller]
pub fn bare() -> Self {
let cmd = setup_common();
Self { cmd }
}
#[track_caller]
pub fn new_aux_build() -> Self {
let mut cmd = setup_common();
cmd.arg("--crate-type=lib");
Self { cmd }
}
pub fn cfg(&mut self, s: &str) -> &mut Self {
self.cmd.arg("--cfg");
self.cmd.arg(s);
self
}
pub fn opt(&mut self) -> &mut Self {
self.cmd.arg("-O");
self
}
pub fn opt_level(&mut self, option: &str) -> &mut Self {
self.cmd.arg(format!("-Copt-level={option}"));
self
}
pub fn metadata(&mut self, meta: &str) -> &mut Self {
self.cmd.arg(format!("-Cmetadata={meta}"));
self
}
pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
self.cmd.arg(format!("-Cextra-filename={suffix}"));
self
}
pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
let kinds = kinds.as_ref();
self.cmd.arg(format!("--emit={kinds}"));
self
}
pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
assert!(
!crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
"crate name cannot contain whitespace or path separators"
);
let path = path.as_ref().to_string_lossy();
self.cmd.arg("--extern");
self.cmd.arg(format!("{crate_name}={path}"));
self
}
pub fn remap_path_prefix<P: AsRef<Path>, P2: AsRef<Path>>(
&mut self,
from: P,
to: P2,
) -> &mut Self {
let from = from.as_ref().to_string_lossy();
let to = to.as_ref().to_string_lossy();
self.cmd.arg("--remap-path-prefix");
self.cmd.arg(format!("{from}={to}"));
self
}
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());
self
}
pub fn set_backtrace_level<R: AsRef<OsStr>>(&mut self, level: R) -> &mut Self {
self.cmd.env("RUST_BACKTRACE", level);
self
}
pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("-o");
self.cmd.arg(path.as_ref());
self
}
pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("--out-dir");
self.cmd.arg(path.as_ref());
self
}
pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self {
self.cmd.arg(format!("-Clinker-plugin-lto={option}"));
self
}
pub fn panic(&mut self, option: &str) -> &mut Self {
self.cmd.arg(format!("-Cpanic={option}"));
self
}
pub fn codegen_units(&mut self, units: usize) -> &mut Self {
self.cmd.arg(format!("-Ccodegen-units={units}"));
self
}
pub fn incremental<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
let mut arg = OsString::new();
arg.push("-Cincremental=");
arg.push(path.as_ref());
self.cmd.arg(&arg);
self
}
pub fn profile_generate<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
let mut arg = OsString::new();
arg.push("-Cprofile-generate=");
arg.push(path.as_ref());
self.cmd.arg(&arg);
self
}
pub fn profile_use<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
let mut arg = OsString::new();
arg.push("-Cprofile-use=");
arg.push(path.as_ref());
self.cmd.arg(&arg);
self
}
pub fn error_format(&mut self, format: &str) -> &mut Self {
self.cmd.arg(format!("--error-format={format}"));
self
}
pub fn json(&mut self, items: &str) -> &mut Self {
self.cmd.arg(format!("--json={items}"));
self
}
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
let target = target.as_ref();
self.cmd.arg(format!("--target={target}"));
self
}
pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
self.cmd.arg("--crate-type");
self.cmd.arg(crate_type);
self
}
pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("-L");
self.cmd.arg(path.as_ref());
self
}
pub fn sysroot<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("--sysroot");
self.cmd.arg(path.as_ref());
self
}
pub fn edition(&mut self, edition: &str) -> &mut Self {
self.cmd.arg("--edition");
self.cmd.arg(edition);
self
}
pub fn print(&mut self, request: &str) -> &mut Self {
self.cmd.arg("--print");
self.cmd.arg(request);
self
}
pub fn link_arg(&mut self, link_arg: &str) -> &mut Self {
self.cmd.arg(format!("-Clink-arg={link_arg}"));
self
}
pub fn link_args(&mut self, link_args: &str) -> &mut Self {
self.cmd.arg(format!("-Clink-args={link_args}"));
self
}
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.cmd.stdin(input);
self
}
pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
self.cmd.arg("--crate-name");
self.cmd.arg(name.as_ref());
self
}
pub fn linker(&mut self, linker: &str) -> &mut Self {
self.cmd.arg(format!("-Clinker={linker}"));
self
}
pub fn linker_flavor(&mut self, linker_flavor: &str) -> &mut Self {
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
self
}
}