From 877da76bd6f4002ab3be3b421218339b57c69679 Mon Sep 17 00:00:00 2001 From: heisen-li Date: Fri, 14 Jun 2024 17:00:09 +0800 Subject: [PATCH] fix(env): Get environment variables from the latest environment config --- .../compiler/build_context/target_info.rs | 6 ++++ src/cargo/core/compiler/fingerprint/mod.rs | 30 ++++++++++++++++--- tests/testsuite/build_script_env.rs | 12 ++------ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index ed4b04dc228d..3082abecea3a 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -21,6 +21,8 @@ use cargo_util::{paths, ProcessBuilder}; use serde::{Deserialize, Serialize}; use std::cell::RefCell; use std::collections::hash_map::{Entry, HashMap}; +use std::collections::BTreeMap; +use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; @@ -588,6 +590,10 @@ impl TargetInfo { .iter() .any(|sup| sup.as_str() == split.as_str()) } + + pub fn get_target_envs(&self) -> &BTreeMap> { + return self.crate_type_process.get_envs(); + } } /// Takes rustc output (using specialized command line args), and calculates the file prefix and diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 9d9eb4e4da4a..49a6039856bd 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -357,7 +357,9 @@ mod dirty_reason; use std::collections::hash_map::{Entry, HashMap}; +use std::collections::BTreeMap; use std::env; +use std::ffi::OsString; use std::hash::{self, Hash, Hasher}; use std::io; use std::path::{Path, PathBuf}; @@ -772,10 +774,18 @@ impl LocalFingerprint { // TODO: This is allowed at this moment. Should figure out if it makes // sense if permitting to read env from the config system. #[allow(clippy::disallowed_methods)] - fn from_env>(key: K) -> LocalFingerprint { + fn from_env>( + key: K, + envs: &BTreeMap>, + ) -> LocalFingerprint { let key = key.as_ref(); let var = key.to_owned(); - let val = env::var(key).ok(); + let val = envs + .get(key) + .map(|v| v.to_owned()) + .or_else(|| Some(env::var_os(key))) + .and_then(|os_str| os_str?.into_string().ok()); + LocalFingerprint::RerunIfEnvChanged { var, val } } @@ -1608,6 +1618,12 @@ fn build_script_local_fingerprints( bool, ) { assert!(unit.mode.is_run_custom_build()); + let envs = build_runner + .bcx + .target_data + .info(unit.kind) + .get_target_envs() + .clone(); // First up, if this build script is entirely overridden, then we just // return the hash of what we overrode it with. This is the easy case! if let Some(fingerprint) = build_script_override_fingerprint(build_runner, unit) { @@ -1660,7 +1676,12 @@ fn build_script_local_fingerprints( // Ok so now we're in "new mode" where we can have files listed as // dependencies as well as env vars listed as dependencies. Process // them all here. - Ok(Some(local_fingerprints_deps(deps, &target_dir, &pkg_root))) + Ok(Some(local_fingerprints_deps( + deps, + &target_dir, + &pkg_root, + &envs, + ))) }; // Note that `false` == "not overridden" @@ -1695,6 +1716,7 @@ fn local_fingerprints_deps( deps: &BuildDeps, target_root: &Path, pkg_root: &Path, + envs: &BTreeMap>, ) -> Vec { debug!("new local fingerprints deps {:?}", pkg_root); let mut local = Vec::new(); @@ -1719,7 +1741,7 @@ fn local_fingerprints_deps( local.extend( deps.rerun_if_env_changed .iter() - .map(LocalFingerprint::from_env), + .map(|v| LocalFingerprint::from_env(v, &envs)), ); local diff --git a/tests/testsuite/build_script_env.rs b/tests/testsuite/build_script_env.rs index e54a584029b6..639373036241 100644 --- a/tests/testsuite/build_script_env.rs +++ b/tests/testsuite/build_script_env.rs @@ -46,20 +46,12 @@ fn rerun_if_env_changes_config() { "#, ); - p.cargo("check") - .with_stderr_data(str![[r#" -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s - -"#]]) - .run(); - - p.cargo("clean").run(); p.cargo("check") .with_status(101) .with_stderr_data( "\ - [COMPILING] foo v0.1.0 ([ROOT]/foo) -[ERROR] failed to run custom build command for `foo v0.1.0 ([..])` +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[ERROR] failed to run custom build command for `foo v0.1.0 ([ROOT]/foo)` ...", ) .run();