-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Request not to suppress the output of build script #1106
Comments
This has come up before, and the reason it's all suppressed by default is to tone down the noise of builds. If you're not seeing the output when the script fails, that's definitely a bug though. Do you have an example of this occurring? |
The exmpleI have copied the // build.rs
use std::io::Command;
use std::os;
fn main() {
let out_dir = os::getenv("OUT_DIR").unwrap();
// note that there are a number of downsides to this approach, the comments
// below detail how to improve the portability of these commands.
Command::new("gcc").args(&["src/hello.c", "-c", "-o"])
.arg(format!("{}/hello.o", out_dir))
.status().unwrap();
Command::new("ar").args(&["crus", "libhello.a", "hello.o"])
.cwd(&Path::new(&out_dir))
.status().unwrap();
println!("cargo:rustc-flags=-L {} -l hello:static", out_dir);
} Note that the script does not check the status code of GCC or AR. The problemAnd it happened that the source does not compile. However Cargo printed out NOTHING helpful to diagnose this problem:
I spent an extra hour figuring out where the problem is, having add some extra code to redirect the output of GCC to a log file. I admit that there is a bug in the build script that the status code should be checked. But anyway, there need to be a way to debug this, or it will be a pain if this happens on a client's computer, causing a complaining mail. If the user says
|
I think that I should update the example listed to also check that the return code is 0, the real bug here is that the build script should fail if the return code is not 0, which would cause output to show up. Some other points:
|
I have already stated that there is a bug in the build script.
Why aren't Rust warnings treated like this? This is a discrimination against C. Some other points:
I'm not convening you to let out the output of P.S. Maybe a combination of |
Idly, I've also faced this issue, but broadly speaking I agree with @alexcrichton on it. There's no way to 'stream' output from a process. It just can't happen. The Process API doesn't support it. The best you can do is block on stdout and stderr in a thread and wait until the process dies. Without an async io story, the very idea of streaming output from the build command is just a non-starter. ...and without that, I don't really see much benefit from being able to push output to stdout on success. I mean, what's really the use case for 'This C compile passed, but I want to display some output messages'? If you want to do debugging, just set the build.rs to always fail and it'll print the output to stderr. If you want a more comprehensive logging solution (eg. log output of the entire build command to a file) you can use a 3rd party logging library for it. I feel like if you allow build scripts to push output to stdout, everyone will start doing it, and it'll clutter the cargo build --verbose output like crazy. (To be fair though, cargo does occasionally just hang for various reasons, and it is quite useful to stream build output to make sure, for example, xcode hasn't just spazzed out and stopped doing anything without killing the process, which it does, for example, when building libuv sometimes. ...but like I said, without streaming, there's no way of having any idea what's going on anyway, so... /shrug) |
Thank you for your note. I have read the code at It seems that Cargo pipes out all the output to a file, read it into the memory as a string and process it.
|
@m13253 You can block on the pipe, but that locks the entire thread; cargo runs multiple commands at the same time, and this would halt the entire process it while it performs the build step. Technically you could create a solution I suppose, where you created a separate thread for each pipe, and used Sender & Receiver to message pass data back to the 'parent' thread. I'm not aware of any existing implementation of that, but I believe it should be technically possible... Re: stderr output; I think that's just the way Process works. As you said; it (by default) consumes the streams (stderr, stdout). Wouldn't that require changing the Process api to fix? |
In order to pass |
Ugghh, debugging of build scripts is such a pain :( I can't run the script directly from So it's a black box that's calling a bunch of commands with arguments I'm not sure about, and something doesn't work right, and maybe it has printed why… but I can't see it! The way I write them is: let result = cmd.output().unwrap();
std::io::File::create(&Path::new("/tmp/sucks1")).write(&result.output[]).unwrap();
std::io::File::create(&Path::new("/tmp/sucks2")).write(&result.error[]).unwrap(); rm -f /tmp/sucks*; cargo build; cat /tmp/sucks* Surely, there must be a better way. |
@pornel Once again, if the build script fails, cargo reports the output stderr; so you can totally debug the output and dump the env vars if you want to. Just add:
For example a build.rs of:
I'm sure we'll see a growth of 'build helper' libraries as we go past 1.0 to help with the tedious tasks. Personally I use https://github.com/shadowmint/rust-script for this, but there are a few others around. Perhaps you can pull the pieces you need out of them for your build script? |
Yes, panic!() is possible. But it didn't solve the problem. For example I usually prefer this procedure to debug this kind of script:
Cargo only consumes stdout, but it is managing both stdin and stderr, making this method unavailable. There should be a way that I can use gdb for instant debugging. Anyway, I can still achieve the goal by starting a new XTerm (or AllocConsole on Windows). However this will decrease user experience even more, and is oppose to the original design of Cargo. |
@shadowmint Ok, it's good to know that
|
From @larsbergstrom in #1324
|
Cargo does print the custom build commands:
It just doesn't print the output or the list of env variables passed to them. Once again, I find myself skeptical that logging the output will be useful unless there's a way to stream that output line by line as the build command generates it. ...and even then, unless the build command invokes commands correctly, it will still work exactly the same way (people just use read_to_end() all the time). Really, there's no benefit is having cargo run to the end, and then spit out the output to stderr and stdout at the end; the issue with cargo is while its running you want some visibility about what it's actually doing, so you can debug scripts. For example, if cargo hangs due to xcode ( >___< ) you have no visibility of what happened or why it stopped. I use a custom file logger for this; but clearly this is a troublesome pain point for people. Perhaps we can change the way cargo works (although I'm worried about breaking changes here... but still...) so that instead of using env variables, all the arguments are passed on the command line. This would allow you to trivially run your build script in 'stand alone' mode, by running:
Running these outside of cargo would then print stdout & stderr as you go; although doubtless people will continue to discover that when build.rs invokes make, or other tools via Command it doesn't usefully log it's output for exactly the same reason. NB. though that as recently raised in irc, windows has a command line length limit that might make this infeasible. |
I just found this obnoxious in a case where my build script succeeded, but screwed up generated link flags, causing the library link to fail. I resorted to |
User perspective: First time hacking on a build script helper (@alexcrichton's gcc-rs), and I slammed straight into this. 😃 |
It would be tremendously helpful on build bots like Travis, Jenkins, AppVeyor, etc. Imagine that you are developing a wrapper around a native library, and you're trying to use Travis, etc. to set up builds for a platform that you don't even have access to locally. The build logs are critical to getting that situation to work. More generally, verbose build logs from buildbots are much preferred over quiet logs from buildbots. IMO, |
@briansmith how do propose to do this, technically? I've said my piece; if you want to hack on it, the code is here: https://github.com/rust-lang/cargo/blob/master/src/cargo/ops/cargo_rustc/custom_build.rs#L149 The execution engine is here: https://github.com/rust-lang/cargo/blob/master/src/cargo/util/process_builder.rs#L89 Try it and see how it works out for you? I found that without streaming output, having 'log on failure' vs 'log on success' made no tangible difference. |
It may be possible to have cargo both stream and capture the output via some pipe trickery on Windows/Unix, and I may also be pretty ok with doing this on multiple
|
@alexcrichton That double-v support would be fantastic. I'm pretty sure we would use it by default on our builds for pretty much everything on the builders on Servo, for exactly the reasons @briansmith outlines above. Right now, we have to have an admin log into the build machine, cargo build -v to get the execution line, then try to invoke stuff in the right directory to hopefully get the output (assuming we're lucky enough that it isn't something that only happens on a first-time build through the project!). cc @metajack |
+1 on -vv showing script output. When running Travis CI I really dislike the idea of having to introduce another build failure(by committing a panic!("fail");) in order to see build script output. |
👍 on Travis is killing my jobs because I'm building ffmpeg from the |
I just wasted a considerable chunk of my weekend trying to debug a build-script. And it was all because of this 'feature'. The default way things work now is really terrible, especially for new users. When the script panics you get to see some stdout/stderr, which lead me to believe that stdout/stderr can be printed from the build-script. I spent the rest of my time trying to figure out why I can see it sometimes and other runs it seems to be missing. I thought cargo was linking in the old build script or something. I agree with the other commenters here that this should be changed. Verbose should mean verbose. |
This adds support for forwarding warnings from build scripts to the main console for diagnosis. A new `warning` metadata key is recognized by Cargo and is printed after a build script has finished executing. The purpose of this key is for build dependencies to try to produce useful warnings for local crates being developed. For example a parser generator could emit warnings about ambiguous grammars or the gcc crate could print warnings about the C/C++ code that's compiled. Warnings are only emitted for path dependencies by default (like lints) so warnings printed in crates.io crates are suppressed. cc rust-lang#1106
This commit alters Cargo's behavior when the `-vv` option is passed (two verbose flags) to stream output of all build scripts to the console. Cargo makes not attempt to prevent interleaving or indicate *which* build script is producing output, rather it simply forwards all output to one to the console. Cargo still acts as a middle-man, capturing the output, to parse build script output and interpret the results. The parsing is still deferred to completion but the stream output happens while the build script is running. On Unix this is implemented via `select` and on Windows this is implemented via IOCP. Closes rust-lang#1106
Add build script warnings, streaming output from build scripts to the console These commits add a few features to Cargo: * Cargo now recognizes the `warning` key in build scripts and will print warnings *after a build script has completed* if the build script is for a path dependency. That is, if a build script prints `cargo:warning=foo` then Cargo will forward that to the console if the crate's being developed. * Cargo now accepts multiple `-v` flags for all commands. The `-vv` flag prints warnings for *all* upstream crates, not just the local ones. * When the `-vv` flag is passed Cargo will stream the output of all build scripts to the console, allowing more easy debugging of what happened if the build fails later on. More details can be found in each commit, and otherwise this Closes #1106
Sometimes the build script may fail, leaving some useful information (such as the output of GCC) in stdout or stderr.
However, I found that Cargo is not displaying the output of my build script.
I request a feature, that the stderr is displayed by default and stdout is displayed when
--verbose
is on.Thanks.
The text was updated successfully, but these errors were encountered: