I've seen many examples of users stuck unable to compile crates, because they fail to notice error messages printed by build scripts. That is, the build script prints what user needs to do to fix the issue, but that text is lost in the noise of all other build error information, so user never notices the message, and it makes Rust look like it's failing for an unknown reason.
Most recent example where build script needed git installed, but user didn't notice it, and basically needed someone on the forum to read the message and say back to them what the message said. I'm not picking on this user in particular — it's a pattern, and IMHO Cargo is here to blame.
When a build script panics, Cargo dumps an overwhelming amount of information around the message:
I'd agree. When I'm already skimming through a ton of irrelevant lines, a line starting with "thread 'main' panicked at" initially looks like it's just more noise. So it's very easy to miss the only information that matters to me at the time.
The two lines that actually start with "error: " give very limited or no information about the actual cause despite the build script's attempts to inform the user.
I wanna add that my knee-jerk reaction to any diagnostic that contains "thread ... panicked at" is "oh crap, that's an internal error, do I have time to file a bug report?" It does not suggest to me a situation that I can fix myself.
Is this actually Cargo's fault though? Cargo dumps whatever build.rs prints to stdout/stderr, so probably it is the build script which needs to be less spammy?
Looked at the build script in question. Looks like the fix is to swap these two groups of commands:
This particular build script could output less before failing, but you can't rely on this in general. For example, build failures in C builds may print a lot before failing.
The messy "thread 'main' panicked" text is technically Rust's/std's fault, since it's the default panic message and Cargo merely pipes it. Improving this bit may need some clever integration between Rust/std/Cargo.
There's also a problem that this full verbose output is useful to sys crate developers, and might be useful to users who need to debug less obvious build failures.
How about this:
Cargo should continue to dump full stdout/stderr on error when the build script belongs to the current workspace. This will avoid frustrating sys crate developers.
When building sys crate of a dependency, it should print cargo:warning + panic message, and a suggestion to run again with --verbose to get the full output.
There needs to be some way of Cargo "catching" a panic with just the relevant part of the message, rather than the whole "thread 'main' panicked at". I'm not sure how could this be implemented. Some env var like RUST_MACHINE_READABLE_PANIC=1 that makes any Rust executable output panics in parseable format? Or a rustc flag similar to panic=abort, but something like panic=special-for-build-script-integration?
This seems like a good option to me, since cargo is already watching the output of the script.
It also allows the build script to add additional error info in special cases where the crate developer knows how to fix some specific error. By explicitly printing cargo:warning Here's how to fix this they would get the same "error" presentation regardless of whether the script caught the error and printed some help or panicked.
One potential complication to relying on passing a rustc flag of some sort for build scripts would be custom panic hooks, but I'm not sure how common those are in build scripts.