Using Rust's Cargo as a build system
If everything is a cargo package, it makes for a pretty good build system.
Around the beginning of 2020, I started using Rust’s cargo
as my build system for a large repo. The repo has a couple
of languages; Rust, Go, Javascript, Typescript, CSS, and some bash.
In the past I’ve used Maven, NPM, Pants, Bazel, and Make, but they all required a lot fo setup and maintenance for multi-language targets. Maven is java focused, and since I’m not using java at the moment, extending it is pretty awkward. NPM is upsetting because it’s just a proxy to scripts and commands - not much structure. Pants and Bazel both have pretty full features, but seem to be focused on large organizations. Make has always been great - but I’ve found Cargo to be even better.
Why not use the one that I’m already using to build Rust binaries? Cargo has a lot of good features that Make has, but with the benefit of being in a full-featured programming language I already know and use. Here’s a rough list of the benefits:
- Checks dependency graph - bash and NPM can’t easily do this.
- Extensible using
build.rs
. Can easily run pre-build tasks, or if need be, use the build file that to call into shell scripts. - Already using cargo to manage dependencies, don’t need to install something else.
- Can extend development tooling beyond build with
cargo x
by creating custom cargo commands. - Watch specific files through the use of
cargo:rerun-if-changed
- equally flexible to Make, if not more so. - Depend on non-rust languages and targets by just making them a dependency.
All of these taken together allow me to run cargo build -p x
and build a package once, watching dependencies to see if
they changed.
It’s nice to be able to build frontend targets by calling shell scripts from build.rs
. For example, since all my
frontend code is built with esbuild, the cargo build script runs esbuild.sh
, which does
some building and cp
-ing of files.
If you’re already using Rust, give it a try. It’s simpler, easier, and far less time-consuming than almost all the other options.