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 does not re-build if Rust toolchain changes without version changing #10664

Closed
jonhoo opened this issue May 12, 2022 · 8 comments
Closed
Labels
C-bug Category: bug

Comments

@jonhoo
Copy link
Contributor

jonhoo commented May 12, 2022

Problem

In my build environment, Rust is built from source into a custom toolchain, which I then have set as a rustup override for all my Rust projects. This normally works just fine. But, if I ever re-build Rust, any later Cargo build starts failing with errors like

error[E0460]: found possibly newer version of crate `std` which `autocfg` depends on
 --> ~/.cargo/registry/src/-9b9edb9e6458afc3/num-traits-0.2.15/build.rs:1:1
  |
1 | extern crate autocfg;
  | ^^^^^^^^^^^^^^^^^^^^^
  |
  = note: perhaps that crate needs to be recompiled?
  = note: the following crate versions were found:
          crate `std`: ~/rust-toolchain/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-21f44e42eb110109.rlib
          crate `std`: ~/rust-toolchain/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-21f44e42eb110109.so
          crate `autocfg`: target/debug/deps/libautocfg-92c37f7a46b79193.rlib

The error stems from here in rustc, and is raised because the hash for libstd has changed. rustc is accurately identifying that autocfg was previously built against a different libstd than is now in the toolchain, and thus refusing to build against it.

I think this is really a bug (or, perhaps, missing feature) in Cargo's fingergprinting. Specifically, it currently only takes into account the version of Rust used to build an artifact, not the core library hashes. This means that if the version stays the same but the hash changes, Cargo doesn't realize a re-build is necessary:

/// Hash of the version of `rustc` used.
rustc: u64,

Steps

  1. Build Rust from source
  2. Create a new Cargo project with at least one dependency
  3. Use Rustup to set a toolchain override for the Cargo project to point at the from-source Rust build
  4. Build the Cargo project
  5. Make a change to the Rust source and re-build
  6. Build the Cargo project again

Possible Solution(s)

Cargo's fingerprinting should probably take into account the hashes for the core libraries, not just the overall Rust version.

Notes

No response

Version

cargo 1.60.0 (d1fd9fe 2022-03-01)
release: 1.60.0
commit-hash: d1fd9fe2c40a1a56af9132b5c92ab963ac7ae422
commit-date: 2022-03-01
host: x86_64-unknown-linux-gnu
libgit2: 1.3.0 (sys:0.13.23 vendored)
libcurl: 7.80.0-DEV (sys:0.4.51+curl-7.80.0 vendored ssl:OpenSSL/1.1.1m)
os: Amazon Linux AMI 2.0.0 [64-bit]
@jonhoo jonhoo added the C-bug Category: bug label May 12, 2022
@ehuss
Copy link
Contributor

ehuss commented May 12, 2022

This is currently intentional behavior, which is not clear if it can be changed. Closing as a duplicate of #10367.

@ehuss ehuss closed this as completed May 12, 2022
@jonhoo
Copy link
Contributor Author

jonhoo commented May 12, 2022

I think this is actually slightly different — this isn't about whether the path to rustc changes, but rather whether the hashes of rustlib/lib/*.rlib change, which definitely mean a re-compile is necessary. It's also not related to build scripts or RUSTC, which the other issue seems to focus on. Specifically, in my case, the toolchain stays in exactly the same place, and no environment variables change — it's the toolchain content that changes in place.

@ehuss
Copy link
Contributor

ehuss commented May 12, 2022

#10367 is also about changing the rustc binary in place. That is, cargo doesn't check the mtime (or hash) of the rustc executable.

If you want to check if libstd and friends change, perhaps you can use -Zbinary-dep-depinfo? That is how rustbuild works.

@jonhoo
Copy link
Contributor Author

jonhoo commented May 12, 2022

Ah, I read it as specifically talking about the RUSTC environment variable given the capitalization, not the rustc binary itself. I think even just checking if the rlib-embedded hash of libcore changes would actually get us a really long way here. Or phrased differently, it's (probably) unlikely for other bits to change but not libcore. I suppose mtime might be a decent proxy metric here too, but hopefully the hash shouldn't be too bad.

When you say "use -Zbinary-dep-depinfo, what do you mean? I was imagining I'd submit a PR that updates Cargo itself to include the libcore hash (or mtime) in its fingerprinting, though maybe that can re-use some of the logic from -Zbinary-dep-depinfo?

@ehuss
Copy link
Contributor

ehuss commented May 12, 2022

Passing -Zbinary-dep-depinfo to cargo will cause it to include the standard library dependencies in the dep-info file. Cargo checks the mtime of all those files and compares them to see if it needs a rebuild. When you rebuild the standard library, that should update the timestamp and allow cargo to know things need to be rebuilt.

@jonhoo
Copy link
Contributor Author

jonhoo commented May 12, 2022

Oh iiinteresting. That's a great tip, thanks! The nightly-only-ness and reliance on mtime over the hashes present in the rmeta files is unfortunate, but might still get me pretty far. Looking at the tracking issue makes me curious about why codegen backends not being tracked is considered a blocker. Seems like an improvement that could be added down the line eventually rather than be a head-of-line blocker. Also, is the intention that this might become the default behavior, or will it always remain an opt-in?

@ehuss
Copy link
Contributor

ehuss commented May 12, 2022

We haven't really discussed moving it beyond the initial introduction which was needed for rustbuild, so I'm not sure. I expect it will be enabled unconditionally. Yea, I think the codegen backends could be added later.

@bodenstorfer
Copy link

I ran into the issue in the stable version after having upgraded from macOS Monterey to Ventura.
As a quick workaround for newbies such as myself, I removed the target directory from the project folder before cargo run.

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

No branches or pull requests

3 participants