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 recompiles many of my crate's deps when my the case for my CWD changes on windows #4961

Open
Boscop opened this issue Jan 20, 2018 · 31 comments
Labels
A-rebuild-detection Area: rebuild detection and fingerprinting O-windows OS: Windows S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review

Comments

@Boscop
Copy link

Boscop commented Jan 20, 2018

cargo recompiles many of my crate's deps when I switch between cargo check in sublime and cargo build in cmd.exe, why?
Usually I have cargo watch -x run running in Cmder while coding in sublime and doing cargo check there. Until today, it was working fine, but now it always recompiles many of my crate's dependencies whenever I do cargo check in the editor, because cargo watch -x run has built it in the meantime, also with the deps which don't need to be built: it always recompiles them for both (from the shell and from the editor).
This is very frustrating because it's a huge project which takes a long time to compile, even with incremental compilation.

Btw, I tested it also with a cmd.exe spawned from sublime, and switching between that and the cmd.exe in Cmder. Same behavior. It always rebuilds when I switch shell and cargo build.
Btw, it only rebuilds direct deps that are in the combined Cargo.toml's of this workspace, not indirect deps, those are always still Fresh. Why would it rebuild all direct deps though?

This is with nightly 01-16 btw. It didn't happen before.

In the env I don't see any env vars that could cause cargo to recompile..

Why doesn't cargo build -vvvv print out more info about why it decides to rebuild those crates? (just "Compiling <crate>..")

@ehuss
Copy link
Contributor

ehuss commented Jan 20, 2018

If you set the environment variable RUST_LOG to info, it will log the reason it thinks it needs to rebuild. Look for the lines that say fingerprint error, and there may be a few lines below with detailed cause information. What do those say?

@Boscop
Copy link
Author

Boscop commented Jan 20, 2018

@ehuss Thanks! Yes, I get lots of fingerprint errors (for all direct deps) when doing cargo build in cmder and then in cmd.exe spawned by sublime, but why?

@alexcrichton
Copy link
Member

@Boscop that's saying profile configuration has changed which means that a different build is happening, for example debug differences, optimization levels, etc. Do you know what may be changing about that?

@Boscop
Copy link
Author

Boscop commented Jan 20, 2018

No idea. It uses the same Cargo.toml files, is called from the same dir (workspace root) etc. Both building in debug mode using the same nightly.

@ehuss
Copy link
Contributor

ehuss commented Jan 20, 2018

I'm having a hard time reproducing this, or thinking of ways it could fail. One possibility is that your environment variables are different in your shell versus Sublime, in particular the CARGO_INCREMENTAL environment variable, which is part of the profile. Can you check for any CARGO or RUST environment variables and see if they are set? Do you have any .cargo/config files anywhere (your home directory, or in your project directory, or any parent directory)? Do you have a build script doing anything weird?

It might also help if you could post a project with the minimum needed to reproduce it.

@Boscop
Copy link
Author

Boscop commented Jan 21, 2018

CARGO_INCREMENTAL is not set for either (because incremental is the default on nightly now, right?)
I checked all of these vars. Both envs have only these:

CARGO_HOME=D:\Program Files\.multirust\cargo
RUSTUP_HOME=D:\Program Files\.multirust
RUST_SRC_PATH=D:\Program Files\.multirust\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src

And they are the same for both.
I am doing something in build.rs (transpiling some parts of my project which are written in a Rust-dialect to Rust) but the source didn't change since when it was working (before I updated my nightly). Also the build.rs didn't change.

I have a .cargo\config file in this workspace, so it's also the same for both:

[build]
rustflags = "-C target-cpu=native"

And I have a global .cargo\config file but it's also the same for both.

What else could be the reason?
Maybe the nightly changed the way that my transpiled code affects the freshness of the crates? (I only transpile to OUT_DIR though.)

@alexcrichton
Copy link
Member

Given the way the profile hash is defined my guess is that this has something to do with incremental compilation. @Boscop are you sure that its consistently either incremental or not? If not it may be the case that different paths are being passed down messing with the hash. Can you get the verbose output of Cargo in both situations?

@Boscop
Copy link
Author

Boscop commented Jan 22, 2018

It's nightly 01-16 and I haven't set CARGO_INCREMENTAL to 0, so it should build incrementally by default, right? Either way, it's the same for both environments. But when I spawn a shell out of sublime and do the build there, it doesn't rebuild the deps unnecessarily, so it must be something in the environment, but what else can it be?

@Boscop
Copy link
Author

Boscop commented Jan 22, 2018

@alexcrichton

Here is the full output of cargo build -vvvv in cmder (after building it in the cmd.exe spawned from sublime before).

Here is the full output of cargo build -vvvv in cmd.exe (spawned by sublime) after that.

Here is the full environment of cmder (as reported by the set command).

Here is the full env of cmd.exe spawned from sublime.

@alexcrichton
Copy link
Member

It looks like the drive path is changing from d:\ to D:\ which is probably causing Cargo to hash it differently as it means the literal bytes being passed down through the incremental_args call is changing. Do you know why the drive letter is changing?

@Boscop
Copy link
Author

Boscop commented Jan 23, 2018

Cmder shows all paths with lowercase drive letters for the prompt too.
So the actual drive's letter is not changing.

@Boscop
Copy link
Author

Boscop commented Jan 23, 2018

But yes, when I spawn a new "tab" (another shell in Cmder) and enter the dir path with capital drive letter, then build in sublime, then in that new tab, it doesn't trigger the rebuild! But then when I switch to the old tab (with lowercase drive letter) that triggers the rebuild (just switching between those two cmder shell instances).
So that seems to be what caused it!
But in both cases it shows Compiling foo v0.1.0 (file:///D:/projects/foo) with a capital drive letter!
Can cargo be made to ignore the case of drive letters on windows? (I think msys also uses lowercase drive letters.)

@alexcrichton
Copy link
Member

I believe what's happening here is:

  • Hash for PathBuf does the right thing and doens't account for case sensitivity.
  • We're, however, not hashing a PathBuf, but rather a vector of strings. Strings don't know about the case insensitivity so it fails.

@Boscop would you be curious to help work on a patch for this? I think we could solve this by basically returning some custom structure from incremental_args which stores a PathBuf and implements Hash.

@Boscop
Copy link
Author

Boscop commented Jan 24, 2018

I'd be interested to help but I'm not familiar with cargo internals at all and super busy with my job and studies at the moment..

Not sure how much time would be needed to read all the code necessary to come up with a good solution vs someone who is already familiar with the internals..

I guess a solution would be that instead of flattening "incremental=" and the path into a string before hashing, keeping them separate as struct Incremental(path_buf: PathBuf); which impls Hash and ToString (or Display).

But maybe an even simpler solution would make sense: just normalize all paths on windows to lowercase before concatenating with "incremental="?

@alexcrichton
Copy link
Member

Indeed yeah! I think we'd basically just change

fn incremental_args(..) -> Vec<String>

to

fn incremental_args(...) -> IncrementalArgs

where it'd just store a PathBuf internally (or an Option for when it's disabled). Then a method could be added to IncrementalArgs to explicitly turn it into a vector of strings to pass to a Command as well.

@Boscop
Copy link
Author

Boscop commented Jan 25, 2018

But why not normalize paths on windows to lowercase before concatenating with "incremental="? That would be a smaller and more localized change.

@alexcrichton
Copy link
Member

I'm personally not a huge fan of normalization in general b/c of the bugs it can introduce, and sticking with the source of truth I don't think will be too large of a change here.

@jocutajar

This comment was marked as off-topic.

@ehuss

This comment was marked as off-topic.

@jocutajar

This comment was marked as off-topic.

@dwijnand

This comment was marked as resolved.

@alexcrichton

This comment was marked as resolved.

@ehuss ehuss added the A-rebuild-detection Area: rebuild detection and fingerprinting label Sep 23, 2019
@gilescope
Copy link
Contributor

Is this still an issue? Looks like the cargo code has changed considerably and been re-organised since this was raised.

@jocutajar
Copy link

I haven't seen this problem in a long while.

@hnrklssn

This comment was marked as off-topic.

@swfsql

This comment was marked as off-topic.

@kaimast

This comment was marked as off-topic.

@Boscop

This comment was marked as off-topic.

@janikrabe

This comment was marked as off-topic.

@horacimacias

This comment was marked as off-topic.

@epage epage changed the title cargo recompiles many of my crate's deps when I switch between cargo check in sublime and cargo build in shell Cargo recompiles many of my crate's deps when my the case for my CWD changes on windows Oct 17, 2023
@epage epage added O-windows OS: Windows S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review labels Oct 17, 2023
@epage
Copy link
Contributor

epage commented Oct 17, 2023

There are many reasons why a rebuild may be happening. This is focusing on one specific case that was narrowed down to a change in the case for the CWD.

We first need a test for this case. If it doesn't reproduce, great, let's merge it. If it does reproduce then we can work on fixing it. Most of the fingerprinting code lives at https://github.com/rust-lang/cargo/tree/master/src/cargo/core/compiler/fingerprint these days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rebuild-detection Area: rebuild detection and fingerprinting O-windows OS: Windows S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review
Projects
None yet
Development

No branches or pull requests