Why does rust have to build crate instead of download already built binaryies?

If those packages on crate.io are already built, when I build my application, I only need to compile my own source and link to those libraries.
I don't know much about compiler, just feel that way.

There's a few reasons:

  • It's simpler: publishing is just uploading sources, and distribution becomes just downloading those source files.
  • It's safer: you can't publish source that says it does one thing and a binary that does something else that may be evil
  • It's smaller: binary libraries can get to thousands of times bigger than their sources
  • It's configurable: libraries can be configured with different features enabled based on your situation that can arbitrarily alter the compiled code
  • It's more optimizable: since the compiler can see the application and the library source it can do better optimizations that apply across both
  • It's even more optimizable: compilation can be configured to the specific target you're building for, taking advantage of later CPU features, for example

But most importantly:

  • It's possible: binary builds of Rust code not only depend on the the target platform, but the specific version of the Rust compiler, any time a new version of Rust releases every create would need to be compiled for every platform
24 Likes

Thank you.
Then is there a way to not only manage Cargo.toml but also binaries of those packages in my
repository?
In that way, I don't need to build them every time, but just use the binaries I pre-built once.
I see that under target\debug/release\build, there're lots of binaries of packages.
If I put it somewhere, how can I let cargo download them instead of building all the dependencies every time.
I know there is incremental compilation, just ignore it right now.

you cannot "manage" the binaries in the Cargo.tmol manifest, whatever "manage" means. but you can cache and re-use already built artifacts using a tool called sccache:

basically use it as rustc wrapper, by setting the environment variable RUSTC_WRAPPER. read the manual for detailed installation and usage instructions.

5 Likes

Another option is pointing your target directories to a common path with $CARGO_TARGET_DIR

You might be a bit disappointed as cargo will rebuild crates with different features enabled, and if you happen to be working on multiple projects at the same time this will cause them to block each other, but some people do like this setup.

1 Like

Thank you.
I'll try it later

Thank you.
I can't see the merit doing this if there is only one project, is there any?

If you only have one project, why are you rebuilding all the time? Are you talking about a build machine / CI?

Yes.
I'm thinking about doing it in GitHub action.

GitHub Actions has a decent cache system you can hook into: I haven't used it myself but here's a decent looking action: Rust Cache · Actions · GitHub Marketplace · GitHub

3 Likes

Thank you.
I'll definitely check it out.

@newme I have used this exact cache action and it works really well.
The only hicckup I found was that if you're using nightly to build for any reason, it will invalidate your cache frequently and build slowly more often.

2 Likes