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

Rebuild crate dependencies when the rust compiler version changes #45

Closed

Conversation

ekump
Copy link

@ekump ekump commented May 7, 2019

I've noticed that every time a new version of Rust is released my Heroku deployments fail and I have to purge the build cache using the Heroku CLI. It turns out that there is one particular crate that has a build script that fails. I intend on working with the maintainer of the crate to make their build script more resilient. But, I thought it might be nice to also have the option to rebuild all crates when a new version of Rust is released.

@emk
Copy link
Owner

emk commented May 8, 2019

I'm sorry to hear about this issue!

I haven't looked at this problem in detail, but I feel like one of two things is true (at least in an ideal world):

  1. Clearing the build cache is properly the responsibility of cargo, but it's failing. The ideal fix here would be to fix either cargo or the library that is causing problems.
  2. We can't count on cargo to clear things, in which case we should always clear it manually after a compiler upgrade. In this case, we don't really need a configuration variable which controls this.

Since you've looked at this problem more closely than I have, what do you think?

@ekump
Copy link
Author

ekump commented May 8, 2019

Clearing the build cache is properly the responsibility of cargo, but it's failing.

I agree. I decided to dig deeper into what is going on and I don't believe the buildpack should have to worry about the build cache. When the compiler is upgraded it triggers the project to rebuild its dependencies. But it doesn't clean the target folders for the crates in ~/.cargo/registry/src (or in the buildpack's case cache/cargo/registry/src). The same can be said for running cargo clean on a project. It doesn't actually clean the contents in cargo's registry, just the target/ folder for the current workspace.

The ideal fix here would be to fix either cargo or the library that is causing problems.

I think you're correct. It looks like not cleaning what's in cargo's registry is a known missing feature.

Fixing the library that is a problem is a good idea. I incorrectly assumed it was an issue with the buildpack because the problem only occurs on linux, and I primarily develop on macOS and the only time I was having an issue was when building on Heroku. I just spun up a linux VM and created a simple project with the library as a dependency and was able to recreate the failure by performing cargo build && cargo clean && cargo build. So, it's definitely not the buildpack's fault!

On linux, the custom build script for the library creates a symlink in its target/release/deps folder in cargo/registry/src. If the symlink already exists (because a previous build put it there) it will error out. Clearly this build script should be fixed. But I wonder if the buildpack cleaning cache/cargo/registry/src would be useful until Cargo handles this correctly?

We can't count on cargo to clear things, in which case we should always clear it manually after a compiler upgrade.

As I've investigated this more I've concluded this isn't an issue specific to the compiler updating. It just so happens that the only time the buildpack is rebuilding existing dependencies is when the compiler version is changed.

If you agree that it is a good idea to clean cache/cargo/registry/src then I think the correct thing to do is always perform an rm -rf cache/cargo/registry/src after cargo build. This will achieve the same effect with simpler code. It would also mean we don't have to maintain the rustc version file in the cache. It looks like cargo only references what is in cargo/registry/src when it's rebuilding a crate, which will theoretically only happen on builds with a new version of the compiler so it shouldn't adversely affect build times.

we don't really need a configuration variable which controls this

For my use case I'm ok with not making this a configuration variable. I made it configurable because I was not sure if there are other users who have a longer or more complex build process who don't want to clear the cargo registry folder.

Let me know what you think and I can update or close this PR.

@emk
Copy link
Owner

emk commented May 9, 2019

This sounds like an upstream bug that should be fixed upstream, if possible. But since that hasn't happened, let's go with a plan where we clear the entire build cache whenever the compiler version changes. (But don't clear anything if the compiler version stays the same.) Sound reasonable?

@ekump ekump force-pushed the feature/rebuild-cargo-when-rust-updated branch from b3243eb to 11a4591 Compare May 11, 2019 15:41
@ekump
Copy link
Author

ekump commented May 11, 2019

Sounds good to me. Should I remove the config var?

@ekump ekump closed this Jul 9, 2019
@ekump ekump deleted the feature/rebuild-cargo-when-rust-updated branch July 9, 2019 17:11
@ekump
Copy link
Author

ekump commented Jul 9, 2019

I fixed the issue with the crate that was causing the error.

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

Successfully merging this pull request may close these issues.

2 participants