From 305f5263f933d5d730f2bba5f0d43d9f9006361d Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Wed, 21 Jun 2017 10:04:21 -0600 Subject: [PATCH] Make rustc errors colorful. Rustbuild passes --message-format=json to Cargo to learn about the dependencies for a given build, which then makes Cargo steal the stderr/stdout for the compiler process, leading to non colorful output. To avoid this, detection of stderr being a tty is added to rustbuild, and an environment variable is used to communicate with the rustc shim. --- src/bootstrap/bin/rustc.rs | 9 +++++++++ src/bootstrap/compile.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 12152fc4399..8c6eaee24f2 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -236,6 +236,15 @@ fn main() { } } + let color = match env::var("RUSTC_COLOR") { + Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"), + Err(_) => 0, + }; + + if color != 0 { + cmd.arg("--color=always"); + } + if verbose > 1 { writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap(); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9a07e8a8b10..f92a199fa3f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -477,11 +477,43 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) { build.run(&mut cargo); } + +// Avoiding a dependency on winapi to keep compile times down +#[cfg(unix)] +fn stderr_isatty() -> bool { + use libc; + unsafe { libc::isatty(libc::STDERR_FILENO) != 0 } +} +#[cfg(windows)] +fn stderr_isatty() -> bool { + type DWORD = u32; + type BOOL = i32; + type HANDLE = *mut u8; + const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; + extern "system" { + fn GetStdHandle(which: DWORD) -> HANDLE; + fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL; + } + unsafe { + let handle = GetStdHandle(STD_ERROR_HANDLE); + let mut out = 0; + GetConsoleMode(handle, &mut out) != 0 + } +} + fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) { // Instruct Cargo to give us json messages on stdout, critically leaving // stderr as piped so we can get those pretty colors. cargo.arg("--message-format").arg("json") .stdout(Stdio::piped()); + + if stderr_isatty() { + // since we pass message-format=json to cargo, we need to tell the rustc + // wrapper to give us colored output if necessary. This is because we + // only want Cargo's JSON output, not rustcs. + cargo.env("RUSTC_COLOR", "1"); + } + build.verbose(&format!("running: {:?}", cargo)); let mut child = match cargo.spawn() { Ok(child) => child,