Rust build.rs "OUT_DIR not set" / Generated File Missing in CI
Code that reads OUT_DIR - typically an include!(concat!(env!("OUT_DIR"), "/generated.rs")) - failed because OUT_DIR wasn’t set, or the build script didn’t write the file the code includes. OUT_DIR only exists for code invoked by Cargo with a build script present.
What this error means
The build fails with environment variable OUT_DIR not defined, or a No such file or directory for a generated file under OUT_DIR. It often appears when invoking rustc/a tool directly outside Cargo, or when build.rs didn’t run or didn’t emit the expected file.
error: environment variable `OUT_DIR` not defined at compile time
--> src/proto.rs:1:14
|
1 | include!(concat!(env!("OUT_DIR"), "/items.rs"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `std::env::var("OUT_DIR")` to read at run timeCommon causes
OUT_DIR only set by Cargo with a build script
Cargo sets OUT_DIR for the crate when a build.rs exists. Compiling the file directly with rustc, or in a crate that has no build script, leaves env!("OUT_DIR") undefined at compile time.
The build script didn’t write the included file
The code includes a file the build script is supposed to generate into OUT_DIR. If build.rs failed, was skipped, or wrote to the wrong path, the include can’t find it.
How to fix it
Build through Cargo with a real build.rs
Ensure the crate has a build.rs and is built by Cargo (not a bare rustc call), and that the script writes into OUT_DIR.
// build.rs
use std::{env, fs, path::Path};
fn main() {
let out = env::var("OUT_DIR").unwrap();
fs::write(Path::new(&out).join("items.rs"), "pub const N: u32 = 1;").unwrap();
}Confirm the script ran and emitted the file
- Run
cargo build -vvand check the build-script ran and its output path. - Verify the generated file exists under
target/.../build/<crate>-*/out/. - Make sure you’re compiling via Cargo, not invoking
rustcon the file directly.
How to prevent it
- Only read
OUT_DIRfrom code Cargo compiles for a crate that has abuild.rs. - Have the build script create the included file deterministically every run.
- Use
cargo build -vvto confirm build-script output when diagnosing.