Skip to content

Commit

Permalink
Seperated build directory from target directory
Browse files Browse the repository at this point in the history
This commits implements the seperation of the intermidate artifact
directory (called "build directory") from the target directory. (see rust-lang#14125)
  • Loading branch information
ranger-ross committed Jan 26, 2025
1 parent 599d493 commit 549dab9
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/cargo/core/compiler/build_runner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
});
}

super::output_depinfo(&mut self, unit)?;
if !self.bcx.gctx.cli_unstable().build_dir {
super::output_depinfo(&mut self, unit)?;
}
}

for (script_meta, output) in self.build_script_outputs.lock().unwrap().iter() {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ fn prepare_metabuild(
let path = unit
.pkg
.manifest()
.metabuild_path(build_runner.bcx.ws.target_dir());
.metabuild_path(build_runner.bcx.ws.build_dir());
paths::create_dir_all(path.parent().unwrap())?;
paths::write_if_changed(path, &output)?;
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/fingerprint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,7 @@ pub fn dep_info_loc(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> Path
/// Returns an absolute path that target directory.
/// All paths are rewritten to be relative to this.
fn target_root(build_runner: &BuildRunner<'_, '_>) -> PathBuf {
build_runner.bcx.ws.target_dir().into_path_unlocked()
build_runner.bcx.ws.build_dir().into_path_unlocked()
}

/// Reads the value from the old fingerprint hash file and compare.
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/future_incompat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl OnDiskReports {
}
let on_disk = serde_json::to_vec(&self).unwrap();
if let Err(e) = ws
.target_dir()
.build_dir()
.open_rw_exclusive_create(
FUTURE_INCOMPAT_FILE,
ws.gctx(),
Expand All @@ -191,7 +191,7 @@ impl OnDiskReports {

/// Loads the on-disk reports.
pub fn load(ws: &Workspace<'_>) -> CargoResult<OnDiskReports> {
let report_file = match ws.target_dir().open_ro_shared(
let report_file = match ws.build_dir().open_ro_shared(
FUTURE_INCOMPAT_FILE,
ws.gctx(),
"Future incompatible report",
Expand Down
36 changes: 31 additions & 5 deletions src/cargo/core/compiler/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ pub struct Layout {
/// 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.
///
/// NOTE: `_lock` and `_build_lock` can eventually be merged once #14125 is stablized.
/// Will be `None` when the build-directory and target-directory are the same path as we cannot
/// lock the same path twice.
_build_lock: Option<FileLock>,
}

impl Layout {
Expand All @@ -150,15 +156,22 @@ impl Layout {
dest: &str,
) -> CargoResult<Layout> {
let mut root = ws.target_dir();
let mut build_root = ws.build_dir();
if let Some(target) = target {
root.push(target.short_name());
build_root.push(target.short_name());
}
let build_dest = build_root.join(dest);
let dest = root.join(dest);
// If the root directory doesn't already exist go ahead and create it
// here. Use this opportunity to exclude it from backups as well if the
// system supports it since this is a freshly created folder.
//
paths::create_dir_all_excluded_from_backups_atomic(root.as_path_unlocked())?;
if root != build_root {
paths::create_dir_all_excluded_from_backups_atomic(build_root.as_path_unlocked())?;
}

// Now that the excluded from backups target root is created we can create the
// actual destination (sub)subdirectory.
paths::create_dir_all(dest.as_path_unlocked())?;
Expand All @@ -167,23 +180,36 @@ impl Layout {
// 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 build_lock = if root != build_root {
Some(build_dest.open_rw_exclusive_create(
".cargo-lock",
ws.gctx(),
"build directory",
)?)
} else {
None
};
let root = root.into_path_unlocked();
let build_root = build_root.into_path_unlocked();
let dest = dest.into_path_unlocked();
let deps = dest.join("deps");
let build_dest = build_dest.as_path_unlocked();
let deps = build_dest.join("deps");
let artifact = deps.join("artifact");

Ok(Layout {
deps,
build: dest.join("build"),
build: build_dest.join("build"),
artifact,
incremental: dest.join("incremental"),
fingerprint: dest.join(".fingerprint"),
incremental: build_dest.join("incremental"),
fingerprint: build_dest.join(".fingerprint"),
examples: dest.join("examples"),
doc: root.join("doc"),
tmp: root.join("tmp"),
tmp: build_root.join("tmp"),
root,
dest,
_lock: lock,
_build_lock: build_lock,
})
}

Expand Down
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ fn rustc(
let exec = exec.clone();

let root_output = build_runner.files().host_dest().to_path_buf();
let target_dir = build_runner.bcx.ws.target_dir().into_path_unlocked();
let target_dir = build_runner.bcx.ws.build_dir().into_path_unlocked();
let pkg_root = unit.pkg.root().to_path_buf();
let cwd = rustc
.get_cwd()
Expand Down Expand Up @@ -555,7 +555,7 @@ fn link_targets(
let path = unit
.pkg
.manifest()
.metabuild_path(build_runner.bcx.ws.target_dir());
.metabuild_path(build_runner.bcx.ws.build_dir());
target.set_src_path(TargetSourcePath::Path(path));
}

Expand Down
4 changes: 1 addition & 3 deletions src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,7 @@ impl<'gctx> Workspace<'gctx> {
if !self.gctx().cli_unstable().build_dir {
return self.target_dir();
}
self.build_dir
.clone()
.unwrap_or_else(|| self.default_target_dir())
self.build_dir.clone().unwrap_or_else(|| self.target_dir())
}

fn default_target_dir(&self) -> Filesystem {
Expand Down
9 changes: 8 additions & 1 deletion src/cargo/ops/cargo_package/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ pub fn run_verify(
let mut src = PathSource::new(&dst, id, ws.gctx());
let new_pkg = src.root_package()?;
let pkg_fingerprint = hash_all(&dst)?;
let mut ws = Workspace::ephemeral(new_pkg, gctx, None, true)?;

let target_dir = if gctx.cli_unstable().build_dir {
Some(ws.build_dir())
} else {
None
};

let mut ws = Workspace::ephemeral(new_pkg, gctx, target_dir, true)?;
if let Some(local_reg) = local_reg {
ws.add_local_overlay(
local_reg.upstream,
Expand Down
7 changes: 2 additions & 5 deletions src/cargo/util/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,8 @@ impl GlobalContext {

/// Gets the path to the `rustc` executable.
pub fn load_global_rustc(&self, ws: Option<&Workspace<'_>>) -> CargoResult<Rustc> {
let cache_location = ws.map(|ws| {
ws.target_dir()
.join(".rustc_info.json")
.into_path_unlocked()
});
let cache_location =
ws.map(|ws| ws.build_dir().join(".rustc_info.json").into_path_unlocked());
let wrapper = self.maybe_get_tool("rustc_wrapper", &self.build_config()?.rustc_wrapper);
let rustc_workspace_wrapper = self.maybe_get_tool(
"rustc_workspace_wrapper",
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/util/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions) -> Ca
pub fn path_args(ws: &Workspace<'_>, unit: &Unit) -> (PathBuf, PathBuf) {
let src = match unit.target.src_path() {
TargetSourcePath::Path(path) => path.to_path_buf(),
TargetSourcePath::Metabuild => unit.pkg.manifest().metabuild_path(ws.target_dir()),
TargetSourcePath::Metabuild => unit.pkg.manifest().metabuild_path(ws.build_dir()),
};
assert!(src.is_absolute());
if unit.pkg.package_id().source_id().is_path() {
Expand Down

0 comments on commit 549dab9

Please sign in to comment.