Cargo assumes you want to cache downloaded/built dependencies at the granularity of a unix user account. It's very easy to break things if you try to force current cargo cache dependencies at the per-project level and there's been no interest in caching things at a per-machine or shared-between-machines level. If duplicating compilation work is desirable to ensure some amount of noninterference, it should be supported to have a package cache per project. If we can treat Cargo as a pure function from inputs to outputs, we should be sharing these build results across the Internet, at least within the set of machines used by one person.
Cargo also refuses to follow the XDG directory specification for its per-unix-user configuration; it should put things in $XDG_CONFIG_HOME and $XDG_CACHE_HOME, but instead dumps both configuration and downloaded/compiled stuff in ~/.cargo.
> Cargo assumes you want to cache ... built dependencies at the granularity of a unix user account
This isn't true: actual build artifacts are cached in a per-project way (in `./target` by default). Cargo does download all packages to a user-shared directory, but this directory is essentially immutable, just a list of the source code.
Sharing more broadly than per-project is the form that is unreliable, things can change subtly between projects e.g. different targets, different compiler flags. Of course, cargo has essentially full information about everything involved in a build and so can track this---in the limit caching all the different configurations of each crate version---but I don't think it does currently (I recall an issue about it, but I cannot find it at the moment).
I like Nix-style caches myself, but a gc-cache command is needed in order to clean up only the stuff that isn't referenced anymore. I hope that's a design consideration.
> If we can treat Cargo as a pure function from inputs to outputs, we should be sharing these build results across the Internet, at least within the set of machines used by one person.
AFAIK, all it takes is a single `build.rs` to make rustc, and therefore Cargo, an impure 'function'. I'm not sure about compiler plugins, but I expect them to behave the same way.
I actually do this with one project, with a very small script that wraps cargo and sets $CARGO_HOME to a project local path before actually calling cargo. I keep a very short cargo.py and cargo.sh with my project.
It sounds like there's two obvious work-arounds, and I'm not sure if I'd consider them all that bad: 1) use a caching http proxy for the downloads (in my experience cargo itself is pretty quick), or 2) use a shared user account for building ("sudo -s cargo-build; ... ").
I'm not sure concurrently writing to a group-writeable cache-folder is such a hot idea -- even things like apt use a write-lock when doing updates.
I suppose a third option is to mount (or probably symlink) ~/.cargo on a filesystem with deduplication -- but that wouldn't buy you caching for free (might work well coupled with a caching http proxy though).
Cargo also refuses to follow the XDG directory specification for its per-unix-user configuration; it should put things in $XDG_CONFIG_HOME and $XDG_CACHE_HOME, but instead dumps both configuration and downloaded/compiled stuff in ~/.cargo.