From 424e3b4cff48ed1d8bfbb2e7e541aa29b7dbbf0f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 24 Feb 2022 10:52:56 +0800 Subject: [PATCH] PoC: separate artifact dependencies from the files accessible in env-vars This needs more work and is just meant to show it can work at all. --- .../compiler/context/compilation_files.rs | 29 +++++++++++++++++++ src/cargo/core/compiler/layout.rs | 8 +++++ src/cargo/core/compiler/mod.rs | 13 +++++---- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index 079b7c695d7..9927874998c 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -205,6 +205,8 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { self.build_script_dir(unit) } else if unit.target.is_example() { self.layout(unit.kind).examples().to_path_buf() + } else if unit.artifact.is_true() { + self.artifact_dir_private(unit) } else { self.deps_dir(unit).to_path_buf() } @@ -291,6 +293,33 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { self.layout(CompileKind::Host).build().join(dir) } + /// Returns the directory for compiled artifacts files. + /// `/path/to/target/{debug,release}/deps/artifact/KIND/PKG-HASH` + pub(crate) fn artifact_dir_private(&self, unit: &Unit) -> PathBuf { + assert!(self.metas.contains_key(unit)); + assert!(unit.artifact.is_true()); + let dir = self.pkg_dir(unit); + let kind = match unit.target.kind() { + TargetKind::Bin => "bin", + TargetKind::Lib(lib_kinds) => match lib_kinds.as_slice() { + &[CrateType::Cdylib] => "cdylib", + &[CrateType::Staticlib] => "staticlib", + invalid => unreachable!( + "BUG: unexpected artifact library type(s): {:?} - these should have been split", + invalid + ), + }, + invalid => unreachable!( + "BUG: {:?} are not supposed to be used as artifacts", + invalid + ), + }; + self.layout(unit.kind) + .artifact_private() + .join(dir) + .join(kind) + } + /// Returns the directory for compiled artifacts files. /// `/path/to/target/{debug,release}/deps/artifact/KIND/PKG-HASH` pub(crate) fn artifact_dir(&self, unit: &Unit) -> PathBuf { diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index d92adffebb3..b1168d24efa 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -122,6 +122,8 @@ pub struct Layout { build: PathBuf, /// The directory for artifacts, i.e. binaries, cdylibs, staticlibs: `$dest/deps/artifact` artifact: PathBuf, + /// The directory for artifacts dependencies, which are undesirable in the exposed artifact directory + artifact_private: PathBuf, /// The directory for incremental files: `$dest/incremental` incremental: PathBuf, /// The directory for fingerprints: `$dest/.fingerprint` @@ -171,11 +173,13 @@ impl Layout { let dest = dest.into_path_unlocked(); let deps = dest.join("deps"); let artifact = deps.join("artifact"); + let artifact_private = deps.join("artifact_deps"); Ok(Layout { deps, build: dest.join("build"), artifact, + artifact_private, incremental: dest.join("incremental"), fingerprint: dest.join(".fingerprint"), examples: dest.join("examples"), @@ -234,6 +238,10 @@ impl Layout { pub fn artifact(&self) -> &Path { &self.artifact } + /// Fetch the private artifact path. + pub fn artifact_private(&self) -> &Path { + &self.artifact_private + } /// Create and return the tmp path. pub fn prepare_tmp(&self) -> CargoResult<&Path> { paths::create_dir_all(&self.tmp)?; diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 0429f92f656..97f3c8fe461 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -262,17 +262,20 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc) -> Car let fingerprint_dir = cx.files().fingerprint_dir(unit); let script_metadata = cx.find_build_script_metadata(unit); let is_local = unit.is_local(); - let artifact_dir = unit - .artifact - .is_true() - .then(|| cx.files().artifact_dir(unit)); + let artifact_dirs = unit.artifact.is_true().then(|| { + ( + cx.files().artifact_dir(unit), + cx.files().artifact_dir_private(unit), + ) + }); return Ok(Work::new(move |state| { // Artifacts are in a different location than typical units, // hence we must assure the crate- and target-dependent // directory is present. - if let Some(artifact_dir) = artifact_dir { + if let Some((artifact_dir, artifact_dir_private)) = artifact_dirs { paths::create_dir_all(artifact_dir)?; + paths::create_dir_all(artifact_dir_private)?; } // Only at runtime have we discovered what the extra -L and -l