diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 654e03d0c3c7f..e4c512f9df0e4 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) - Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false. - Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false. +- Add a `RUSTC_EMIT` environment variable which passes on `--emit` to `rustc`. [#108365](https://github.com/rust-lang/rust/pull/108365) ## [Version 2] - 2020-09-25 diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 9611c866df599..a4f493a93bf11 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -18,6 +18,7 @@ include!("../dylib_util.rs"); use std::env; +use std::ffi::OsStr; use std::path::PathBuf; use std::process::{Child, Command}; use std::str::FromStr; @@ -70,6 +71,46 @@ fn main() { cmd.arg("-Ztime-passes"); } } + + if let Some(crate_targets) = env::var_os("RUSTC_EMIT") { + let formats: Vec<&str> = crate_targets + .to_str() + .unwrap() + .split(';') + .filter_map(|target| { + let mut iter = target.split('='); + let krate = iter.next().unwrap(); + let formats = iter.next().unwrap(); + assert!(iter.next().is_none(), "Invalid format for RUSTC_EMIT"); + (krate.trim() == crate_name || krate.trim() == "*").then_some(formats) + }) + .flat_map(|formats| formats.split(',').map(|format| format.trim())) + .collect(); + + if !formats.is_empty() { + let dir = PathBuf::from( + env::var_os("RUSTC_EMIT_DIR").expect("RUSTC_EMIT_DIR was not set"), + ); + std::fs::create_dir_all(&dir).expect("unable to create dump directory"); + + for format in formats { + let ext = match format { + "llvm-ir" => "ll", + "llvm-bc" => "bc", + "asm" => { + if target.map_or(false, |target| target.starts_with("x86")) { + cmd.arg("-Cllvm-args=-x86-asm-syntax=intel"); + } + "s" + } + _ => format, + }; + let mut arg = OsStr::new(&format!("--emit={format}=")).to_owned(); + arg.push(dir.join(format!("{crate_name}.{ext}")).as_os_str()); + cmd.arg(arg); + } + } + } } // Print backtrace in case of ICE diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bb07ca1908e1c..1ec03911ccdc6 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1183,6 +1183,11 @@ impl<'a> Builder<'a> { let mut cargo = self.bare_cargo(compiler, mode, target, cmd); let out_dir = self.stage_out(compiler, mode); + cargo.env( + "RUSTC_EMIT_DIR", + self.out.join(target.triple).join("emit").join(out_dir.file_name().unwrap()), + ); + // Codegen backends are not yet tracked by -Zbinary-dep-depinfo, // so we need to explicitly clear out if they've been updated. for backend in self.codegen_backends(compiler) {