diff --git a/src/cargo/core/compiler/build_runner/compilation_files.rs b/src/cargo/core/compiler/build_runner/compilation_files.rs index a914dc7056d..bbc13c1536a 100644 --- a/src/cargo/core/compiler/build_runner/compilation_files.rs +++ b/src/cargo/core/compiler/build_runner/compilation_files.rs @@ -11,6 +11,7 @@ use tracing::debug; use super::{BuildContext, BuildRunner, CompileKind, FileFlavor, Layout}; use crate::core::compiler::{CompileMode, CompileTarget, CrateType, FileType, Unit}; +use crate::core::features::is_new_build_dir_layout_enabled; use crate::core::{Target, TargetKind, Workspace}; use crate::util::{self, CargoResult, OnceExt, StableHasher}; @@ -245,7 +246,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> { /// Note that some units may share the same directory, so care should be /// taken in those cases! fn pkg_dir(&self, unit: &Unit) -> String { - let separator = match self.ws.gctx().cli_unstable().build_dir_new_layout { + let separator = match is_new_build_dir_layout_enabled(self.ws.gctx()) { true => "/", false => "-", }; diff --git a/src/cargo/core/compiler/build_runner/mod.rs b/src/cargo/core/compiler/build_runner/mod.rs index 02f3c62267a..f64284ee8e2 100644 --- a/src/cargo/core/compiler/build_runner/mod.rs +++ b/src/cargo/core/compiler/build_runner/mod.rs @@ -7,6 +7,7 @@ use std::sync::{Arc, Mutex}; use crate::core::PackageId; use crate::core::compiler::compilation::{self, UnitOutput}; use crate::core::compiler::{self, Unit, UserIntent, artifact}; +use crate::core::features::is_new_build_dir_layout_enabled; use crate::util::cache_lock::CacheLockMode; use crate::util::errors::CargoResult; use annotate_snippets::{Level, Message}; @@ -467,7 +468,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> { .root_output .insert(kind, artifact_dir.dest().to_path_buf()); } - if self.bcx.gctx.cli_unstable().build_dir_new_layout { + if is_new_build_dir_layout_enabled(self.bcx.gctx) { for (unit, _) in self.bcx.unit_graph.iter() { let dep_dir = self.files().deps_dir(unit); paths::create_dir_all(&dep_dir)?; diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 272e8198e27..664ccd41c9e 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -103,6 +103,7 @@ use crate::core::Workspace; use crate::core::compiler::CompileTarget; +use crate::core::features::is_new_build_dir_layout_enabled; use crate::util::flock::is_on_nfs_mount; use crate::util::{CargoResult, FileLock}; use cargo_util::paths; @@ -129,7 +130,7 @@ impl Layout { dest: &str, must_take_artifact_dir_lock: bool, ) -> CargoResult { - let is_new_layout = ws.gctx().cli_unstable().build_dir_new_layout; + let is_new_layout = is_new_build_dir_layout_enabled(ws.gctx()); let mut root = ws.target_dir(); let mut build_root = ws.build_dir(); if let Some(target) = target { diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 4ad36afdbb8..4df1bb57672 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -95,6 +95,7 @@ use self::unit_graph::UnitDep; use crate::core::compiler::future_incompat::FutureIncompatReport; use crate::core::compiler::timings::SectionTiming; pub use crate::core::compiler::unit::{Unit, UnitInterner}; +use crate::core::features::is_new_build_dir_layout_enabled; use crate::core::manifest::TargetSourcePath; use crate::core::profiles::{PanicStrategy, Profile, StripInner}; use crate::core::{Feature, PackageId, Target, Verbosity}; @@ -1825,7 +1826,7 @@ pub fn lib_search_paths( unit: &Unit, ) -> CargoResult> { let mut lib_search_paths = Vec::new(); - if build_runner.bcx.gctx.cli_unstable().build_dir_new_layout { + if is_new_build_dir_layout_enabled(build_runner.bcx.gctx) { let mut map = BTreeMap::new(); // Recursively add all dependency args to rustc process diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 36bb8414296..82f71ae3bc7 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -1556,3 +1556,13 @@ pub fn cargo_docs_link(path: &str) -> String { }; format!("https://doc.rust-lang.org/{url_channel}cargo/{path}") } + +/// Returns true of the new build dir layout is enabled. +#[allow(clippy::disallowed_methods)] +pub fn is_new_build_dir_layout_enabled(gctx: &GlobalContext) -> bool { + match std::env::var("CARGO_BUILD_DIR_LAYOUT_V2").as_deref() { + Ok("true") => true, + Ok("false") => false, + Ok(_) | Err(_) => gctx.cli_unstable().build_dir_new_layout, + } +} diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 7f445259dcc..28ad6e4be16 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -1,4 +1,5 @@ use crate::core::compiler::{CompileKind, CompileMode, Layout, RustcTargetData}; +use crate::core::features::is_new_build_dir_layout_enabled; use crate::core::profiles::Profiles; use crate::core::{PackageIdSpec, PackageIdSpecQuery, TargetKind, Workspace}; use crate::ops; @@ -196,7 +197,7 @@ fn clean_specs( clean_ctx.progress = Box::new(CleaningPackagesBar::new(clean_ctx.gctx, packages.len())); let mut dirs_to_clean = DirectoriesToClean::default(); - if clean_ctx.gctx.cli_unstable().build_dir_new_layout { + if is_new_build_dir_layout_enabled(clean_ctx.gctx) { for pkg in packages { clean_ctx.progress.on_cleaning_package(&pkg.name())?; diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 9e684dc1d9d..dcf158cfce8 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -2040,6 +2040,12 @@ enabled = true Enables the new build-dir filesystem layout. This layout change unblocks work towards caching and locking improvements. +In addition to `-Zbuild-dir-new-layout`, `CARGO_BUILD_DIR_LAYOUT_V2` also exists as +a way to opt in and out of the new layout during the transition period. +`CARGO_BUILD_DIR_LAYOUT_V2=true` allows users to opt in to the new layout, even on stable. +`CARGO_BUILD_DIR_LAYOUT_V2=false` allows users to opt out to the new layout. +This includes post stabilization but it's important to note that this is a temporary flag and will +eventually be removed. See the tracking issue for the transition plan and updates. ## compile-time-deps diff --git a/tests/testsuite/build_dir.rs b/tests/testsuite/build_dir.rs index 8c0e591dcaa..30b44d7def8 100644 --- a/tests/testsuite/build_dir.rs +++ b/tests/testsuite/build_dir.rs @@ -1094,6 +1094,63 @@ fn template_should_handle_reject_unmatched_brackets() { .run(); } +#[cargo_test] +fn fallback_env_var_should_allow_overriding() { + let p = project() + .file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#) + .file( + ".cargo/config.toml", + r#" + [build] + target-dir = "target-dir" + build-dir = "build-dir" + "#, + ) + .build(); + + // Stable + CARGO_BUILD_DIR_LAYOUT_V2=true should opt in + p.cargo("build") + .env("CARGO_BUILD_DIR_LAYOUT_V2", "true") + .enable_mac_dsym() + .run(); + + p.root().join("build-dir").assert_build_dir_layout(str![[r#" +[ROOT]/foo/build-dir/.rustc_info.json +[ROOT]/foo/build-dir/CACHEDIR.TAG +[ROOT]/foo/build-dir/debug/.cargo-lock +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/bin-foo +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/bin-foo.json +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/dep-bin-foo +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/invoked.timestamp +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/deps/foo[..][EXE] +[ROOT]/foo/build-dir/debug/build/foo/[HASH]/deps/foo[..].d + +"#]]); + + p.root().join("build-dir").rm_rf(); + + // Nightly + -Zbuild-dir-new-layout + CARGO_BUILD_DIR_LAYOUT_V2=false should allow user to fall + // back to old layout + p.cargo("-Zbuild-dir-new-layout build") + .masquerade_as_nightly_cargo(&["new build-dir layout"]) + .env("CARGO_BUILD_DIR_LAYOUT_V2", "false") + .enable_mac_dsym() + .run(); + + p.root().join("build-dir").assert_build_dir_layout(str![[r#" +[ROOT]/foo/build-dir/.rustc_info.json +[ROOT]/foo/build-dir/CACHEDIR.TAG +[ROOT]/foo/build-dir/debug/.cargo-lock +[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/bin-foo +[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/bin-foo.json +[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/dep-bin-foo +[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/invoked.timestamp +[ROOT]/foo/build-dir/debug/deps/foo[..][EXE] +[ROOT]/foo/build-dir/debug/deps/foo[..].d + +"#]]); +} + fn parse_workspace_manifest_path_hash(hash_dir: &PathBuf) -> PathBuf { // Since the hash will change between test runs simply find the first directories and assume // that is the hash dir. The format is a 2 char directory followed by the remaining hash in the