Skip to content

Commit a859f2b

Browse files
Rollup merge of rust-lang#42804 - Mark-Simulacrum:rustbuild-colors, r=alexcrichton
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. Fixes rust-lang#42801. r? @alexcrichton
2 parents a56fef8 + 305f526 commit a859f2b

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/bootstrap/bin/rustc.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ fn main() {
236236
}
237237
}
238238

239+
let color = match env::var("RUSTC_COLOR") {
240+
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
241+
Err(_) => 0,
242+
};
243+
244+
if color != 0 {
245+
cmd.arg("--color=always");
246+
}
247+
239248
if verbose > 1 {
240249
writeln!(&mut io::stderr(), "rustc command: {:?}", cmd).unwrap();
241250
}

src/bootstrap/compile.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,43 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) {
477477
build.run(&mut cargo);
478478
}
479479

480+
481+
// Avoiding a dependency on winapi to keep compile times down
482+
#[cfg(unix)]
483+
fn stderr_isatty() -> bool {
484+
use libc;
485+
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
486+
}
487+
#[cfg(windows)]
488+
fn stderr_isatty() -> bool {
489+
type DWORD = u32;
490+
type BOOL = i32;
491+
type HANDLE = *mut u8;
492+
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
493+
extern "system" {
494+
fn GetStdHandle(which: DWORD) -> HANDLE;
495+
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL;
496+
}
497+
unsafe {
498+
let handle = GetStdHandle(STD_ERROR_HANDLE);
499+
let mut out = 0;
500+
GetConsoleMode(handle, &mut out) != 0
501+
}
502+
}
503+
480504
fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
481505
// Instruct Cargo to give us json messages on stdout, critically leaving
482506
// stderr as piped so we can get those pretty colors.
483507
cargo.arg("--message-format").arg("json")
484508
.stdout(Stdio::piped());
509+
510+
if stderr_isatty() {
511+
// since we pass message-format=json to cargo, we need to tell the rustc
512+
// wrapper to give us colored output if necessary. This is because we
513+
// only want Cargo's JSON output, not rustcs.
514+
cargo.env("RUSTC_COLOR", "1");
515+
}
516+
485517
build.verbose(&format!("running: {:?}", cargo));
486518
let mut child = match cargo.spawn() {
487519
Ok(child) => child,

0 commit comments

Comments
 (0)