From 0a264a9d986df9a6fa7c06ada0757cffbb80be07 Mon Sep 17 00:00:00 2001 From: heisen-li Date: Thu, 13 Jun 2024 19:35:46 +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 | 33 ++++++++++++++++--- tests/testsuite/build_script_env.rs | 12 ++----- 3 files changed, 37 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..152499fd9856 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) -> CargoResult<&BTreeMap>> { + return Ok(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..ea8bdb8f288f 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,20 @@ 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) + .and_then(|opt| { + opt.as_ref() + .and_then(|os_str| os_str.clone().into_string().ok()) + }) + .or_else(|| env::var_os(key).and_then(|os_str| os_str.into_string().ok())); + LocalFingerprint::RerunIfEnvChanged { var, val } } @@ -1608,6 +1620,13 @@ 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() + .unwrap() + .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 +1679,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 +1719,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 +1744,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();