-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Presentation of cargo::error encourages build scripts to exit with a successful status code on failure #15038
Comments
I see there being 3 exit conditions with
I would assume the exhaustive output would be most helpful in the case of a logic bug which would usually come in the form of a I don't see how the extra output would be relevant to help with an "error" with the For the concern for the |
I do not think that developers would print Exiting with an error status on failure is the correct thing to do, but this issue is not about beating non-compliant people with the best practices. It's the opposite: an observation that Rust users already value correctness, so they would find it objectionable to be forced to use incorrect and backwards-incompatible As much as I'd like to make pull requests to all the -sys crates to make them use the clean error presentation, I expect I'd have hard time convincing crate owners to accept a PR that uses Debug dump on fn probe_library(name: &str) -> bool {
match search_for_it(name) {
Ok(found) => {
println!("cargo::rustc-link-lib={found}");
return true;
},
Err(error) => {
println!("cargo::error={error}");
return false;
}
}
}
fn main() {
if !probe_library("dep") {
build_static().unwrap();
}
} This script prints
Build scripts very often intentionally
However, the If you think that I'm proposing to add the stdout/stderr dump on |
Problem
The current implementation of
cargo::error
has a minimal, concise error presentation only when the build script exits with a successful status code (0) when it reports a build failure.If a build script fails with a non-zero status code, use of the
cargo::error
directive doesn't prevent Cargo from adding a full dump of stdout/stderr after it, which makes the output noisy and difficult to understand #10159.The current implementation incentivises build scripts to exit with the status 0 (success) to cleanly report fatal build errors. This is a non-standard behavior for reporting failures, and it's not backwards compatible with older Cargo versions that don't understand
cargo::error
.Dumping the full stdout/stderr output is a major problem that diminishes usefulness of
cargo::error
. The dump is so noisy that the errors reported viacargo::error
may be less visible and less readable than a raw text printed to stderr. The stdout dump can contain long lists ofcargo::rerun-if-(env-)changed
directives, and other potentially irrelevant logs from subcommands. A long noisy stdout/stderr dump usually causes users to stop reading the output carefully, and gloss over the entire output instead. It may even push the "error:" lines out of the view, leaving only the raw dump on screen, which ends with less helpful content. Thepkg-config
andcmake
crates have this problem, and they also happen to be the most frequent source of build script failures.pkg-config
prints 21cargo::rerun-if-env-changed
lines, which together with Cargo's boilerplate is 25 lines, the same as the default height ofcmd.exe
console on Windows. Windows users may literally not see the errors generated bycargo::error
if a build script fails with a failure status code. The long output dump can be made even noisier when the build script panics, and Cargo actively encourages users to enable even longer backtraces, which pushes the "error:" lines even further, and obscures even the last lines of stderr that may contain another copy of the error.I think the conditions for when
cargo::error=
has a clean presentation should be swapped: it should give the cleanest presentation when the build script reportscargo::error
and exits with a failure status code to match it. This is a consistent response.When a build script prints
cargo::error
, but exits with a success code, this is a self-contradictory result. This is likely a bug in the build script. Such failures could be caused by helper functions or build-time dependencies eagerly printingcargo::error
, even when the build script manages to recover from the error and succeeds using some other way. To help catch such roguecargo::error
s that break succesful build scripts, Cargo should be printing the full stdout dump, so that build script authors can check where in the log the unintended directive has appeared.In other words, this is the current behavior:
cargo::error=
but to make
cargo::error
useful to end users, and bad error reporting debuggable, it should work like this:cargo::error=
Steps
Buggy
build.rs
:happens to get a clean error output with a high signal-to-noise ratio:
A more typical script that exits with a correct status code:
gets an ugly noisy dump that makes it hard for end users to understand what's going on:
Possible Solution(s)
build scripts that report both failure and success at the same time (one via
cargo::
the other via status) should get the stdout dump to help find the source of the contradictory response.build scripts that print
cargo::error=
and correctly return failure code should get a clean error output with just the errors and warnings the script reported, without irrelevant information dumped by Cargo.Version
The text was updated successfully, but these errors were encountered: