Skip to content

Conversation

@ranger-ross
Copy link
Member

@ranger-ross ranger-ross commented Sep 10, 2025

What does this PR try to resolve?

This PR re-organizes the build-dir file layout structure to a layout organized by "build unit" when -Zbuild-dir-new-layout is enabled.
See #15010 for the motivations and design discussions.

Below is file structure generated for a foo crate with a single dependency on syn.

$ tree -a target
target
├── CACHEDIR.TAG
├── debug
│   ├── build
│   │   ├── foo
│   │   │   └── 9f7d8db454c2e3a0
│   │   │       ├── deps
│   │   │       │   ├── foo-9f7d8db454c2e3a0
│   │   │       │   └── foo-9f7d8db454c2e3a0.d
│   │   │       └── fingerprint
│   │   │           ├── bin-foo
│   │   │           ├── bin-foo.json
│   │   │           ├── dep-bin-foo
│   │   │           └── invoked.timestamp
│   │   ├── proc-macro2
│   │   │   ├── 39344080ec273066
│   │   │   │   ├── deps
│   │   │   │   │   ├── libproc_macro2-39344080ec273066.rlib
│   │   │   │   │   ├── libproc_macro2-39344080ec273066.rmeta
│   │   │   │   │   └── proc_macro2-39344080ec273066.d
│   │   │   │   └── fingerprint
│   │   │   │       ├── dep-lib-proc_macro2
│   │   │   │       ├── invoked.timestamp
│   │   │   │       ├── lib-proc_macro2
│   │   │   │       └── lib-proc_macro2.json
│   │   │   ├── 8fc259c340d09182
│   │   │   │   ├── build-script
│   │   │   │   │   ├── build-script-build
│   │   │   │   │   ├── build_script_build-8fc259c340d09182
│   │   │   │   │   └── build_script_build-8fc259c340d09182.d
│   │   │   │   ├── deps
│   │   │   │   └── fingerprint
│   │   │   │       ├── build-script-build-script-build
│   │   │   │       ├── build-script-build-script-build.json
│   │   │   │       ├── dep-build-script-build-script-build
│   │   │   │       └── invoked.timestamp
│   │   │   └── a6c299e456bc1663
│   │   │       ├── build-script-execution
│   │   │       │   ├── invoked.timestamp
│   │   │       │   ├── out
│   │   │       │   ├── output
│   │   │       │   ├── root-output
│   │   │       │   └── stderr
│   │   │       ├── deps
│   │   │       └── fingerprint
│   │   │           ├── run-build-script-build-script-build
│   │   │           └── run-build-script-build-script-build.json
│   │   ├── quote
│   │   │   └── e95944fa29b3b7d5
│   │   │       ├── deps
│   │   │       │   ├── libquote-e95944fa29b3b7d5.rlib
│   │   │       │   ├── libquote-e95944fa29b3b7d5.rmeta
│   │   │       │   └── quote-e95944fa29b3b7d5.d
│   │   │       └── fingerprint
│   │   │           ├── dep-lib-quote
│   │   │           ├── invoked.timestamp
│   │   │           ├── lib-quote
│   │   │           └── lib-quote.json
│   │   ├── syn
│   │   │   └── a0dd360a8d0d85f9
│   │   │       ├── deps
│   │   │       │   ├── libsyn-a0dd360a8d0d85f9.rlib
│   │   │       │   ├── libsyn-a0dd360a8d0d85f9.rmeta
│   │   │       │   └── syn-a0dd360a8d0d85f9.d
│   │   │       └── fingerprint
│   │   │           ├── dep-lib-syn
│   │   │           ├── invoked.timestamp
│   │   │           ├── lib-syn
│   │   │           └── lib-syn.json
│   │   └── unicode-ident
│   │       └── 90d3c33eeb6b75ae
│   │           ├── deps
│   │           │   ├── libunicode_ident-90d3c33eeb6b75ae.rlib
│   │           │   ├── libunicode_ident-90d3c33eeb6b75ae.rmeta
│   │           │   └── unicode_ident-90d3c33eeb6b75ae.d
│   │           └── fingerprint
│   │               ├── dep-lib-unicode_ident
│   │               ├── invoked.timestamp
│   │               ├── lib-unicode_ident
│   │               └── lib-unicode_ident.json
│   ├── .cargo-lock
│   ├── examples
│   ├── foo
│   ├── foo.d
│   └── incremental
│       └── foo-2476dro80nq0n
│           ├── s-hbvjw5x5fa-1d58onh-7sam1xj7vrwy85uyr70f3vu2p
│           │   ├── 1z96gpvj66dpsd06phiqkocsr.o
│           │   ├── 8jaqpsn916x4kajeuk1b7rl12.o
│           │   ├── 8sv45ek5gkoxjdcr3b6nbgu2o.o
│           │   ├── 9yqg9fn9x870xvia9frlvvazg.o
│           │   ├── a5v36uvuoyp00oyvscfno2pce.o
│           │   ├── c2q7ff0mmsk4s1yg7s5ei1ryr.o
│           │   ├── dep-graph.bin
│           │   ├── query-cache.bin
│           │   └── work-products.bin
│           └── s-hbvjw5x5fa-1d58onh.lock
└── .rustc_info.json

36 directories, 62 files

For why incremental is where it is, see #15947 (comment)

As a side effect, we pass a lot more parameters to rustc, likely making cargo -v more annoying, similar to #13941.

How to test and review this PR?

This PR still needs to be more thoroughly tested. Thus far I have been testing on simple test crates.
Also see #15874 for potential test harness improvements that could be used by this PR.

Follow up actions

@rustbot rustbot added A-build-execution Area: anything dealing with executing the compiler A-layout Area: target output directory layout, naming, and organization Command-clean labels Sep 10, 2025
@epage
Copy link
Contributor

epage commented Sep 10, 2025

CC @Kobzol due to your work on rust-lang/rust#145408. If reducing duplicate search paths speeds up builds, I wonder what the impact will be of having more but pin point focused search paths will be.

@weihanglo
Copy link
Member

weihanglo commented Sep 10, 2025

If reducing duplicate search paths speeds up builds, I wonder what the impact will be of having more but pin point focused search paths will be.

Probably doesn't matter much because you still need to go through all of them to find what a crate need?

Edit: doesn't matter for primary crate, but for dependencies at the very root (like syn), it would be helpful.

@epage
Copy link
Contributor

epage commented Sep 10, 2025

Probably doesn't matter much because you still need to go through all of them to find what a crate need?

Currently, the search path includes each -Cextra-filename variant of a package's build. With this change, it will only see the variants relevant for this build.

@Kobzol
Copy link
Member

Kobzol commented Sep 10, 2025

I would be a bit worried about perf. in large scenarios (e.g. 1000 crates, which is not that uncommon), as I suspect that rustc does a bunch of linear (hopefully not quadratic) searches through these directories and files in them. I would suggest benchmarking on https://github.com/zed-industries/zed 😆

@weihanglo

This comment was marked as off-topic.

@weihanglo
Copy link
Member

Basically files under a search directory are preloaded and sorted and then binary search on them, so shouldn't be too bad? It may incur more opendir/readdir syscall though.

Like epage mentioned, it also help for transitive dependency loading less files.

But yeah worth some benchmark for larger projects.

@Kobzol
Copy link
Member

Kobzol commented Sep 11, 2025

Ah, I forgot that we do binary search already. In that case it will be probably fine, yeah.

Kobzol added a commit to Kobzol/rust that referenced this pull request Sep 11, 2025
@Kobzol
Copy link
Member

Kobzol commented Sep 11, 2025

I tried it on Zed and didn't see any perf. difference vs master, neither for clean builds nor for incremental rebuilds.

@epage
Copy link
Contributor

epage commented Sep 11, 2025

I tried it on Zed and didn't see any perf. difference vs master, neither for clean builds nor for incremental rebuilds.

If there is a different, it will most likely appear if you have multiple unique versions for each package, e.g. from

  • cargo check
  • cargo clippy
  • cargo build
  • cargo doc
  • changing RUSTFLAGS
  • changing features

@Kobzol
Copy link
Member

Kobzol commented Sep 11, 2025

I didn't see the rebuild time getting higher for Zed when I added multiple versions from different cargo invocations.

@epage
Copy link
Contributor

epage commented Sep 17, 2025

As a follow up to this PR, we may want to remove -Cextra-filename where possible since uniqueness is now guaranteed by the directory. Unsure if rustc relies on this for loading of rlibs or if we can only drop the hash from non-rlibs.

@epage
Copy link
Contributor

epage commented Sep 17, 2025

Another reason we might want to remove -Cextra-filename where possible is to reduce the risk of hitting windows path length issues

@rustbot

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. label Oct 1, 2025
@weihanglo
Copy link
Member

We got this pretty frequently these days.

---- package::reserved_windows_name stdout ----
running `D:\a\cargo\cargo\target\debug\cargo.exe package`

thread 'package::reserved_windows_name' (8372) panicked at tests\testsuite\package.rs:2997:10:

test failed running `D:\a\cargo\cargo\target\debug\cargo.exe package`
error: process exited with code 0 (expected 101)
--- stdout

--- stderr
warning: manifest has no documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
   Packaging foo v0.0.1 (D:\a\cargo\cargo\target\tmp\cit\t2560\foo)
    Updating `dummy-registry` index
    Packaged 4 files, 1.4KiB (877B compressed)
   Verifying foo v0.0.1 (D:\a\cargo\cargo\target\tmp\cit\t2560\foo)
 Downloading crates ...
  Downloaded bar v1.0.0 (registry `dummy-registry`)
   Compiling bar v1.0.0
   Compiling foo v0.0.1 (D:\a\cargo\cargo\target\tmp\cit\t2560\foo\target\package\foo-0.0.1)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.55s

Re-running jobs.

@ranger-ross ranger-ross force-pushed the impl-build-dir-layout branch from 47e0ec9 to b137a08 Compare October 4, 2025 04:28
@rustbot rustbot added the A-testing-cargo-itself Area: cargo's tests label Oct 4, 2025
@ranger-ross ranger-ross force-pushed the impl-build-dir-layout branch from c849440 to 54c5186 Compare October 9, 2025 15:48
@ranger-ross ranger-ross force-pushed the impl-build-dir-layout branch from 54c5186 to c89baf2 Compare October 10, 2025 07:27
Copy link
Contributor

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@epage epage added this pull request to the merge queue Oct 10, 2025
Merged via the queue into rust-lang:master with commit c169b66 Oct 10, 2025
25 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 10, 2025
bors added a commit to rust-lang/rust that referenced this pull request Oct 10, 2025
Update cargo submodule

22 commits in 801d9b4981dd07e3aecdca1ab86834c13615737e..81c3f77a467359c8be6bc747dc93ec66a6e4ce11
2025-10-04 13:30:15 +0000 to 2025-10-10 18:41:02 +0000
- docs(changelog): literal host-tuple support (rust-lang/cargo#16033)
- refactor: Define cargo script's target-dir using build-dir templating (rust-lang/cargo#16073)
- feat(build-dir): Reorganize build-dir layout (rust-lang/cargo#15947)
- refactor: unflatten `(String, Def)` to `ConfigValue` (rust-lang/cargo#16084)
- fix(tree): Switch from `--depth public` to `--edges public` (rust-lang/cargo#16081)
- docs(guide): Point out tools for reducing dependencies (rust-lang/cargo#16078)
- Allow to rustfix unused_variables lint. (rust-lang/cargo#16082)
- Fix test that assumes `CARGO_CFG_TARGET_FAMILY` is a single value (rust-lang/cargo#16079)
- Fix regression that swallowed json diagnostic explanations (rust-lang/cargo#16075)
- docs(ref): fix link to clippy incompatible_msrv lint (rust-lang/cargo#16077)
- Convert a few more diagnostics to reports (rust-lang/cargo#16066)
- fix(support): Add track_caller to know the actual failure (rust-lang/cargo#16069)
- fix(add): Report a missing source error for workspace dependencies  (rust-lang/cargo#16063)
- fix(script): Default bin.name to package.name  (rust-lang/cargo#16064)
- refactor(gctx): ConfigValue getter cleanup (rust-lang/cargo#16067)
- Fix unsafe_op_in_unsafe_fn for Windows (rust-lang/cargo#16058)
- Consider public dependencies when choosing a version in cargo add (rust-lang/cargo#1… (rust-lang/cargo#15966)
- docs: clarify panic-immediate-abort can be used in config (rust-lang/cargo#16054)
- fix(timings): compute codegen start time to draw dep lines (rust-lang/cargo#16055)
- chore: Added tracing span for build script execution (rust-lang/cargo#16053)
- test: null-terminated path for reserved windows name detection (rust-lang/cargo#16052)
- feat (publish): deprecate `--token` option (rust-lang/cargo#16046)

r? ghost
bors added a commit to rust-lang/rust that referenced this pull request Oct 11, 2025
Update cargo submodule

22 commits in 801d9b4981dd07e3aecdca1ab86834c13615737e..81c3f77a467359c8be6bc747dc93ec66a6e4ce11
2025-10-04 13:30:15 +0000 to 2025-10-10 18:41:02 +0000
- docs(changelog): literal host-tuple support (rust-lang/cargo#16033)
- refactor: Define cargo script's target-dir using build-dir templating (rust-lang/cargo#16073)
- feat(build-dir): Reorganize build-dir layout (rust-lang/cargo#15947)
- refactor: unflatten `(String, Def)` to `ConfigValue` (rust-lang/cargo#16084)
- fix(tree): Switch from `--depth public` to `--edges public` (rust-lang/cargo#16081)
- docs(guide): Point out tools for reducing dependencies (rust-lang/cargo#16078)
- Allow to rustfix unused_variables lint. (rust-lang/cargo#16082)
- Fix test that assumes `CARGO_CFG_TARGET_FAMILY` is a single value (rust-lang/cargo#16079)
- Fix regression that swallowed json diagnostic explanations (rust-lang/cargo#16075)
- docs(ref): fix link to clippy incompatible_msrv lint (rust-lang/cargo#16077)
- Convert a few more diagnostics to reports (rust-lang/cargo#16066)
- fix(support): Add track_caller to know the actual failure (rust-lang/cargo#16069)
- fix(add): Report a missing source error for workspace dependencies  (rust-lang/cargo#16063)
- fix(script): Default bin.name to package.name  (rust-lang/cargo#16064)
- refactor(gctx): ConfigValue getter cleanup (rust-lang/cargo#16067)
- Fix unsafe_op_in_unsafe_fn for Windows (rust-lang/cargo#16058)
- Consider public dependencies when choosing a version in cargo add (rust-lang/cargo#1… (rust-lang/cargo#15966)
- docs: clarify panic-immediate-abort can be used in config (rust-lang/cargo#16054)
- fix(timings): compute codegen start time to draw dep lines (rust-lang/cargo#16055)
- chore: Added tracing span for build script execution (rust-lang/cargo#16053)
- test: null-terminated path for reserved windows name detection (rust-lang/cargo#16052)
- feat (publish): deprecate `--token` option (rust-lang/cargo#16046)

r? ghost
@bjorn3
Copy link
Member

bjorn3 commented Oct 11, 2025

As a follow up to this PR, we may want to remove -Cextra-filename where possible since uniqueness is now guaranteed by the directory. Unsure if rustc relies on this for loading of rlibs or if we can only drop the hash from non-rlibs.

For dylibs and for everything shipped in the sysroot we do still need this. For the former you almost certainly want to copy the dylibs together into a single directory and even if you don't, the linker only records the filenames of dylibs in executables, not their full path. And for the latter, not doing so would cause conflicts between multiple rustc versions installed on a single system. Also it helps speed up loading dependencies when there are multiple dependencies with the same crate name.

As a side effect, we pass a lot more parameters to rustc, likely making cargo -v more annoying, similar to #13941.

Not just that, but there are hard limits on the cli length on most operating systems. This would make it impossible to just copy paste commands into your shell if you exceed the limit even if cargo were to use response files to workaround this limit for executions it does on its own.

bors added a commit to rust-lang/rust that referenced this pull request Oct 11, 2025
Update cargo submodule

22 commits in 801d9b4981dd07e3aecdca1ab86834c13615737e..81c3f77a467359c8be6bc747dc93ec66a6e4ce11
2025-10-04 13:30:15 +0000 to 2025-10-10 18:41:02 +0000
- docs(changelog): literal host-tuple support (rust-lang/cargo#16033)
- refactor: Define cargo script's target-dir using build-dir templating (rust-lang/cargo#16073)
- feat(build-dir): Reorganize build-dir layout (rust-lang/cargo#15947)
- refactor: unflatten `(String, Def)` to `ConfigValue` (rust-lang/cargo#16084)
- fix(tree): Switch from `--depth public` to `--edges public` (rust-lang/cargo#16081)
- docs(guide): Point out tools for reducing dependencies (rust-lang/cargo#16078)
- Allow to rustfix unused_variables lint. (rust-lang/cargo#16082)
- Fix test that assumes `CARGO_CFG_TARGET_FAMILY` is a single value (rust-lang/cargo#16079)
- Fix regression that swallowed json diagnostic explanations (rust-lang/cargo#16075)
- docs(ref): fix link to clippy incompatible_msrv lint (rust-lang/cargo#16077)
- Convert a few more diagnostics to reports (rust-lang/cargo#16066)
- fix(support): Add track_caller to know the actual failure (rust-lang/cargo#16069)
- fix(add): Report a missing source error for workspace dependencies  (rust-lang/cargo#16063)
- fix(script): Default bin.name to package.name  (rust-lang/cargo#16064)
- refactor(gctx): ConfigValue getter cleanup (rust-lang/cargo#16067)
- Fix unsafe_op_in_unsafe_fn for Windows (rust-lang/cargo#16058)
- Consider public dependencies when choosing a version in cargo add (rust-lang/cargo#1… (rust-lang/cargo#15966)
- docs: clarify panic-immediate-abort can be used in config (rust-lang/cargo#16054)
- fix(timings): compute codegen start time to draw dep lines (rust-lang/cargo#16055)
- chore: Added tracing span for build script execution (rust-lang/cargo#16053)
- test: null-terminated path for reserved windows name detection (rust-lang/cargo#16052)
- feat (publish): deprecate `--token` option (rust-lang/cargo#16046)

r? ghost
@rustbot rustbot added this to the 1.92.0 milestone Oct 11, 2025
rust-cloud-vms bot pushed a commit to makai410/rustc_public that referenced this pull request Oct 12, 2025
Update cargo submodule

22 commits in 801d9b4981dd07e3aecdca1ab86834c13615737e..81c3f77a467359c8be6bc747dc93ec66a6e4ce11
2025-10-04 13:30:15 +0000 to 2025-10-10 18:41:02 +0000
- docs(changelog): literal host-tuple support (rust-lang/cargo#16033)
- refactor: Define cargo script's target-dir using build-dir templating (rust-lang/cargo#16073)
- feat(build-dir): Reorganize build-dir layout (rust-lang/cargo#15947)
- refactor: unflatten `(String, Def)` to `ConfigValue` (rust-lang/cargo#16084)
- fix(tree): Switch from `--depth public` to `--edges public` (rust-lang/cargo#16081)
- docs(guide): Point out tools for reducing dependencies (rust-lang/cargo#16078)
- Allow to rustfix unused_variables lint. (rust-lang/cargo#16082)
- Fix test that assumes `CARGO_CFG_TARGET_FAMILY` is a single value (rust-lang/cargo#16079)
- Fix regression that swallowed json diagnostic explanations (rust-lang/cargo#16075)
- docs(ref): fix link to clippy incompatible_msrv lint (rust-lang/cargo#16077)
- Convert a few more diagnostics to reports (rust-lang/cargo#16066)
- fix(support): Add track_caller to know the actual failure (rust-lang/cargo#16069)
- fix(add): Report a missing source error for workspace dependencies  (rust-lang/cargo#16063)
- fix(script): Default bin.name to package.name  (rust-lang/cargo#16064)
- refactor(gctx): ConfigValue getter cleanup (rust-lang/cargo#16067)
- Fix unsafe_op_in_unsafe_fn for Windows (rust-lang/cargo#16058)
- Consider public dependencies when choosing a version in cargo add (rust-lang/cargo#1… (rust-lang/cargo#15966)
- docs: clarify panic-immediate-abort can be used in config (rust-lang/cargo#16054)
- fix(timings): compute codegen start time to draw dep lines (rust-lang/cargo#16055)
- chore: Added tracing span for build script execution (rust-lang/cargo#16053)
- test: null-terminated path for reserved windows name detection (rust-lang/cargo#16052)
- feat (publish): deprecate `--token` option (rust-lang/cargo#16046)

r? ghost
@ranger-ross ranger-ross deleted the impl-build-dir-layout branch October 14, 2025 14:24
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Oct 18, 2025
Update cargo submodule

22 commits in 801d9b4981dd07e3aecdca1ab86834c13615737e..81c3f77a467359c8be6bc747dc93ec66a6e4ce11
2025-10-04 13:30:15 +0000 to 2025-10-10 18:41:02 +0000
- docs(changelog): literal host-tuple support (rust-lang/cargo#16033)
- refactor: Define cargo script's target-dir using build-dir templating (rust-lang/cargo#16073)
- feat(build-dir): Reorganize build-dir layout (rust-lang/cargo#15947)
- refactor: unflatten `(String, Def)` to `ConfigValue` (rust-lang/cargo#16084)
- fix(tree): Switch from `--depth public` to `--edges public` (rust-lang/cargo#16081)
- docs(guide): Point out tools for reducing dependencies (rust-lang/cargo#16078)
- Allow to rustfix unused_variables lint. (rust-lang/cargo#16082)
- Fix test that assumes `CARGO_CFG_TARGET_FAMILY` is a single value (rust-lang/cargo#16079)
- Fix regression that swallowed json diagnostic explanations (rust-lang/cargo#16075)
- docs(ref): fix link to clippy incompatible_msrv lint (rust-lang/cargo#16077)
- Convert a few more diagnostics to reports (rust-lang/cargo#16066)
- fix(support): Add track_caller to know the actual failure (rust-lang/cargo#16069)
- fix(add): Report a missing source error for workspace dependencies  (rust-lang/cargo#16063)
- fix(script): Default bin.name to package.name  (rust-lang/cargo#16064)
- refactor(gctx): ConfigValue getter cleanup (rust-lang/cargo#16067)
- Fix unsafe_op_in_unsafe_fn for Windows (rust-lang/cargo#16058)
- Consider public dependencies when choosing a version in cargo add (rust-lang/cargo#1… (rust-lang/cargo#15966)
- docs: clarify panic-immediate-abort can be used in config (rust-lang/cargo#16054)
- fix(timings): compute codegen start time to draw dep lines (rust-lang/cargo#16055)
- chore: Added tracing span for build script execution (rust-lang/cargo#16053)
- test: null-terminated path for reserved windows name detection (rust-lang/cargo#16052)
- feat (publish): deprecate `--token` option (rust-lang/cargo#16046)

r? ghost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-build-execution Area: anything dealing with executing the compiler A-layout Area: target output directory layout, naming, and organization A-testing-cargo-itself Area: cargo's tests Command-clean S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants