use serde::{Deserialize, Serialize};
use std::{
env::{args, vars},
path::PathBuf,
};
pub const DX_RUSTC_WRAPPER_ENV_VAR: &str = "DX_RUSTC";
pub fn is_wrapping_rustc() -> bool {
std::env::var(DX_RUSTC_WRAPPER_ENV_VAR).is_ok()
}
#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Args {
pub args: Vec<String>,
pub envs: Vec<(String, String)>,
pub link_args: Vec<String>,
}
pub async fn run_rustc() {
if std::env::args()
.take(5)
.any(|arg| arg.ends_with(".o") || arg == "-flavor" || arg.starts_with("@"))
{
return crate::link::LinkAction::from_env()
.expect("Linker action not found")
.run_link()
.await;
}
let var_file: PathBuf = std::env::var(DX_RUSTC_WRAPPER_ENV_VAR)
.expect("DX_RUSTC not set")
.into();
let mut rustc_args = Args {
args: args().skip(1).collect::<Vec<_>>(),
envs: vars().collect::<_>(),
link_args: Default::default(),
};
if rustc_args
.args
.iter()
.skip_while(|arg| *arg != "--crate-name")
.nth(1)
.is_some_and(|name| name != "___")
{
rustc_args
.envs
.retain_mut(|(key, _)| key != "CARGO_MAKEFLAGS");
std::fs::create_dir_all(var_file.parent().expect("Failed to get parent dir"))
.expect("Failed to create parent dir");
std::fs::write(
&var_file,
serde_json::to_string(&rustc_args).expect("Failed to serialize rustc args"),
)
.expect("Failed to write rustc args to file");
}
let rustc = std::process::Command::new("rustc")
.args(rustc_args.args.iter().skip(1))
.envs(rustc_args.envs)
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit())
.current_dir(std::env::current_dir().expect("Failed to get current dir"))
.status();
std::process::exit(rustc.unwrap().code().unwrap())
}