Learn

What a build does

From source to a program

When you run cargo build, your Rust source becomes one program you can run. Two jobs make that happen: compiling turns code into machine code, and linking joins the pieces into one file.

Source goes to the compiler, the compiler's output goes to the linker, and the linker writes the program.

Crates

Cargo hands your code to the Rust compiler, rustc, one crate per run. A crate is one library or one program: your app is a crate, and so is each of its dependencies.

For each crate, rustc starts up fresh, does its work, and exits.

rustc keeps notes

It doesn't start from nothing, though. In a dev build rustc saves notes on disk for each crate: what it worked out about your code, and the machine code it made, in groups of functions called codegen units.

Next time it checks the crate against those notes and recompiles only the groups that changed. This is incremental compilation, on by default in the dev profile.

Crates use crates

Crates use other crates. Here app uses net and json, and both of them use core. Tap a crate to edit it, and watch which crates cargo runs rustc on again.

Four crates: app uses net and json, and net and json both use core. Editing a crate lights it and every crate that uses it, which cargo runs rustc on again, then the program, which is linked again.

Which crates?

You fix a typo in json. Which crates does cargo run rustc on again? Tap each one.

Start at json, then follow the arrows back to every crate that uses it.

Show the answer

json changed, and app uses json, so rustc runs again for both, reusing what it can from its notes. net and core don't use json, so cargo leaves them alone.

Why is it slow?

You change one line in core, which every other crate uses. Why can the build still take a while?

  1. rustc recompiles just that line, but very carefully.rustc reuses work in groups of functions, not lines, and cargo runs it again for core and for each crate that uses it.
  2. Cargo runs rustc again for core and every crate that uses it, and then the whole program is linked.Each of those runs starts up, reloads its notes and checks its crate again, and the link redoes the whole program. Incremental compilation makes each run cheaper, not free.
  3. Cargo downloads core again.Nothing is downloaded: core is your own code here. The time goes into compiling and linking.
Show the answer

Cargo runs rustc again for core and every crate that uses it, and then the whole program is linked. Each of those runs starts up, reloads its notes and checks its crate again, and the link redoes the whole program. Incremental compilation makes each run cheaper, not free.

blaze stays running

blaze is a compiler that stays running. Rather than a fresh rustc per crate reloading its notes from disk, one blaze keeps your whole program in memory, already read and type-checked, and when you save it compiles only the functions you changed, one by one rather than in groups.

Then, usually, it patches them into the program it already built, instead of linking it all again.

Same commands

You still type cargo's commands, with blaze in place of cargo: blaze build, blaze run, blaze test. These don't run rustc: blaze compiles the code itself. (Plain cargo build after blaze enable still runs rustc for some crates, for now.)

On a 200-crate workspace, an edit in the crate everything uses took 6.33 s with cargo and 0.60 s with blaze (measured once, by hand; more runs).

What happens on save?

You save an edit to one function. What does blaze do?

  1. Runs rustc on that crate, only faster.blaze build doesn't run rustc: blaze compiles the code itself, and only what changed.
  2. Rebuilds every crate from scratch, in parallel.The point is to do less work, not the same work faster: functions you didn't touch are kept.
  3. Compiles that function and patches it into the program it already built.It redoes the one function and patches it in, with no full link in the usual case.
Show the answer

Compiles that function and patches it into the program it already built. It redoes the one function and patches it in, with no full link in the usual case.

Discussion

Questions, corrections, ideas: anything about this page.