]> git.proxmox.com Git - cargo.git/blame - src/cargo/core/compiler/layout.rs
bump version to 0.66.0+pve1-1~bpo11+pve1
[cargo.git] / src / cargo / core / compiler / layout.rs
CommitLineData
9f5d9b81
AC
1//! Management of the directory layout of a build
2//!
3//! The directory layout is a little tricky at times, hence a separate file to
4//! house this logic. The current layout looks like this:
5//!
e26ef017 6//! ```text
39f0bd47
AC
7//! # This is the root directory for all output, the top-level package
8//! # places all of its output here.
9//! target/
9f5d9b81 10//!
16f8cc39
EH
11//! # Cache of `rustc -Vv` output for performance.
12//! .rustc-info.json
9f5d9b81 13//!
16f8cc39 14//! # All final artifacts are linked into this directory from `deps`.
abe92bcc
EH
15//! # Note that named profiles will soon be included as separate directories
16//! # here. They have a restricted format, similar to Rust identifiers, so
17//! # Cargo-specific directories added in the future should use some prefix
18//! # like `.` to avoid name collisions.
16f8cc39
EH
19//! debug/ # or release/
20//!
21//! # File used to lock the directory to prevent multiple cargo processes
22//! # from using it at the same time.
23//! .cargo-lock
24//!
25//! # Hidden directory that holds all of the fingerprint files for all
26//! # packages
27//! .fingerprint/
28//! # Each package is in a separate directory.
eac3b66b 29//! # Note that different target kinds have different filename prefixes.
16f8cc39
EH
30//! $pkgname-$META/
31//! # Set of source filenames for this package.
eac3b66b 32//! dep-lib-$targetname
16f8cc39
EH
33//! # Timestamp when this package was last built.
34//! invoked.timestamp
35//! # The fingerprint hash.
eac3b66b 36//! lib-$targetname
16f8cc39
EH
37//! # Detailed information used for logging the reason why
38//! # something is being recompiled.
eac3b66b 39//! lib-$targetname.json
bd73e8da
EH
40//! # The console output from the compiler. This is cached
41//! # so that warnings can be redisplayed for "fresh" units.
7438770b 42//! output-lib-$targetname
16f8cc39
EH
43//!
44//! # This is the root directory for all rustc artifacts except build
45//! # scripts, examples, and test and bench executables. Almost every
46//! # artifact should have a metadata hash added to its filename to
47//! # prevent collisions. One notable exception is dynamic libraries.
48//! deps/
49//!
7248f4b7
ST
50//! # Each artifact dependency gets in its own directory.
51//! /artifact/$pkgname-$META/$kind
52//!
16f8cc39
EH
53//! # Root directory for all compiled examples.
54//! examples/
55//!
56//! # Directory used to store incremental data for the compiler (when
57//! # incremental is enabled.
58//! incremental/
e969e495 59//!
28cabee6
EH
60//! # This is the location at which the output of all custom build
61//! # commands are rooted.
62//! build/
63//!
64//! # Each package gets its own directory where its build script and
65//! # script output are placed
66//! $pkgname-$META/ # For the build script itself.
67//! # The build script executable (name may be changed by user).
68//! build-script-build-$META
69//! # Hard link to build-script-build-$META.
70//! build-script-build
71//! # Dependency information generated by rustc.
72//! build-script-build-$META.d
73//! # Debug information, depending on platform and profile
74//! # settings.
75//! <debug symbols>
76//!
77//! # The package shows up twice with two different metadata hashes.
78//! $pkgname-$META/ # For the output of the build script.
79//! # Timestamp when the build script was last executed.
80//! invoked.timestamp
81//! # Directory where script can output files ($OUT_DIR).
82//! out/
83//! # Output from the build script.
84//! output
85//! # Path to `out`, used to help when the target directory is
86//! # moved.
87//! root-output
88//! # Stderr output from the build script.
89//! stderr
16f8cc39
EH
90//!
91//! # Output from rustdoc
92//! doc/
34ace110 93//!
16f8cc39
EH
94//! # Used by `cargo package` and `cargo publish` to build a `.crate` file.
95//! package/
96//!
97//! # Experimental feature for generated build scripts.
98//! .metabuild/
39f0bd47 99//! ```
16f8cc39
EH
100//!
101//! When cross-compiling, the layout is the same, except it appears in
102//! `target/$TRIPLE`.
9f5d9b81 103
ef425b77 104use crate::core::compiler::CompileTarget;
04ddd4d0 105use crate::core::Workspace;
16f8cc39 106use crate::util::{CargoResult, FileLock};
1dae5acb 107use cargo_util::paths;
5102de2b 108use std::path::{Path, PathBuf};
c2b23512 109
72899f5b
RD
110/// Contains the paths of all target output locations.
111///
112/// See module docs for more information.
9f5d9b81 113pub struct Layout {
16f8cc39
EH
114 /// The root directory: `/path/to/target`.
115 /// If cross compiling: `/path/to/target/$TRIPLE`.
a6dad622 116 root: PathBuf,
16f8cc39
EH
117 /// The final artifact destination: `$root/debug` (or `release`).
118 dest: PathBuf,
119 /// The directory with rustc artifacts: `$dest/deps`
a6dad622 120 deps: PathBuf,
16f8cc39 121 /// The directory for build scripts: `$dest/build`
a6dad622 122 build: PathBuf,
7248f4b7
ST
123 /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs: `$dest/deps/artifact`
124 artifact: PathBuf,
16f8cc39 125 /// The directory for incremental files: `$dest/incremental`
a5bf3b88 126 incremental: PathBuf,
16f8cc39 127 /// The directory for fingerprints: `$dest/.fingerprint`
a6dad622 128 fingerprint: PathBuf,
16f8cc39 129 /// The directory for examples: `$dest/examples`
a6dad622 130 examples: PathBuf,
16f8cc39
EH
131 /// The directory for rustdoc output: `$root/doc`
132 doc: PathBuf,
64bfe7f1
VK
133 /// The directory for temporary data of integration tests and benches: `$dest/tmp`
134 tmp: PathBuf,
16f8cc39
EH
135 /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this
136 /// struct is `drop`ped.
a9fd1c2c 137 _lock: FileLock,
9f5d9b81
AC
138}
139
9f5d9b81 140impl Layout {
ffd5e0fc 141 /// Calculate the paths for build output, lock the build directory, and return as a Layout.
72899f5b
RD
142 ///
143 /// This function will block if the directory is already locked.
144 ///
16f8cc39
EH
145 /// `dest` should be the final artifact directory name. Currently either
146 /// "debug" or "release".
ef425b77
AC
147 pub fn new(
148 ws: &Workspace<'_>,
149 target: Option<CompileTarget>,
150 dest: &str,
151 ) -> CargoResult<Layout> {
16f8cc39 152 let mut root = ws.target_dir();
ef425b77
AC
153 if let Some(target) = target {
154 root.push(target.short_name());
155 }
16f8cc39 156 let dest = root.join(dest);
643b6606
AC
157 // If the root directory doesn't already exist go ahead and create it
158 // here. Use this opportunity to exclude it from backups as well if the
159 // system supports it since this is a freshly created folder.
2793d7bf 160 //
f34b0869
JS
161 paths::create_dir_all_excluded_from_backups_atomic(root.as_path_unlocked())?;
162 // Now that the excluded from backups target root is created we can create the
163 // actual destination (sub)subdirectory.
164 paths::create_dir_all(dest.as_path_unlocked())?;
643b6606 165
a9fd1c2c
AC
166 // For now we don't do any more finer-grained locking on the artifact
167 // directory, so just lock the entire thing for the duration of this
168 // compile.
16f8cc39 169 let lock = dest.open_rw(".cargo-lock", ws.config(), "build directory")?;
a9fd1c2c 170 let root = root.into_path_unlocked();
16f8cc39 171 let dest = dest.into_path_unlocked();
7248f4b7
ST
172 let deps = dest.join("deps");
173 let artifact = deps.join("artifact");
a9fd1c2c
AC
174
175 Ok(Layout {
7248f4b7 176 deps,
16f8cc39 177 build: dest.join("build"),
7248f4b7 178 artifact,
16f8cc39
EH
179 incremental: dest.join("incremental"),
180 fingerprint: dest.join(".fingerprint"),
181 examples: dest.join("examples"),
182 doc: root.join("doc"),
4e7fe836 183 tmp: root.join("tmp"),
0247dc42 184 root,
16f8cc39 185 dest,
a9fd1c2c
AC
186 _lock: lock,
187 })
9f5d9b81
AC
188 }
189
f7c91ba6 190 /// Makes sure all directories stored in the Layout exist on the filesystem.
5102de2b
AC
191 pub fn prepare(&mut self) -> CargoResult<()> {
192 paths::create_dir_all(&self.deps)?;
193 paths::create_dir_all(&self.incremental)?;
194 paths::create_dir_all(&self.fingerprint)?;
195 paths::create_dir_all(&self.examples)?;
196 paths::create_dir_all(&self.build)?;
9f5d9b81 197
3fce5092 198 Ok(())
9f5d9b81
AC
199 }
200
16f8cc39 201 /// Fetch the destination path for final artifacts (`/…/target/debug`).
1e682848 202 pub fn dest(&self) -> &Path {
16f8cc39 203 &self.dest
1e682848 204 }
72899f5b 205 /// Fetch the deps path.
1e682848
AC
206 pub fn deps(&self) -> &Path {
207 &self.deps
208 }
72899f5b 209 /// Fetch the examples path.
1e682848
AC
210 pub fn examples(&self) -> &Path {
211 &self.examples
212 }
16f8cc39
EH
213 /// Fetch the doc path.
214 pub fn doc(&self) -> &Path {
215 &self.doc
216 }
217 /// Fetch the root path (`/…/target`).
1e682848
AC
218 pub fn root(&self) -> &Path {
219 &self.root
220 }
72899f5b 221 /// Fetch the incremental path.
1e682848
AC
222 pub fn incremental(&self) -> &Path {
223 &self.incremental
224 }
72899f5b 225 /// Fetch the fingerprint path.
1e682848
AC
226 pub fn fingerprint(&self) -> &Path {
227 &self.fingerprint
228 }
16f8cc39 229 /// Fetch the build script path.
1e682848
AC
230 pub fn build(&self) -> &Path {
231 &self.build
232 }
7248f4b7
ST
233 /// Fetch the artifact path.
234 pub fn artifact(&self) -> &Path {
235 &self.artifact
236 }
64bfe7f1
VK
237 /// Create and return the tmp path.
238 pub fn prepare_tmp(&self) -> CargoResult<&Path> {
239 paths::create_dir_all(&self.tmp)?;
240 Ok(&self.tmp)
241 }
9f5d9b81 242}