Skip to content

Commit 07836ed

Browse files
committed
feat(build-dir): Reorganize build-dir layout
1 parent c519405 commit 07836ed

File tree

5 files changed

+135
-43
lines changed

5 files changed

+135
-43
lines changed

src/cargo/core/compiler/build_runner/compilation_files.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,28 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
255255
}
256256

257257
/// Returns the host `deps` directory path.
258-
pub fn host_deps(&self) -> &Path {
259-
self.host.deps()
258+
pub fn host_deps(&self, unit: &Unit) -> PathBuf {
259+
let dir = self.pkg_dir(unit);
260+
self.host.deps(&dir)
260261
}
261262

262263
/// Returns the directories where Rust crate dependencies are found for the
263264
/// specified unit.
264-
pub fn deps_dir(&self, unit: &Unit) -> &Path {
265-
self.layout(unit.kind).deps()
265+
pub fn deps_dir(&self, unit: &Unit) -> PathBuf {
266+
let dir = self.pkg_dir(unit);
267+
self.layout(unit.kind).deps(&dir)
266268
}
267269

268270
/// Directory where the fingerprint for the given unit should go.
269271
pub fn fingerprint_dir(&self, unit: &Unit) -> PathBuf {
270272
let dir = self.pkg_dir(unit);
271-
self.layout(unit.kind).fingerprint().join(dir)
273+
self.layout(unit.kind).fingerprint(&dir)
274+
}
275+
276+
/// Directory where incremental output for the given unit should go.
277+
pub fn incremental_dir(&self, unit: &Unit) -> PathBuf {
278+
let dir = self.pkg_dir(unit);
279+
self.layout(unit.kind).incremental(&dir)
272280
}
273281

274282
/// Returns the path for a file in the fingerprint directory.

src/cargo/core/compiler/build_runner/mod.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ use std::sync::{Arc, Mutex};
66

77
use crate::core::PackageId;
88
use crate::core::compiler::compilation::{self, UnitOutput};
9-
use crate::core::compiler::{self, Unit, artifact};
9+
use crate::core::compiler::{self, CompileTarget, Unit, artifact};
1010
use crate::util::cache_lock::CacheLockMode;
1111
use crate::util::errors::CargoResult;
1212
use anyhow::{Context as _, bail};
13+
use cargo_util::paths;
1314
use filetime::FileTime;
1415
use itertools::Itertools;
1516
use jobserver::Client;
@@ -358,11 +359,18 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
358359
#[tracing::instrument(skip_all)]
359360
pub fn prepare_units(&mut self) -> CargoResult<()> {
360361
let dest = self.bcx.profiles.get_dir_name();
361-
let host_layout = Layout::new(self.bcx.ws, None, &dest)?;
362+
let host = &self.compilation.host;
363+
let host_target = CompileTarget::new(&host)?;
364+
let host_layout = if self.bcx.gctx.cli_unstable().build_dir_new_layout {
365+
Layout::new(self.bcx.ws, Some(host_target), &dest, true)?
366+
} else {
367+
Layout::new(self.bcx.ws, None, &dest, true)?
368+
};
362369
let mut targets = HashMap::new();
363370
for kind in self.bcx.all_kinds.iter() {
364371
if let CompileKind::Target(target) = *kind {
365-
let layout = Layout::new(self.bcx.ws, Some(target), &dest)?;
372+
let is_host = target == host_target;
373+
let layout = Layout::new(self.bcx.ws, Some(target), &dest, is_host)?;
366374
targets.insert(target, layout);
367375
}
368376
}
@@ -401,9 +409,18 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
401409
self.compilation
402410
.root_output
403411
.insert(kind, layout.dest().to_path_buf());
404-
self.compilation
405-
.deps_output
406-
.insert(kind, layout.deps().to_path_buf());
412+
if self.bcx.gctx.cli_unstable().build_dir_new_layout {
413+
for (unit, _) in self.bcx.unit_graph.iter() {
414+
let dep_dir = self.files().deps_dir(unit);
415+
paths::create_dir_all(&dep_dir)?;
416+
self.compilation.deps_output.insert(kind, dep_dir);
417+
}
418+
} else {
419+
// TODO: FIX
420+
// self.compilation
421+
// .deps_output
422+
// .insert(kind, layout.deps().to_path_buf());
423+
}
407424
}
408425
Ok(())
409426
}

src/cargo/core/compiler/layout.rs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub struct Layout {
142142
/// Will be `None` when the build-dir and target-dir are the same path as we cannot
143143
/// lock the same path twice.
144144
_build_lock: Option<FileLock>,
145+
is_new_layout: bool,
145146
}
146147

147148
impl Layout {
@@ -155,12 +156,23 @@ impl Layout {
155156
ws: &Workspace<'_>,
156157
target: Option<CompileTarget>,
157158
dest: &str,
159+
is_host_layout: bool,
158160
) -> CargoResult<Layout> {
161+
let is_new_layout = true; // TODO: impl feature flag
159162
let mut root = ws.target_dir();
160163
let mut build_root = ws.build_dir();
161-
if let Some(target) = target {
162-
root.push(target.short_name());
163-
build_root.push(target.short_name());
164+
if is_new_layout {
165+
assert!(target.is_some());
166+
let short_name = target.as_ref().unwrap().short_name();
167+
if is_host_layout {
168+
root.push(short_name);
169+
}
170+
build_root.push(short_name);
171+
} else {
172+
if let Some(target) = target {
173+
root.push(target.short_name());
174+
build_root.push(target.short_name());
175+
}
164176
}
165177
let build_dest = build_root.join(dest);
166178
let dest = root.join(dest);
@@ -212,6 +224,7 @@ impl Layout {
212224
dest,
213225
_lock: lock,
214226
_build_lock: build_lock,
227+
is_new_layout: true, // TODO: impl feature flag
215228
})
216229
}
217230

@@ -232,8 +245,12 @@ impl Layout {
232245
&self.dest
233246
}
234247
/// Fetch the deps path.
235-
pub fn deps(&self) -> &Path {
236-
&self.deps
248+
pub fn deps(&self, pkg_dir: &str) -> PathBuf {
249+
if self.is_new_layout {
250+
self.build_unit(pkg_dir).join("deps")
251+
} else {
252+
self.deps.clone()
253+
}
237254
}
238255
/// Fetch the examples path.
239256
pub fn examples(&self) -> &Path {
@@ -252,12 +269,20 @@ impl Layout {
252269
&self.root
253270
}
254271
/// Fetch the incremental path.
255-
pub fn incremental(&self) -> &Path {
256-
&self.incremental
272+
pub fn incremental(&self, pkg_dir: &str) -> PathBuf {
273+
if self.is_new_layout {
274+
self.build_unit(pkg_dir).join("incremental")
275+
} else {
276+
self.incremental.clone()
277+
}
257278
}
258279
/// Fetch the fingerprint path.
259-
pub fn fingerprint(&self) -> &Path {
260-
&self.fingerprint
280+
pub fn fingerprint(&self, pkg_dir: &str) -> PathBuf {
281+
if self.is_new_layout {
282+
self.build_unit(pkg_dir).join("fingerprint")
283+
} else {
284+
self.fingerprint.clone()
285+
}
261286
}
262287
/// Fetch the build script path.
263288
pub fn build(&self) -> &Path {
@@ -267,6 +292,10 @@ impl Layout {
267292
pub fn artifact(&self) -> &Path {
268293
&self.artifact
269294
}
295+
/// Fetch the build unit path
296+
pub fn build_unit(&self, pkg_dir: &str) -> PathBuf {
297+
self.build().join(pkg_dir)
298+
}
270299
/// Create and return the tmp path.
271300
pub fn prepare_tmp(&self) -> CargoResult<&Path> {
272301
paths::create_dir_all(&self.tmp)?;

src/cargo/core/compiler/mod.rs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub mod unit_dependencies;
5656
pub mod unit_graph;
5757

5858
use std::borrow::Cow;
59-
use std::collections::{HashMap, HashSet};
59+
use std::collections::{BTreeMap, HashMap, HashSet};
6060
use std::env;
6161
use std::ffi::{OsStr, OsString};
6262
use std::fmt::Display;
@@ -66,6 +66,7 @@ use std::path::{Path, PathBuf};
6666
use std::sync::Arc;
6767

6868
use anyhow::{Context as _, Error};
69+
use itertools::Itertools;
6970
use lazycell::LazyCell;
7071
use tracing::{debug, instrument, trace};
7172

@@ -1347,12 +1348,8 @@ fn build_base_args(
13471348
.map(|s| s.as_ref()),
13481349
);
13491350
if incremental {
1350-
let dir = build_runner
1351-
.files()
1352-
.layout(unit.kind)
1353-
.incremental()
1354-
.as_os_str();
1355-
opt(cmd, "-C", "incremental=", Some(dir));
1351+
let dir = build_runner.files().incremental_dir(&unit);
1352+
opt(cmd, "-C", "incremental=", Some(dir.as_os_str()));
13561353
}
13571354

13581355
let pkg_hint_mostly_unused = match hints.mostly_unused {
@@ -1662,18 +1659,35 @@ fn build_deps_args(
16621659
unit: &Unit,
16631660
) -> CargoResult<()> {
16641661
let bcx = build_runner.bcx;
1665-
cmd.arg("-L").arg(&{
1666-
let mut deps = OsString::from("dependency=");
1667-
deps.push(build_runner.files().deps_dir(unit));
1668-
deps
1669-
});
1662+
if build_runner.bcx.gctx.cli_unstable().build_dir_new_layout {
1663+
let mut map = BTreeMap::new();
1664+
1665+
// Recusively add all depenendency args to rustc process
1666+
add_dep_arg(&mut map, build_runner, unit);
1667+
1668+
let paths = map.into_iter().map(|(_, path)| path).sorted_unstable();
1669+
1670+
for path in paths {
1671+
cmd.arg("-L").arg(&{
1672+
let mut deps = OsString::from("dependency=");
1673+
deps.push(path);
1674+
deps
1675+
});
1676+
}
1677+
} else {
1678+
cmd.arg("-L").arg(&{
1679+
let mut deps = OsString::from("dependency=");
1680+
deps.push(build_runner.files().deps_dir(unit));
1681+
deps
1682+
});
1683+
}
16701684

16711685
// Be sure that the host path is also listed. This'll ensure that proc macro
16721686
// dependencies are correctly found (for reexported macros).
16731687
if !unit.kind.is_host() {
16741688
cmd.arg("-L").arg(&{
16751689
let mut deps = OsString::from("dependency=");
1676-
deps.push(build_runner.files().host_deps());
1690+
deps.push(build_runner.files().host_deps(unit)); // TODO: Handle backwards compt
16771691
deps
16781692
});
16791693
}
@@ -1730,6 +1744,21 @@ fn build_deps_args(
17301744
Ok(())
17311745
}
17321746

1747+
fn add_dep_arg<'a, 'b: 'a>(
1748+
map: &mut BTreeMap<&'a Unit, PathBuf>,
1749+
build_runner: &'b BuildRunner<'b, '_>,
1750+
unit: &'a Unit,
1751+
) {
1752+
map.insert(&unit, build_runner.files().deps_dir(&unit));
1753+
1754+
for dep in build_runner.unit_deps(unit) {
1755+
if map.contains_key(&dep.unit) {
1756+
continue;
1757+
}
1758+
add_dep_arg(map, build_runner, &dep.unit);
1759+
}
1760+
}
1761+
17331762
/// Adds extra rustc flags and environment variables collected from the output
17341763
/// of a build-script to the command to execute, include custom environment
17351764
/// variables and `cfg`.

src/cargo/ops/cargo_clean.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::core::compiler::{CompileKind, CompileMode, Layout, RustcTargetData};
1+
use crate::core::compiler::{CompileKind, CompileMode, CompileTarget, Layout, RustcTargetData};
22
use crate::core::profiles::Profiles;
33
use crate::core::{PackageIdSpec, PackageIdSpecQuery, TargetKind, Workspace};
44
use crate::ops;
@@ -116,15 +116,22 @@ fn clean_specs(
116116
let target_data = RustcTargetData::new(ws, &requested_kinds)?;
117117
let (pkg_set, resolve) = ops::resolve_ws(ws, dry_run)?;
118118
let prof_dir_name = profiles.get_dir_name();
119-
let host_layout = Layout::new(ws, None, &prof_dir_name)?;
119+
let host_target = CompileTarget::new(target_data.short_name(&CompileKind::Host))?;
120+
let host_layout = if clean_ctx.gctx.cli_unstable().build_dir_new_layout {
121+
Layout::new(ws, Some(host_target), &prof_dir_name, true)?
122+
} else {
123+
Layout::new(ws, None, &prof_dir_name, true)?
124+
};
120125
// Convert requested kinds to a Vec of layouts.
121126
let target_layouts: Vec<(CompileKind, Layout)> = requested_kinds
122127
.into_iter()
123128
.filter_map(|kind| match kind {
124-
CompileKind::Target(target) => match Layout::new(ws, Some(target), &prof_dir_name) {
125-
Ok(layout) => Some(Ok((kind, layout))),
126-
Err(e) => Some(Err(e)),
127-
},
129+
CompileKind::Target(target) => {
130+
match Layout::new(ws, Some(target), &prof_dir_name, false) {
131+
Ok(layout) => Some(Ok((kind, layout))),
132+
Err(e) => Some(Err(e)),
133+
}
134+
}
128135
CompileKind::Host => None,
129136
})
130137
.collect::<CargoResult<_>>()?;
@@ -200,7 +207,7 @@ fn clean_specs(
200207

201208
// Clean fingerprints.
202209
for (_, layout) in &layouts_with_host {
203-
let dir = escape_glob_path(layout.fingerprint())?;
210+
let dir = escape_glob_path(&layout.fingerprint(&pkg_dir))?;
204211
clean_ctx
205212
.rm_rf_package_glob_containing_hash(&pkg.name(), &Path::new(&dir).join(&pkg_dir))?;
206213
}
@@ -236,8 +243,10 @@ fn clean_specs(
236243
(layout.build_examples(), Some(layout.examples()))
237244
}
238245
// Tests/benchmarks are never uplifted.
239-
TargetKind::Test | TargetKind::Bench => (layout.deps(), None),
240-
_ => (layout.deps(), Some(layout.dest())),
246+
// TODO: FIX
247+
// TargetKind::Test | TargetKind::Bench => (layout.deps(), None),
248+
// _ => (layout.deps(), Some(layout.dest())),
249+
_ => todo!(),
241250
};
242251
let mut dir_glob_str = escape_glob_path(dir)?;
243252
let dir_glob = Path::new(&dir_glob_str);
@@ -284,7 +293,7 @@ fn clean_specs(
284293
}
285294

286295
// TODO: what to do about build_script_build?
287-
let dir = escape_glob_path(layout.incremental())?;
296+
let dir = escape_glob_path(&layout.incremental(&pkg_dir))?;
288297
let incremental = Path::new(&dir).join(format!("{}-*", crate_name));
289298
clean_ctx.rm_rf_glob(&incremental)?;
290299
}

0 commit comments

Comments
 (0)