Does a shared build cache for unrelated projects fit into the scope of Cargo?
Basically, I’d like cargo to search for and link against precompiled crates in a shared build cache. And by extension, that begs the question, how would such cache get populated? In my scenario, I actually prefer the project-defined artifacts NOT land in the cache (rather in a project-local target dir), where I suspect most build cache scenarios would want the final artifacts in the cache too. I could imagine options to tweaks where cargo outputs artifacts, or alternatively, separate cache manager (maybe a cargo plugin?) that manages a cache based on some cache manifest. I think some of these ideas overlap use cases of (but aren’t solved by) cargo workspaces, and on the other end of the spectrum, a distributed build cache seems ideal, but beyond the scope of my current needs.
I’m looking to understand how this might fit into or alongside cargo before I dive deeper into it and possibly contribute to a solution. The rest of my post here is just adding context to my motivation for such a feature.
I’m adding rust as a supported language to a lambda-like PaaS that focuses on hosting algorithms and ML projects as services (because I think there is some interesting ML work in the rust community). Fundamentally you start with a (WIP) template, transform input into output with arbitrary code, and publish it to an API. I’ve hit a wall in actually landing rust support because we’re very sensitive to build times (currently capped at 2 minutes) because of the impact to user experience, especially first experience.
The build environment, the build command, and some boilerplate interop code are fixed, but otherwise the project is user-managed (including Cargo.toml). There are 3 specific cases where we want to minimize user-perceived build time (in order of priority):
- First build of a newly created project (from a template that depends on hyper) should be <10 seconds
- After deploying rustc upgrades, users should not experience the long rebuild
- A lot of projects will add overlapping deps; it’s not a deal-breaker, but ideally we wouldn’t need to compile commonly added deps more than once
Currently, we have a compiled copy of the template project, and just copy its Cargo.lock and target dir into new projects. Anecdotally, it seems like a viable solution to #1. However, that leaves us recompiling every project as part of deploying rustc upgrades to address #2. Recompiling the same version of dependency crates again and again is a bit painful, which could be partially mitigated by first recompiling the template project and replacing target dir, but this sounds like a pretty lousy hack (and solves even less when the template’s Cargo.lock changes). It’s probably good enough to ship minimum viable rust support, but I’m super hesitant about keeping up with the 6-week-train-model until there is a robust cache story - I think the whole process is greatly improved with a shared build cache.
(Sorry if this seems like a re-post of a topic I recently made in the users forum; originally I was looking for immediate hacks, now I’m trying to get a sense of how this aligns with cargo as I consider contributing to a solution).