-
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
Inform build scripts whether cargo is check
ing or build
ing
#4001
Comments
Sounds like a good idea to me! The only catch that I can think of is that we need to ensure we don't cache the check'd output and use it for the real output, other than that should be relatively easy to do with a new env var! |
that is what is currently happening, ie.:
tested: |
I think this is an ok thing to expose to build scripts, but it further highlights that a better factoring around build scripts might reduce footguns This kind of solution will help people who remember to check for the mode, but breaking up But as long as |
I'd expand the specific cases described in the title and first comment to include any subcommand, as I've seen Stack Overflow questions for "only do something for documentation" and "only do something for tests" |
I have a use case where a bunch of heavy work in build.rs script can (and should) be skipped for both the |
This would be helpful for rust-lang/rust#76444 |
This would be great. My use case is that I'm wrapping a C++ library that has static globals whose constructors read env vars (:scream:), and I'd like to set those appropriately for testing without impacting the normal build. FWIW I'd prefer to just run a different script altogether if it exists (e.g. |
To be able to run the unit tests seamlessly on any dev machine, we need to have the test resources downloaded. This can be achieved by calling the post-checkout script. Since this does not need to be executed when running with Buildkite, but all the time, the script is now moved to .buildkite/download_resources.sh and it is no longer a Buildkite hook, but rather a regular bash script. The script is called from build.rs so that it is transparent to the user when the resources are downloaded. The disadvantage with this approach is that the resources will be downloaded even when calling cargo build, and not only for cargo test. This can be updated in the future once cargo adds support for identifying the build profile in build scripts. Tracking issue: rust-lang/cargo#4001 Signed-off-by: Andreea Florescu <fandree@amazon.com>
To be able to run the unit tests seamlessly on any dev machine, we need to have the test resources downloaded. This can be achieved by calling the post-checkout script. Since this does not need to be executed when running with Buildkite, but all the time, the script is now moved to .buildkite/download_resources.sh and it is no longer a Buildkite hook, but rather a regular bash script. The script is called from build.rs so that it is transparent to the user when the resources are downloaded. The disadvantage with this approach is that the resources will be downloaded even when calling cargo build, and not only for cargo test. This can be updated in the future once cargo adds support for identifying the build profile in build scripts. Tracking issue: rust-lang/cargo#4001 To be able to run this with the rust-vmm-container, the script needs to be updated such that it uses curl instead of wget (wget is not available in the container). Signed-off-by: Andreea Florescu <fandree@amazon.com>
To be able to run the unit tests seamlessly on any dev machine, we need to have the test resources downloaded. This can be achieved by calling the post-checkout script. Since this does not need to be executed when running with Buildkite, but all the time, the script is now moved to .buildkite/download_resources.sh and it is no longer a Buildkite hook, but rather a regular bash script. The script is called from build.rs so that it is transparent to the user when the resources are downloaded. The disadvantage with this approach is that the resources will be downloaded even when calling cargo build, and not only for cargo test. This can be updated in the future once cargo adds support for identifying the build profile in build scripts. Tracking issue: rust-lang/cargo#4001 To be able to run this with the rust-vmm-container, the script needs to be updated such that it uses curl instead of wget (wget is not available in the container). Signed-off-by: Andreea Florescu <fandree@amazon.com>
Is there any solution or path towards providing this feature? |
Also have a use case for this like the above: big C++ dependency that Rust builds via build.rs, but only necessary if things get as far as the link step. |
Big +1 on this one:
A beefy C++ dependency is effectively rendering |
+1 I would like to distinguish between |
I have found two things that have helped me reduce the extra undesired work somewhat, although not a full fix yet: In the
This is useful for me as I have a workspace project with many crates, and this only deactivates that for this crate, and Corrected Text Here is some sample code you can use in
|
Closes rust-lang#4001 This PR adds code to track and pass compile mode to the build scripts. Since the unit's mode is always `RunCustomBuild`, I had to add tracking for the parent's compile mode, and pass it around. - [ ] env var naming. I used `CARGO_MODE`, but perhaps another name is better? - [ ] env var values naming. I used: `Test`, `Build`, `Check_test/Check`, `Bench`, `Doc_with_deps/Doc`, `Doctest`, `Docscrape`, `RunCustomBuild` - [ ] how to represent bool values for `Check` and `Doc`. I created two separate values, but perhaps the `test` and `deps` values should be ignored? - [ ] figure out why `cargo bench` sets env var to `Test` - [ ] add unit tests
I have tried to implement this feature in #10126, but it has a few open questions such as the naming of the env var and its values, etc. If my approach is OKed, I will add the unit tests/try to get it to pass CI. (I'm new to Rust, please be patient 😺) |
Yes, exactly :) |
It could be useful to explore whether or not cc can compile the code without optimization or debug symbols, then never link the final objects. I would see value in knowing that I broke all my C code if I'm writing part of the Rust project in C. Unfortunately I don't think cmake can do this (well, not reliably. You can ask it for a list of commands it would have run. But let's not...). |
It can. Use object libraries. |
Ah I see... I was thinking of "what is the least amount of work needed to produce rmeta files", since I view that as the goal of cargo check, but that is not the only way to think about this.
|
You can't ask cmake to produce an object library on someone's behalf without modifying their CMake source, and so such a solution would fall outside the realm of libraries. This feature is good for that too, just not something we could feasibly ask the cmake crate for. What might be useful there though is adding like |
On Windows, we rename symbols using a .def file. For that, we emit a cargo instruction. > cargo:rustc-link-arg=/DEF:sspi.def However, when attempting to run unit tests this causes an error. ``` Caused by: could not execute process `<redacted>` (never executed) Caused by: %1 is not a valid Win32 application. (os error 193) ``` There is currently no built-in way to check if cargo is going to run the tests from the build.rs itself: rust-lang/cargo#4001 This commit adds a new environment variable that when set prevent the instruction emission.
GPT-4 led me to believe cargo exposes this in build scripts via the "CARGO_CFG" environment variable. I was all excited to use it, but turns out it's not a thing. Wish it was.... |
Please don't use LLMs for things like this. |
Ok let me rephrase, we really should add something that gives build scripts some context about what is being built and why. It is ridiculous that we have all this information in the parent process, but none of it is shared with build scripts, and I don't see any good reason for why it is not shared. This should include:
And write access to the above as well as the ability to mutate+inject environment variables that are used later in the build process |
I have tried to find a workaround and checked for differences in environment variables within the build script with: let mut vars = String::from_str("VARS:\n").unwrap();
for (key, value) in std::env::vars() {
vars.push_str(&format!("{}={}\n", key, value));
}
std::fs::write("env-vars.log", vars).expect("Unable to write env-vars.log"); The most promising variable on my machine (ubuntu-22.04) seems to be 'RUST_BACKTRACE': if std::env::var_os("RUST_BACKTRACE").unwrap_or("".into()) == "short" {
std::fs::write("_is-checking.log", "-").expect("Unable to write file");
std::process::exit(0);
} else {
std::fs::write("_is-building.log", "-").expect("Unable to write file");
} You can also just check whether this variable exists at all. |
Using
For debugging, literally by crashes themselves (that is you don't even go as far as the internet, it just tells you).
Similarly with other environment variables. Without help from Cargo, this isn't doable. All the env vars you might check are set for other reasons, and sometimes by the user for other purposes, e.g. |
Yes, this is why we need more context information at the build script level |
For now a workaround is to set |
At this point, is the cargo project looking for someone to implement this? |
No. Still in discussion. We should be cautious of adding new environment variables for build script to read. It is not only a contract affecting Cargo, but also other external build systems. From what I read from this thread so far, people want build scripts to know the mode Cargo is running because that enables a way to
Some design problems need to be resolved are:
Note that I didn't tie this to something like |
Because in
cargo check
there may be work that build.rs can skipcc @wycats
The text was updated successfully, but these errors were encountered: