Help Shape the Future of Build Dir Layout v2 — Community Testing Now Open
The Cargo team is looking for community help testing the new experimental build directory layout, available in nightly builds via the cargo -Zbuild-dir-new-layout flag. Although the build directory layout is an internal implementation detail, many projects have come to depend on its undocumented specifics due to gaps in Cargo's feature set. A crater run has already been completed, but broader real-world testing is needed to surface tools and workflows that rely on the current layout — and to help those projects migrate or support both layouts.
How to Test This
Using nightly 2026-03-10 or later, run your test suite, release workflows, and any other processes that interact with the build or target directory, passing the -Zbuild-dir-new-layout flag:
$ cargo test -Zbuild-dir-new-layout
Note: If you encounter failures, the root cause may not be isolated to -Zbuild-dir-new-layout itself. Starting with Cargo 1.91, intermediate build artifacts (build-dir) and final artifacts (target-dir) can be stored separately. To isolate which change is responsible, you can reproduce the issue by running with only CARGO_BUILD_BUILD_DIR=build set. The Cargo team is also evaluating making a new build-dir the default in #16147.
Depending on what you find, useful outcomes include:
- Fixing issues locally in your own project
- Filing bugs against upstream tools and leaving a note on the tracking issue so others are aware
- Sharing general feedback directly on the tracking issue
Known failure modes to watch for:
- Inferring a
[[bin]]path from a[[test]]path:- For Cargo 1.94+, use
std::env::var_os("CARGO_BIN_EXE_*")— with the old inference as a fallback for older Cargo versions - Alternatively, use the compile-time
env!("CARGO_BIN_EXE_*")macro
- For Cargo 1.94+, use
- Build scripts resolving target-dir from their own binary path or
OUT_DIR: see Issue #13663 — existing workarounds will need updating for the new layout - Locating user-requested artifacts produced by rustc: see Issue #13672 — same applies here
Library support status as of publication:
- assert_cmd: fixed
- cli_test_dir: Issue #65
- compiletest_rs: Issue #309
- executable-path: fixed
- snapbox: fixed
- term-transcript: Issue #269
- test_bin: Issue #13
- trycmd: fixed
What Is Not Changing
The layout of final artifacts within the target directory remains unchanged, as does the nesting of build artifacts under the profile and target tuple directories.
What Is Changing
The current layout organizes artifacts by content type. The new layout instead scopes content by package name combined with a hash of the build unit and its inputs.
Here is the current layout for a workspace containing a package named lib and a package named bin, each with a build script:
build-dir/
├── CACHEDIR.TAG
└── debug/
├── .cargo-lock # file lock protecting access to this location
├── .fingerprint/ # build cache tracking
│ ├── bin-[BUILD_SCRIPT_RUN_HASH]/*
│ ├── bin-[BUILD_SCRIPT_BIN_HASH]/*
│ ├── bin-[HASH]/*
│ ├── lib-[BUILD_SCRIPT_RUN_HASH]/*
│ ├── lib-[BUILD_SCRIPT_BIN_HASH]/*
│ └── lib-[HASH]/*
├── build/
│ ├── bin-[BIN_HASH]/* # build script binary
│ ├── bin-[RUN_HASH]/out/ # build script run OUT_DIR
│ ├── bin-[RUN_HASH]/* # build script run cache
│ ├── lib-[BIN_HASH]/* # build script binary
│ ├── lib-[RUN_HASH]/out/ # build script run OUT_DIR
│ └── lib-[RUN_HASH]/* # build script run cache
├── deps/
│ ├── bin-[HASH]* # binary and debug information
│ ├── lib-[HASH]* # library and debug information
│ └── liblib-[HASH]* # library and debug information
├── examples/ # unused in this case
└── incremental/... # managed by rustc
And the proposed new layout:
build-dir/
├── CACHEDIR.TAG
└── debug/
├── .cargo-lock # file lock protecting access to this location
├── build/
│ ├── bin/ # package name
│ │ ├── [BUILD_SCRIPT_BIN_HASH]/
│ │ │ ├── fingerprint/* # build cache tracking
│ │ │ └── out/* # build script binary
│ │ ├── [BUILD_SCRIPT_RUN_HASH]/
│ │ │ ├── fingerprint/* # build cache tracking
│ │ │ ├── out/* # build script run OUT_DIR
│ │ │ └── run/* # build script run cache
│ │ └── [HASH]/
│ │ ├── fingerprint/* # build cache tracking
│ │ └── out/* # binary and debug information
│ └── lib/ # package name
│ ├── [BUILD_SCRIPT_BIN_HASH]/
│ │ ├── fingerprint/* # build cache tracking
│ │ └── out/* # build script binary
│ ├── [BUILD_SCRIPT_RUN_HASH]/
│ │ ├── fingerprint/* # build cache tracking
│ │ ├── out/* # build script run OUT_DIR
│ │ └── run/* # build script run cache
│ └── [HASH]/
│ ├── fingerprint/* # build cache tracking
│ └── out/* # library and debug information
└── incremental/... # managed by rustc
For a deeper dive into these Cargo internals, refer to the mod layout documentation.
Why Is This Being Done
ranger-ross has driven this effort as a foundational step toward cross-workspace caching. Tracking each cacheable build unit in its own self-contained directory is a prerequisite for that larger goal.
The new layout also unblocks work on:
- Automatic cleanup of stale build units, keeping disk usage stable over time
- More granular locking, so
cargo testand rust-analyzer no longer block each other
As a bonus, the work has also shown improvements in:
- Build performance, as intermediate artifacts accumulate in
deps/ - Preventing
deps/contents from pollutingPATHduring builds on Windows - Eliminating file collisions among intermediate artifacts
While the Cargo team does not officially endorse sharing a build-dir across workspaces, that last point should meaningfully reduce the risk for those who choose to do so anyway.
Future Work
The experience gained from this layout change will inform how the team approaches future layout migrations, including:
- Shortening path lengths to reduce the risk of errors for developers on Windows
- Exploring whether artifacts can be moved out of the
--profileand--targetdirectory hierarchy to enable broader sharing
Not all layout changes are being made at once — some are blocked on the forthcoming locking changes, which are themselves blocked on completing this layout change first.
The team also intends to pursue longer-term work on decoupling downstream projects from undocumented build-dir implementation details.