From d89d1deddc7d536e7004708efeb32ff0ddbcb236 Mon Sep 17 00:00:00 2001 From: Ross Sullivan Date: Sun, 12 Oct 2025 11:31:15 +0900 Subject: [PATCH 1/4] refactor(layout): Moved cargo timings directory to `Layout` --- src/cargo/core/compiler/build_runner/compilation_files.rs | 5 +++++ src/cargo/core/compiler/layout.rs | 7 +++++++ src/cargo/core/compiler/timings.rs | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/build_runner/compilation_files.rs b/src/cargo/core/compiler/build_runner/compilation_files.rs index 23ea9867fd4..84eb5e27add 100644 --- a/src/cargo/core/compiler/build_runner/compilation_files.rs +++ b/src/cargo/core/compiler/build_runner/compilation_files.rs @@ -282,6 +282,11 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { self.layout(unit.kind).incremental() } + /// Directory where timing output should go. + pub fn timings_dir(&self) -> &Path { + self.host.timings() + } + /// Returns the path for a file in the fingerprint directory. /// /// The "prefix" should be something to distinguish the file from other diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 6049e90ec22..7bda56e9675 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -132,6 +132,8 @@ pub struct Layout { build_examples: PathBuf, /// The directory for rustdoc output: `$root/doc` doc: PathBuf, + /// The directory for --timings output + timings: PathBuf, /// The directory for temporary data of integration tests and benches: `$dest/tmp` tmp: PathBuf, /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this @@ -209,6 +211,7 @@ impl Layout { examples: dest.join("examples"), build_examples: build_dest.join("examples"), doc: root.join("doc"), + timings: root.join("cargo-timings"), tmp: build_root.join("tmp"), root, dest, @@ -268,6 +271,10 @@ impl Layout { pub fn incremental(&self) -> &Path { &self.incremental } + /// Fetch the timings path. + pub fn timings(&self) -> &Path { + &self.timings + } /// Fetch the fingerprint path. pub fn fingerprint(&self, pkg_dir: &str) -> PathBuf { if self.is_new_layout { diff --git a/src/cargo/core/compiler/timings.rs b/src/cargo/core/compiler/timings.rs index 4f8b2b82b39..999c1305815 100644 --- a/src/cargo/core/compiler/timings.rs +++ b/src/cargo/core/compiler/timings.rs @@ -441,7 +441,7 @@ impl<'gctx> Timings<'gctx> { ) -> CargoResult<()> { let duration = self.start.elapsed().as_secs_f64(); let timestamp = self.start_str.replace(&['-', ':'][..], ""); - let timings_path = build_runner.files().host_root().join("cargo-timings"); + let timings_path = build_runner.files().timings_dir(); paths::create_dir_all(&timings_path)?; let filename = timings_path.join(format!("cargo-timing-{}.html", timestamp)); let mut f = BufWriter::new(paths::create(&filename)?); From df7dbd65ed49b1d1a60e0e24962dbd9dd44d6ff1 Mon Sep 17 00:00:00 2001 From: Ross Sullivan Date: Sun, 12 Oct 2025 11:43:25 +0900 Subject: [PATCH 2/4] refactor(layout): Split `Layout` internally into `BuildDirLayout` and `ArtifactDirLayout` --- src/cargo/core/compiler/layout.rs | 136 ++++++++++++++++-------------- 1 file changed, 75 insertions(+), 61 deletions(-) diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 7bda56e9675..65eb869af11 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -111,39 +111,48 @@ use std::path::{Path, PathBuf}; /// /// See module docs for more information. pub struct Layout { - /// The root directory: `/path/to/target`. - /// If cross compiling: `/path/to/target/$TRIPLE`. - root: PathBuf, - /// The final artifact destination: `$root/debug` (or `release`). + artifact_dir: ArtifactDirLayout, + build_dir: BuildDirLayout, +} + +pub struct ArtifactDirLayout { + /// The final artifact destination: `/debug` (or `release`). dest: PathBuf, - /// The directory with rustc artifacts: `$dest/deps` + /// The directory for examples + examples: PathBuf, + /// The directory for rustdoc output + doc: PathBuf, + /// The directory for --timings output + timings: PathBuf, + /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this + /// struct is `drop`ped. + _lock: FileLock, +} + +pub struct BuildDirLayout { + /// The root directory: `/path/to/build-dir`. + /// If cross compiling: `/path/to/build-dir/$TRIPLE`. + root: PathBuf, + /// The directory with rustc artifacts deps: PathBuf, - /// The directory for build scripts: `$dest/build` + /// The primary directory for build files build: PathBuf, - /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs: `$dest/deps/artifact` + /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs artifact: PathBuf, - /// The directory for incremental files: `$dest/incremental` + /// The directory for incremental files incremental: PathBuf, - /// The directory for fingerprints: `$dest/.fingerprint` + /// The directory for fingerprints fingerprint: PathBuf, - /// The directory for examples: `$dest/examples` + /// The directory for pre-uplifted examples: `build-dir/debug/examples` examples: PathBuf, - /// The directory for pre-uplifted examples: `$build-dir/debug/examples` - build_examples: PathBuf, - /// The directory for rustdoc output: `$root/doc` - doc: PathBuf, - /// The directory for --timings output - timings: PathBuf, - /// The directory for temporary data of integration tests and benches: `$dest/tmp` + /// The directory for temporary data of integration tests and benches tmp: PathBuf, /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this /// struct is `drop`ped. - _lock: FileLock, - /// Same as `_lock` but for the build directory. /// /// Will be `None` when the build-dir and target-dir are the same path as we cannot /// lock the same path twice. - _build_lock: Option, + _lock: Option, is_new_layout: bool, } @@ -184,9 +193,10 @@ impl Layout { // For now we don't do any more finer-grained locking on the artifact // directory, so just lock the entire thing for the duration of this // compile. - let lock = dest.open_rw_exclusive_create(".cargo-lock", ws.gctx(), "build directory")?; + let artifact_dir_lock = + dest.open_rw_exclusive_create(".cargo-lock", ws.gctx(), "build directory")?; - let build_lock = if root != build_root { + let build_dir_lock = if root != build_root { Some(build_dest.open_rw_exclusive_create( ".cargo-lock", ws.gctx(), @@ -203,45 +213,49 @@ impl Layout { let artifact = deps.join("artifact"); Ok(Layout { - deps, - build: build_dest.join("build"), - artifact, - incremental: build_dest.join("incremental"), - fingerprint: build_dest.join(".fingerprint"), - examples: dest.join("examples"), - build_examples: build_dest.join("examples"), - doc: root.join("doc"), - timings: root.join("cargo-timings"), - tmp: build_root.join("tmp"), - root, - dest, - _lock: lock, - _build_lock: build_lock, - is_new_layout, + artifact_dir: ArtifactDirLayout { + dest: dest.clone(), + examples: dest.join("examples"), + doc: root.join("doc"), + timings: root.join("cargo-timings"), + _lock: artifact_dir_lock, + }, + build_dir: BuildDirLayout { + root: build_root.clone(), + deps, + build: build_dest.join("build"), + artifact, + incremental: build_dest.join("incremental"), + fingerprint: build_dest.join(".fingerprint"), + examples: build_dest.join("examples"), + tmp: build_root.join("tmp"), + _lock: build_dir_lock, + is_new_layout, + }, }) } /// Makes sure all directories stored in the Layout exist on the filesystem. pub fn prepare(&mut self) -> CargoResult<()> { - if !self.is_new_layout { - paths::create_dir_all(&self.deps)?; - paths::create_dir_all(&self.fingerprint)?; + if !self.build_dir.is_new_layout { + paths::create_dir_all(&self.build_dir.deps)?; + paths::create_dir_all(&self.build_dir.fingerprint)?; } - paths::create_dir_all(&self.incremental)?; - paths::create_dir_all(&self.examples)?; - paths::create_dir_all(&self.build_examples)?; - paths::create_dir_all(&self.build)?; + paths::create_dir_all(&self.build_dir.incremental)?; + paths::create_dir_all(&self.artifact_dir.examples)?; + paths::create_dir_all(&self.build_dir.examples)?; + paths::create_dir_all(&self.build_dir.build)?; Ok(()) } /// Fetch the destination path for final artifacts (`/…/target/debug`). pub fn dest(&self) -> &Path { - &self.dest + &self.artifact_dir.dest } /// Fetch the deps path. pub fn deps(&self, pkg_dir: &str) -> PathBuf { - if self.is_new_layout { + if self.build_dir.is_new_layout { self.build_unit(pkg_dir).join("deps") } else { self.legacy_deps().to_path_buf() @@ -249,35 +263,35 @@ impl Layout { } /// Fetch the deps path. (old layout) pub fn legacy_deps(&self) -> &Path { - &self.deps + &self.build_dir.deps } /// Fetch the examples path. pub fn examples(&self) -> &Path { - &self.examples + &self.artifact_dir.examples } /// Fetch the build examples path. pub fn build_examples(&self) -> &Path { - &self.build_examples + &self.build_dir.examples } /// Fetch the doc path. pub fn doc(&self) -> &Path { - &self.doc + &self.artifact_dir.doc } /// Fetch the root path (`/…/target`). pub fn root(&self) -> &Path { - &self.root + &self.build_dir.root } /// Fetch the incremental path. pub fn incremental(&self) -> &Path { - &self.incremental + &self.build_dir.incremental } /// Fetch the timings path. pub fn timings(&self) -> &Path { - &self.timings + &self.artifact_dir.timings } /// Fetch the fingerprint path. pub fn fingerprint(&self, pkg_dir: &str) -> PathBuf { - if self.is_new_layout { + if self.build_dir.is_new_layout { self.build_unit(pkg_dir).join("fingerprint") } else { self.legacy_fingerprint().to_path_buf().join(pkg_dir) @@ -285,15 +299,15 @@ impl Layout { } /// Fetch the fingerprint path. (old layout) pub fn legacy_fingerprint(&self) -> &Path { - &self.fingerprint + &self.build_dir.fingerprint } /// Fetch the build path. pub fn build(&self) -> &Path { - &self.build + &self.build_dir.build } /// Fetch the build script path. pub fn build_script(&self, pkg_dir: &str) -> PathBuf { - if self.is_new_layout { + if self.build_dir.is_new_layout { self.build_unit(pkg_dir).join("build-script") } else { self.build().join(pkg_dir) @@ -301,7 +315,7 @@ impl Layout { } /// Fetch the build script execution path. pub fn build_script_execution(&self, pkg_dir: &str) -> PathBuf { - if self.is_new_layout { + if self.build_dir.is_new_layout { self.build_unit(pkg_dir).join("build-script-execution") } else { self.build().join(pkg_dir) @@ -309,7 +323,7 @@ impl Layout { } /// Fetch the artifact path. pub fn artifact(&self) -> &Path { - &self.artifact + &self.build_dir.artifact } /// Fetch the build unit path pub fn build_unit(&self, pkg_dir: &str) -> PathBuf { @@ -317,7 +331,7 @@ impl Layout { } /// Create and return the tmp path. pub fn prepare_tmp(&self) -> CargoResult<&Path> { - paths::create_dir_all(&self.tmp)?; - Ok(&self.tmp) + paths::create_dir_all(&self.build_dir.tmp)?; + Ok(&self.build_dir.tmp) } } From ce7623796f2befd87e841f04ac5e67719ac30c0c Mon Sep 17 00:00:00 2001 From: Ross Sullivan Date: Sun, 12 Oct 2025 12:02:15 +0900 Subject: [PATCH 3/4] refactor(layout): Moved `Layout` accessors to `BuildDirLayout` and `ArtifactDirLayout` --- .../compiler/build_context/target_info.rs | 4 +- .../build_runner/compilation_files.rs | 45 +++++---- src/cargo/core/compiler/build_runner/mod.rs | 4 +- src/cargo/core/compiler/layout.rs | 98 ++++++++++++------- src/cargo/core/compiler/mod.rs | 6 +- src/cargo/core/compiler/output_depinfo.rs | 2 +- src/cargo/ops/cargo_clean.rs | 24 +++-- 7 files changed, 114 insertions(+), 69 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index f3a00a00750..90e501a2342 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -1141,7 +1141,7 @@ impl RustDocFingerprint { let fingerprint_path = build_runner .files() - .host_root() + .host_build_root() .join(".rustdoc_fingerprint.json"); let write_fingerprint = || -> CargoResult<()> { paths::write( @@ -1181,7 +1181,7 @@ impl RustDocFingerprint { .bcx .all_kinds .iter() - .map(|kind| build_runner.files().layout(*kind).doc()) + .map(|kind| build_runner.files().layout(*kind).artifact_dir().doc()) .filter(|path| path.exists()) .try_for_each(|path| clean_doc(path))?; write_fingerprint()?; diff --git a/src/cargo/core/compiler/build_runner/compilation_files.rs b/src/cargo/core/compiler/build_runner/compilation_files.rs index 84eb5e27add..34d4660c5be 100644 --- a/src/cargo/core/compiler/build_runner/compilation_files.rs +++ b/src/cargo/core/compiler/build_runner/compilation_files.rs @@ -211,13 +211,13 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { // Docscrape units need to have doc/ set as the out_dir so sources for reverse-dependencies // will be put into doc/ and not into deps/ where the *.examples files are stored. if unit.mode.is_doc() || unit.mode.is_doc_scrape() { - self.layout(unit.kind).doc().to_path_buf() + self.layout(unit.kind).artifact_dir().doc().to_path_buf() } else if unit.mode.is_doc_test() { panic!("doc tests do not have an out dir"); } else if unit.target.is_custom_build() { self.build_script_dir(unit) } else if unit.target.is_example() { - self.layout(unit.kind).build_examples().to_path_buf() + self.layout(unit.kind).build_dir().examples().to_path_buf() } else if unit.artifact.is_true() { self.artifact_dir(unit) } else { @@ -250,41 +250,41 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { /// Returns the final artifact path for the host (`/…/target/debug`) pub fn host_dest(&self) -> &Path { - self.host.dest() + self.host.artifact_dir().dest() } - /// Returns the root of the build output tree for the host (`/…/target`) - pub fn host_root(&self) -> &Path { - self.host.root() + /// Returns the root of the build output tree for the host (`/…/build-dir`) + pub fn host_build_root(&self) -> &Path { + self.host.build_dir().root() } /// Returns the host `deps` directory path. pub fn host_deps(&self, unit: &Unit) -> PathBuf { let dir = self.pkg_dir(unit); - self.host.deps(&dir) + self.host.build_dir().deps(&dir) } /// Returns the directories where Rust crate dependencies are found for the /// specified unit. pub fn deps_dir(&self, unit: &Unit) -> PathBuf { let dir = self.pkg_dir(unit); - self.layout(unit.kind).deps(&dir) + self.layout(unit.kind).build_dir().deps(&dir) } /// Directory where the fingerprint for the given unit should go. pub fn fingerprint_dir(&self, unit: &Unit) -> PathBuf { let dir = self.pkg_dir(unit); - self.layout(unit.kind).fingerprint(&dir) + self.layout(unit.kind).build_dir().fingerprint(&dir) } /// Directory where incremental output for the given unit should go. pub fn incremental_dir(&self, unit: &Unit) -> &Path { - self.layout(unit.kind).incremental() + self.layout(unit.kind).build_dir().incremental() } /// Directory where timing output should go. pub fn timings_dir(&self) -> &Path { - self.host.timings() + self.host.artifact_dir().timings() } /// Returns the path for a file in the fingerprint directory. @@ -319,7 +319,9 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { assert!(!unit.mode.is_run_custom_build()); assert!(self.metas.contains_key(unit)); let dir = self.pkg_dir(unit); - self.layout(CompileKind::Host).build_script(&dir) + self.layout(CompileKind::Host) + .build_dir() + .build_script(&dir) } /// Returns the directory for compiled artifacts files. @@ -343,7 +345,11 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { invalid ), }; - self.layout(unit.kind).artifact().join(dir).join(kind) + self.layout(unit.kind) + .build_dir() + .artifact() + .join(dir) + .join(kind) } /// Returns the directory where information about running a build script @@ -353,7 +359,9 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { assert!(unit.target.is_custom_build()); assert!(unit.mode.is_run_custom_build()); let dir = self.pkg_dir(unit); - self.layout(unit.kind).build_script_execution(&dir) + self.layout(unit.kind) + .build_dir() + .build_script_execution(&dir) } /// Returns the "`OUT_DIR`" directory for running a build script. @@ -372,7 +380,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { bcx: &BuildContext<'_, '_>, ) -> CargoResult { assert!(target.is_bin()); - let dest = self.layout(kind).dest(); + let dest = self.layout(kind).artifact_dir().dest(); let info = bcx.target_data.info(kind); let (file_types, _) = info .rustc_outputs( @@ -440,11 +448,14 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { let filename = file_type.uplift_filename(&unit.target); let uplift_path = if unit.target.is_example() { // Examples live in their own little world. - self.layout(unit.kind).examples().join(filename) + self.layout(unit.kind) + .artifact_dir() + .examples() + .join(filename) } else if unit.target.is_custom_build() { self.build_script_dir(unit).join(filename) } else { - self.layout(unit.kind).dest().join(filename) + self.layout(unit.kind).artifact_dir().dest().join(filename) }; if from_path == uplift_path { // This can happen with things like examples that reside in the diff --git a/src/cargo/core/compiler/build_runner/mod.rs b/src/cargo/core/compiler/build_runner/mod.rs index bb3bf67fe2e..1bee67f23db 100644 --- a/src/cargo/core/compiler/build_runner/mod.rs +++ b/src/cargo/core/compiler/build_runner/mod.rs @@ -401,7 +401,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> { let layout = files.layout(kind); self.compilation .root_output - .insert(kind, layout.dest().to_path_buf()); + .insert(kind, layout.artifact_dir().dest().to_path_buf()); if self.bcx.gctx.cli_unstable().build_dir_new_layout { for (unit, _) in self.bcx.unit_graph.iter() { let dep_dir = self.files().deps_dir(unit); @@ -411,7 +411,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> { } else { self.compilation .deps_output - .insert(kind, layout.legacy_deps().to_path_buf()); + .insert(kind, layout.build_dir().legacy_deps().to_path_buf()); } } Ok(()) diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 65eb869af11..c5f04286fa5 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -237,25 +237,62 @@ impl Layout { /// Makes sure all directories stored in the Layout exist on the filesystem. pub fn prepare(&mut self) -> CargoResult<()> { - if !self.build_dir.is_new_layout { - paths::create_dir_all(&self.build_dir.deps)?; - paths::create_dir_all(&self.build_dir.fingerprint)?; - } - paths::create_dir_all(&self.build_dir.incremental)?; - paths::create_dir_all(&self.artifact_dir.examples)?; - paths::create_dir_all(&self.build_dir.examples)?; - paths::create_dir_all(&self.build_dir.build)?; + self.artifact_dir.prepare()?; + self.build_dir.prepare()?; Ok(()) } + pub fn artifact_dir(&self) -> &ArtifactDirLayout { + &self.artifact_dir + } + + pub fn build_dir(&self) -> &BuildDirLayout { + &self.build_dir + } +} + +impl ArtifactDirLayout { + /// Makes sure all directories stored in the Layout exist on the filesystem. + pub fn prepare(&mut self) -> CargoResult<()> { + paths::create_dir_all(&self.examples)?; + + Ok(()) + } /// Fetch the destination path for final artifacts (`/…/target/debug`). pub fn dest(&self) -> &Path { - &self.artifact_dir.dest + &self.dest + } + /// Fetch the examples path. + pub fn examples(&self) -> &Path { + &self.examples + } + /// Fetch the doc path. + pub fn doc(&self) -> &Path { + &self.doc + } + /// Fetch the cargo-timings path. + pub fn timings(&self) -> &Path { + &self.timings + } +} + +impl BuildDirLayout { + /// Makes sure all directories stored in the Layout exist on the filesystem. + pub fn prepare(&mut self) -> CargoResult<()> { + if !self.is_new_layout { + paths::create_dir_all(&self.deps)?; + paths::create_dir_all(&self.fingerprint)?; + } + paths::create_dir_all(&self.incremental)?; + paths::create_dir_all(&self.examples)?; + paths::create_dir_all(&self.build)?; + + Ok(()) } /// Fetch the deps path. pub fn deps(&self, pkg_dir: &str) -> PathBuf { - if self.build_dir.is_new_layout { + if self.is_new_layout { self.build_unit(pkg_dir).join("deps") } else { self.legacy_deps().to_path_buf() @@ -263,35 +300,22 @@ impl Layout { } /// Fetch the deps path. (old layout) pub fn legacy_deps(&self) -> &Path { - &self.build_dir.deps + &self.deps } - /// Fetch the examples path. - pub fn examples(&self) -> &Path { - &self.artifact_dir.examples + pub fn root(&self) -> &Path { + &self.root } /// Fetch the build examples path. - pub fn build_examples(&self) -> &Path { - &self.build_dir.examples - } - /// Fetch the doc path. - pub fn doc(&self) -> &Path { - &self.artifact_dir.doc - } - /// Fetch the root path (`/…/target`). - pub fn root(&self) -> &Path { - &self.build_dir.root + pub fn examples(&self) -> &Path { + &self.examples } /// Fetch the incremental path. pub fn incremental(&self) -> &Path { - &self.build_dir.incremental - } - /// Fetch the timings path. - pub fn timings(&self) -> &Path { - &self.artifact_dir.timings + &self.incremental } /// Fetch the fingerprint path. pub fn fingerprint(&self, pkg_dir: &str) -> PathBuf { - if self.build_dir.is_new_layout { + if self.is_new_layout { self.build_unit(pkg_dir).join("fingerprint") } else { self.legacy_fingerprint().to_path_buf().join(pkg_dir) @@ -299,15 +323,15 @@ impl Layout { } /// Fetch the fingerprint path. (old layout) pub fn legacy_fingerprint(&self) -> &Path { - &self.build_dir.fingerprint + &self.fingerprint } /// Fetch the build path. pub fn build(&self) -> &Path { - &self.build_dir.build + &self.build } /// Fetch the build script path. pub fn build_script(&self, pkg_dir: &str) -> PathBuf { - if self.build_dir.is_new_layout { + if self.is_new_layout { self.build_unit(pkg_dir).join("build-script") } else { self.build().join(pkg_dir) @@ -315,7 +339,7 @@ impl Layout { } /// Fetch the build script execution path. pub fn build_script_execution(&self, pkg_dir: &str) -> PathBuf { - if self.build_dir.is_new_layout { + if self.is_new_layout { self.build_unit(pkg_dir).join("build-script-execution") } else { self.build().join(pkg_dir) @@ -323,7 +347,7 @@ impl Layout { } /// Fetch the artifact path. pub fn artifact(&self) -> &Path { - &self.build_dir.artifact + &self.artifact } /// Fetch the build unit path pub fn build_unit(&self, pkg_dir: &str) -> PathBuf { @@ -331,7 +355,7 @@ impl Layout { } /// Create and return the tmp path. pub fn prepare_tmp(&self) -> CargoResult<&Path> { - paths::create_dir_all(&self.build_dir.tmp)?; - Ok(&self.build_dir.tmp) + paths::create_dir_all(&self.tmp)?; + Ok(&self.tmp) } } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 48862882c05..adeae259af7 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -781,7 +781,11 @@ fn prepare_rustc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult } if unit.target.is_test() || unit.target.is_bench() { - let tmp = build_runner.files().layout(unit.kind).prepare_tmp()?; + let tmp = build_runner + .files() + .layout(unit.kind) + .build_dir() + .prepare_tmp()?; base.env("CARGO_TARGET_TMPDIR", tmp.display().to_string()); } diff --git a/src/cargo/core/compiler/output_depinfo.rs b/src/cargo/core/compiler/output_depinfo.rs index a62d9a0e8ac..77c9775ec5e 100644 --- a/src/cargo/core/compiler/output_depinfo.rs +++ b/src/cargo/core/compiler/output_depinfo.rs @@ -58,7 +58,7 @@ fn add_deps_for_unit( let dep_info_loc = fingerprint::dep_info_loc(build_runner, unit); if let Some(paths) = fingerprint::parse_dep_info( unit.pkg.root(), - build_runner.files().host_root(), + build_runner.files().host_build_root(), &dep_info_loc, )? { for path in paths.files.into_keys() { diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 1ab8dd5e937..a70972fae1b 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -200,7 +200,7 @@ fn clean_specs( // Clean fingerprints. for (_, layout) in &layouts_with_host { - let dir = escape_glob_path(layout.legacy_fingerprint())?; + let dir = escape_glob_path(layout.build_dir().legacy_fingerprint())?; clean_ctx .rm_rf_package_glob_containing_hash(&pkg.name(), &Path::new(&dir).join(&pkg_dir))?; } @@ -209,7 +209,7 @@ fn clean_specs( if target.is_custom_build() { // Get both the build_script_build and the output directory. for (_, layout) in &layouts_with_host { - let dir = escape_glob_path(layout.build())?; + let dir = escape_glob_path(layout.build_dir().build())?; clean_ctx.rm_rf_package_glob_containing_hash( &pkg.name(), &Path::new(&dir).join(&pkg_dir), @@ -227,7 +227,7 @@ fn clean_specs( ] { for (compile_kind, layout) in &layouts { if clean_ctx.gctx.cli_unstable().build_dir_new_layout { - let dir = layout.build_unit(&pkg.name()); + let dir = layout.build_dir().build_unit(&pkg.name()); clean_ctx.rm_rf_glob(&dir)?; continue; } @@ -237,12 +237,18 @@ fn clean_specs( .info(*compile_kind) .rustc_outputs(mode, target.kind(), triple, clean_ctx.gctx)?; let (dir, uplift_dir) = match target.kind() { - TargetKind::ExampleBin | TargetKind::ExampleLib(..) => { - (layout.build_examples(), Some(layout.examples())) - } + TargetKind::ExampleBin | TargetKind::ExampleLib(..) => ( + layout.build_dir().examples(), + Some(layout.artifact_dir().examples()), + ), // Tests/benchmarks are never uplifted. - TargetKind::Test | TargetKind::Bench => (layout.legacy_deps(), None), - _ => (layout.legacy_deps(), Some(layout.dest())), + TargetKind::Test | TargetKind::Bench => { + (layout.build_dir().legacy_deps(), None) + } + _ => ( + layout.build_dir().legacy_deps(), + Some(layout.artifact_dir().dest()), + ), }; let mut dir_glob_str = escape_glob_path(dir)?; let dir_glob = Path::new(&dir_glob_str); @@ -289,7 +295,7 @@ fn clean_specs( } // TODO: what to do about build_script_build? - let dir = escape_glob_path(layout.incremental())?; + let dir = escape_glob_path(layout.build_dir().incremental())?; let incremental = Path::new(&dir).join(format!("{}-*", crate_name)); clean_ctx.rm_rf_glob(&incremental)?; } From 03332a71c1a12be20ad3586df936968f893a45c8 Mon Sep 17 00:00:00 2001 From: Ross Sullivan Date: Mon, 13 Oct 2025 21:25:14 +0900 Subject: [PATCH 4/4] refactor(layout): Moved impl blocks next to thier struct definition --- src/cargo/core/compiler/layout.rs | 82 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index c5f04286fa5..d0207db8aea 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -115,47 +115,6 @@ pub struct Layout { build_dir: BuildDirLayout, } -pub struct ArtifactDirLayout { - /// The final artifact destination: `/debug` (or `release`). - dest: PathBuf, - /// The directory for examples - examples: PathBuf, - /// The directory for rustdoc output - doc: PathBuf, - /// The directory for --timings output - timings: PathBuf, - /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this - /// struct is `drop`ped. - _lock: FileLock, -} - -pub struct BuildDirLayout { - /// The root directory: `/path/to/build-dir`. - /// If cross compiling: `/path/to/build-dir/$TRIPLE`. - root: PathBuf, - /// The directory with rustc artifacts - deps: PathBuf, - /// The primary directory for build files - build: PathBuf, - /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs - artifact: PathBuf, - /// The directory for incremental files - incremental: PathBuf, - /// The directory for fingerprints - fingerprint: PathBuf, - /// The directory for pre-uplifted examples: `build-dir/debug/examples` - examples: PathBuf, - /// The directory for temporary data of integration tests and benches - tmp: PathBuf, - /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this - /// struct is `drop`ped. - /// - /// Will be `None` when the build-dir and target-dir are the same path as we cannot - /// lock the same path twice. - _lock: Option, - is_new_layout: bool, -} - impl Layout { /// Calculate the paths for build output, lock the build directory, and return as a Layout. /// @@ -252,6 +211,20 @@ impl Layout { } } +pub struct ArtifactDirLayout { + /// The final artifact destination: `/debug` (or `release`). + dest: PathBuf, + /// The directory for examples + examples: PathBuf, + /// The directory for rustdoc output + doc: PathBuf, + /// The directory for --timings output + timings: PathBuf, + /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this + /// struct is `drop`ped. + _lock: FileLock, +} + impl ArtifactDirLayout { /// Makes sure all directories stored in the Layout exist on the filesystem. pub fn prepare(&mut self) -> CargoResult<()> { @@ -277,6 +250,33 @@ impl ArtifactDirLayout { } } +pub struct BuildDirLayout { + /// The root directory: `/path/to/build-dir`. + /// If cross compiling: `/path/to/build-dir/$TRIPLE`. + root: PathBuf, + /// The directory with rustc artifacts + deps: PathBuf, + /// The primary directory for build files + build: PathBuf, + /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs + artifact: PathBuf, + /// The directory for incremental files + incremental: PathBuf, + /// The directory for fingerprints + fingerprint: PathBuf, + /// The directory for pre-uplifted examples: `build-dir/debug/examples` + examples: PathBuf, + /// The directory for temporary data of integration tests and benches + tmp: PathBuf, + /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this + /// struct is `drop`ped. + /// + /// Will be `None` when the build-dir and target-dir are the same path as we cannot + /// lock the same path twice. + _lock: Option, + is_new_layout: bool, +} + impl BuildDirLayout { /// Makes sure all directories stored in the Layout exist on the filesystem. pub fn prepare(&mut self) -> CargoResult<()> {