In this lesson, you will learn how to use build.rs to execute custom code before your Rust project compiles.
What is a build script?
Normally, Cargo manages the compilation process automatically. However, sometimes you need to do extra work before your code is ready—like generating source code from a configuration file or linking against a C library installed on your computer. This is where build.rs comes in.
To create one, simply add a file named build.rs in the root of your project (next to Cargo.toml). Cargo will automatically detect this file, compile it first, and run it before building your main crate.
A Concrete Example
Imagine you want your program to display the exact date and time it was compiled. You can use your build script to generate a small Rust file that your main code can then include.
- Create
build.rs:
use std::fs;
fn main() {
// Generate a file with the current compile time
let time = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
fs::write("src/timestamp.rs", format!("pub const BUILD_TIME: u64 = {};", time)).unwrap();
// Tell Cargo to re-run this script only if files change
println!("cargo:rerun-if-changed=build.rs");
}
- Include it in
src/main.rs:
mod timestamp;
fn main() {
println!("This program was compiled at: {}", timestamp::BUILD_TIME);
}
Why use this?
- Code Generation: You can write logic that transforms data (like JSON or Protobuf files) into Rust structs automatically.
- System Linking: If your project depends on a native C++ library, the build script can find where that library is installed on your OS and pass the correct instructions to the compiler so the two can talk to each other.
Whenever you find yourself needing to perform "pre-flight" tasks that Cargo's standard configuration cannot handle, a build.rs script provides a full, powerful Rust environment to bridge the gap between your project and the outside world.
Key Takeaway: A build.rs file allows you to run custom Rust logic during the compilation process, enabling tasks like code generation and system-native library configuration.