crane icon indicating copy to clipboard operation
crane copied to clipboard

Optimize Crane to Avoid Full Rebuilds on Single Dependency Updates

Open noverby opened this issue 1 year ago • 4 comments

Crane currently triggers a full rebuild of all dependencies, even when only a single dependency is updated. This behavior significantly impacts development efficiency in large monorepo Cargo projects, where rebuilding all dependencies can be prohibitively time-consuming.

Is there anything on the roadmap to improve on this?

noverby avatar Feb 21 '24 13:02 noverby

Probably not. There are existing issues about it. It's a fundamental design decision how crane works. There are some projects that attempt to work like this.

I'd advise that generally developers should be using nix dev shell and not have to go through nix build during normal work.

dpc avatar Feb 21 '24 16:02 dpc

Crane currently triggers a full rebuild of all dependencies, even when only a single dependency is updated.

This is an unfortunate consequence of the fact that changing Cargo.lock will result in Nix considering the sources as having changed and will perform a rebuild. There's no way out of this except for splitting up your build into multiple derivations and cleaning our any "unused" bits from Cargo.lock manually.

Otherwise there's also https://github.com/nix-community/crate2nix if you are okay with eschewing using cargo entirely


As for changes to crates from within the workspace it's a similar situation: changing any of the source tree will result in Nix rebuilding things. The best available option is to again split up your build into multiple derivations and "clean" any irrelevant crates to avoid unnecessary rebuilds.

I'll also link to existing discussion on this topic:

  • https://github.com/ipetkov/crane/discussions/341#discussioncomment-7331475
  • https://github.com/ipetkov/crane/issues/180

ipetkov avatar Feb 22 '24 00:02 ipetkov

@ipetkov There's no way out of this except for splitting up your build into multiple derivations and cleaning our any "unused" bits from Cargo.lock manually.

Is there some conceptual reason crane doesn't work this way and builds all dependencies at once? Or is it just because this way it's easier to implement? Because to me, that seems like a nice solution.

FireFragment avatar May 16 '24 19:05 FireFragment

It's harder as it requires basically re-implementing what cargo is doing.

Also, by storing all dependencies as one big artifact everything can be compressed together in the store, saving storage and making things actually faster.

In practice changes to Cargo.lock are infrequent and bulky anyway. Changes to one dependency can cause rebuilds for many dependent dependencies, and when people update dependencies they often do it in bulk as well (one big cargo update).

dpc avatar May 16 '24 20:05 dpc