Skip to content
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

Cargo doesn’t display output from a command in build.rs #985

Closed
0x00b1 opened this issue Nov 26, 2014 · 25 comments
Closed

Cargo doesn’t display output from a command in build.rs #985

0x00b1 opened this issue Nov 26, 2014 · 25 comments

Comments

@0x00b1
Copy link

0x00b1 commented Nov 26, 2014

When a command, e.g. Command::new("nasm"), in build.rs returns an error, Cargo doesn’t output the error to standard output. This is especially frustrating when debugging a Makefile that’s run by Command::new("make").

@alexcrichton
Copy link
Member

This is actually done by default to turn down the noise from builds. If you're debugging makefiles I'd recommend having the build command itself forcibly fail to ensure that Cargo prints the output of the build script.

@0x00b1
Copy link
Author

0x00b1 commented Nov 26, 2014

Why not display this output when using --verbose? How do I forcibly fail?

@0x00b1
Copy link
Author

0x00b1 commented Nov 28, 2014

cc: @alexcrichton

@alexcrichton
Copy link
Member

You can check the full output in target/build/$crate-$hash/output and you can forcibly fail with a panic!() or a std::os::set_exit_status(nonzero_code). I think that printing this out for --verbose would be a bit too verbose, but we could consider printing where the output goes I suppose. In general a successful build script is something you largely want to ignore 90% of the time.

@est31
Copy link
Member

est31 commented Nov 4, 2016

Note to anyone who found this issue by googling: you can pass -vv now to cargo to display the output. See commit 2c0d6af1739be737133e2385033d1395fbcd8342 and #1106 for details.

bors added a commit that referenced this issue Oct 15, 2017
Document how to make `build.rs` write to the terminal

Documenting the solution mentioned here: #985
@ivnsch
Copy link

ivnsch commented Aug 11, 2019

@est31 I passed -vv and still don't see the output of println!

@filmor
Copy link

filmor commented Sep 18, 2019

At least the output of eprintln! goes through in that case.

@mankinskin
Copy link

Why would I write a build script with println! if I didn't want to see any output when building? Hopefully this will get fixed.

@ratulb
Copy link

ratulb commented Apr 17, 2020

Same issue here. Cargo run does not print. Compiling directly with rustc and running main.exe does print.

@mankinskin
Copy link

There is also -- --nocapture which shows the output when running tests. Maybe it helps but I have not tried.

@evandrocoan
Copy link

The only good solution is to write the output you want to see/debug to a file.

Adding -vv outputs too much information and -- --nocapture do not works neither.

@ldm0
Copy link

ldm0 commented Jun 8, 2020

For those who still doesn't see any output even after passing -vv:

  1. Slightly modify the build.rs like adding a new line(force cargo to rebuild it) and using cargo build -vv, then you'll see the outputs.
  2. Using find . -name output, you will be able to get the path(target/build/$crate-$hash/output) to the output file, then you can cat it.

@Lucretiel
Copy link

You shouldn't use println! for debug printing a build.rs script; the cargo build system uses the output of that script to record build & rebuild metadata, as documented here: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script

@fitzoh
Copy link

fitzoh commented Feb 10, 2021

You shouldn't use println! for debug printing a build.rs script; the cargo build system uses the output of that script to record build & rebuild metadata, as documented here: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script

That link states that any output not starting with cargo: will be ignored. As long as you avoid the cargo: prefix for debugging, that link implies that it's fine to use println! for debugging.

@notdanilo
Copy link

You shouldn't use println! for debug printing a build.rs script; the cargo build system uses the output of that script to record build & rebuild metadata, as documented here: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script

Cargo shouldn't use println! for transmitting commands.

@wdanilo
Copy link

wdanilo commented Mar 12, 2022

I don't think this issue should be closed. It's very convenient to use println when debugging. Not being able to use it in part of the codebase is cumbersome and introduces a significant mental burden.

@evandrocoan
Copy link

@notdanilo , I opened a new issue based on your suggestion with an alternative solution:

Cargo shouldn't use println! for transmitting commands.

Cargo if it wants to use print, open a special file and print to it instead of stderr/stdout. Then, users do not have to open a file for their print. It is more reasonable for the tool (cargo) to open a file for its commands than the user to open a file for its debug printing.

If anyone likes it, or have a different proposal, please, upvote it or comment on it: #10475

@Ryan1729
Copy link

Ryan1729 commented Mar 17, 2022

I mentioned this on the new linked issue, but it might be worth mentioning here that you can currently do println!(cargo:warning=MESSAGE) to get output from build scripts. It will always be prefixed with "warning: " however.

So, for quick debugging of a build script you could use this drop in replacement for println:

macro_rules! p {
    ($($tokens: tt)*) => {
        println!("cargo:warning={}", format!($($tokens)*))
    }
}

usage example:

// in build.rs

macro_rules! p {
    ($($tokens: tt)*) => {
        println!("cargo:warning={}", format!($($tokens)*))
    }
}

fn main() {
    let x = 42;
    p!("{x}");
}

@drdavella
Copy link

Another (terrible) hack, but if you panic! at the very end of your build script, it will at least allow you to see any prints emitted from the script. This can be useful if you just need some quick insight into what is happening in the script.

@mahesh-maximus
Copy link

// in build.rs

macro_rules! p {
    ($($tokens: tt)*) => {
        println!("cargo:warning={}", format!($($tokens)*))
    }
}

fn main() {
    let x = 42;
    p!("{x}");
}

Thanks, Really appreciated

1 similar comment
@mahesh-maximus

This comment was marked as duplicate.

@levkk
Copy link

levkk commented Mar 23, 2023

I've managed to debug build.rs scripts by placing a panic! at the end. As it crashes, it will print everything to standard output, including any println! (the universal debugger 😄).

@gdnathan
Copy link

gdnathan commented Nov 6, 2023

I have a project where my rust crate is using some dynamic libraries (also in Rust). So, my build workflow is to basically compile the dynamic libraries, move their binaries somewhere, and then build my main project.
Using build.rs is absolutely cumbersome, I cannot see the output of compiling my dynamic libraries, I cannot see the warnings or anything else.
HOW is it fair that cargo can output it's own informations when building, but I cannot do the same if I introduce a build script ? So yes, cargo build should not capture the output.
I could read that cargo is using the build script output for IPC. But it's only doing so when there is a cargo: prefix, so why not let pass the rest of it when there is not prefix ???

@epage
Copy link
Contributor

epage commented Nov 6, 2023

@gdnathan

I could read that cargo is using the build script output for IPC. But it's only doing so when there is a cargo: prefix, so why not let pass the rest of it when there is not prefix ???

That answer is in the second post

This is actually done by default to turn down the noise from builds. If you're debugging makefiles I'd recommend having the build command itself forcibly fail to ensure that Cargo prints the output of the build script.

As other posts in this thread say

  • Check target/build/$crate-$hash/output
  • Pass -vv
  • Fail your build script

@mratsim
Copy link

mratsim commented Dec 2, 2023

As other posts in this thread say

* Check `target/build/$crate-$hash/output`

Cannot be done easily in CI

* Pass `-vv`

Then you have tens of thousands of lines of log for any complex projects and extremely cumbersome to parse in CI

* Fail your build script

Very noisy when collaborating with many people on a shared project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests