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?