build.rs
- Rust course
- Expert
- Lesson 37/46
- 4 min
Run pre-build code with build.rs.
build.rs
build.rs at the package root is a Rust program that runs before the crate is compiled. It's used to generate code, compile a C library (the cc crate), give instructions to the linker or add build information. It talks to Cargo through cargo:: lines on standard output:
// build.rs
fn main() {
println!("cargo::rerun-if-changed=sablon.txt");
println!("cargo::rustc-env=DERLEME_SURUM=1.4.0");
let cikis = std::env::var("OUT_DIR").unwrap();
std::fs::write(format!("{cikis}/uretilen.rs"), "pub const N: u32 = 42;").unwrap();
}
// src/main.rs
include!(concat!(env!("OUT_DIR"), "/uretilen.rs"));
const SURUM: &str = env!("DERLEME_SURUM");Generated files must only be written to OUT_DIR; the source folder isn't changed.
env! and option_env!
Environment variables at build time can be embedded into code. env! stops the build if the variable is missing; option_env! returns an Option<&'static str>:
const PAKET: &str = env!("CARGO_PKG_NAME"); // Cargo always defines it
const SURUM: &str = env!("CARGO_PKG_VERSION");
let kanal = option_env!("RUST_DERS_KANAL").unwrap_or("geliştirme");These values are read at compile time, not at runtime; they go into the binary as constants.
Practice Build-time information
Read the build-time variable with option_env!("RUST_DERS_KANAL"); if it isn't defined, use "geliştirme" and print it. (This variable isn't defined in the exercise environment.)
Starter code
fn main() {
// buraya yaz
}Sample solution
fn main() {
let kanal = option_env!("RUST_DERS_KANAL").unwrap_or("geliştirme");
println!("{}", kanal);
}Expected output
geliştirme
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What happens if <code>cargo::rerun-if-changed</code> isn't written?
- Compile error
- It runs once
- The script reruns when any file in the package changes; builds slow down Correct answer
- It never runs
Explanation: Declaring the right dependencies keeps incremental builds fast.
2 Optional environment variable
let kanal = ____!("RUST_DERS_KANAL").unwrap_or("geliştirme");
let kanal = option_env!("RUST_DERS_KANAL").unwrap_or("geliştirme");
Explanation: option_env! doesn't stop the build if the variable is missing; it gives None.
3 Item and role
| Term | Meaning |
|---|---|
build.rs |
Pre-build script |
OUT_DIR |
Generated files |
cargo::rerun-if-changed |
Rerun condition |
include! |
Pulls a file into the code |