🎓 A1Learner
🔍
0 of 149 lessons completed

Rust Build Scripts

A build script is a small Rust program that Cargo runs before building a package. A build script can stamp a version into the code, or generate a table too big to type.

The script is a small Rust program

It lives in build.rs, in the project root — or name a different file with build = "path" in the [package] section. Cargo compiles it and runs it before building anything else in your package.

// build.rs
fn main() {
    println!("cargo:rustc-env=APP_VERSION=1.4.0");
}

Your code reads the stamped value

env! picks the value up while your code compiles:

fn main() {
    println!("version = {}", env!("APP_VERSION"));
}

Say which files the script reads

With a rerun line, Cargo re-runs the script only when one of those files changes. Without one, any change in the package re-runs it — safe, but slower than needed.

println!("cargo:rerun-if-changed=version.txt");

Generated code goes in OUT_DIR

The script writes generated files into the OUT_DIR folder. Your code pulls one in with include!:

include!(concat!(env!("OUT_DIR"), "/generated.rs"));

Turn on your own cfg

A rustc-cfg line switches on a condition of your own for this build — the Conditional Compilation lesson uses such conditions.

println!("cargo:rustc-cfg=fast_math");

Example

// build.rs
// fn main() {
//     println!("cargo:rustc-env=APP_VERSION=1.4.0");
// }
// src/main.rs then reads the value with env!("APP_VERSION")
fn main() {
    println!("1. Cargo runs build.rs first");
    println!("2. the script prints: cargo:rustc-env=APP_VERSION=1.4.0");
    println!("3. main.rs then prints: version = 1.4.0");
}

Key points

  • Cargo compiles build.rs.
  • It runs the script before building anything else in your package.
  • If the script fails, the whole build fails.
  • The script talks back by printing lines that start with cargo:.
  • Cargo reads those lines as instructions.
  • Any other printing is saved to a file under target/.
  • It is not shown on your screen.
  • Crates the script itself needs go under [build-dependencies].
  • The script runs on the machine doing the build.
  • So its libraries stay separate from the libraries of your program.

In this example, the comments show the whole mechanism in two small files. The build script prints one cargo: line, which sets the value APP_VERSION to 1.4.0 for this build. The main program reads that value while it compiles, with env!("APP_VERSION"), and prints it. The runnable code traces the three steps in order. The script runs first. The cargo: line carries the value across. The program prints version = 1.4.0.

Note

A build script can only give instructions for its own package.

It is a normal Rust program.

But it runs at build time.

It is not part of the program you ship.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

How does a build script pass a value into the code Cargo is about to compile?