362362mod dep_info;
363363mod dirty_reason;
364364
365+ use std:: cell:: OnceCell ;
365366use std:: collections:: hash_map:: { Entry , HashMap } ;
366367use std:: env;
368+ use std:: ffi:: OsString ;
367369use std:: fs;
368370use std:: fs:: File ;
369371use std:: hash:: { self , Hash , Hasher } ;
@@ -499,7 +501,7 @@ pub fn prepare_target(
499501 // thunk we can invoke on a foreign thread to calculate this.
500502 let build_script_outputs = Arc :: clone ( & build_runner. build_script_outputs ) ;
501503 let metadata = build_runner. get_run_build_script_metadata ( unit) ;
502- let ( gen_local, _overridden) = build_script_local_fingerprints ( build_runner, unit) ;
504+ let ( gen_local, _overridden) = build_script_local_fingerprints ( build_runner, unit) ? ;
503505 let output_path = build_runner. build_explicit_deps [ unit]
504506 . build_script_output
505507 . clone ( ) ;
@@ -796,14 +798,36 @@ pub enum StaleItem {
796798impl LocalFingerprint {
797799 /// Read the environment variable of the given env `key`, and creates a new
798800 /// [`LocalFingerprint::RerunIfEnvChanged`] for it.
799- ///
800- // TODO: This is allowed at this moment. Should figure out if it makes
801- // sense if permitting to read env from the config system.
802801 #[ allow( clippy:: disallowed_methods) ]
803- fn from_env < K : AsRef < str > > ( key : K ) -> LocalFingerprint {
802+ fn from_env < K : AsRef < str > > (
803+ key : K ,
804+ env_config : & Arc < HashMap < String , OsString > > ,
805+ env_config_insensitive : & Arc < OnceCell < HashMap < String , OsString > > > ,
806+ ) -> LocalFingerprint {
804807 let key = key. as_ref ( ) ;
805808 let var = key. to_owned ( ) ;
806- let val = env:: var ( key) . ok ( ) ;
809+ let val = if let Some ( val) = match env_config. get ( key) {
810+ Some ( value) => value. to_str ( ) . map ( |s| s. to_string ( ) ) ,
811+ None => {
812+ if cfg ! ( windows) {
813+ env_config_insensitive
814+ . get_or_init ( || {
815+ env_config
816+ . iter ( )
817+ . map ( |( k, v) | ( k. to_uppercase ( ) . clone ( ) , v. clone ( ) ) )
818+ . collect :: < HashMap < String , OsString > > ( )
819+ } )
820+ . get ( & key. to_uppercase ( ) )
821+ . and_then ( |s| s. to_str ( ) . map ( |s| s. to_string ( ) ) )
822+ } else {
823+ None
824+ }
825+ }
826+ } {
827+ Some ( val)
828+ } else {
829+ env:: var ( key) . ok ( )
830+ } ;
807831 LocalFingerprint :: RerunIfEnvChanged { var, val }
808832 }
809833
@@ -1573,7 +1597,7 @@ fn calculate_run_custom_build(
15731597 // the build script this means we'll be watching files and env vars.
15741598 // Otherwise if we haven't previously executed it we'll just start watching
15751599 // the whole crate.
1576- let ( gen_local, overridden) = build_script_local_fingerprints ( build_runner, unit) ;
1600+ let ( gen_local, overridden) = build_script_local_fingerprints ( build_runner, unit) ? ;
15771601 let deps = & build_runner. build_explicit_deps [ unit] ;
15781602 let local = ( gen_local) (
15791603 deps,
@@ -1667,7 +1691,7 @@ See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-change
16671691fn build_script_local_fingerprints (
16681692 build_runner : & mut BuildRunner < ' _ , ' _ > ,
16691693 unit : & Unit ,
1670- ) -> (
1694+ ) -> CargoResult < (
16711695 Box <
16721696 dyn FnOnce (
16731697 & BuildDeps ,
@@ -1676,20 +1700,20 @@ fn build_script_local_fingerprints(
16761700 + Send ,
16771701 > ,
16781702 bool ,
1679- ) {
1703+ ) > {
16801704 assert ! ( unit. mode. is_run_custom_build( ) ) ;
16811705 // First up, if this build script is entirely overridden, then we just
16821706 // return the hash of what we overrode it with. This is the easy case!
16831707 if let Some ( fingerprint) = build_script_override_fingerprint ( build_runner, unit) {
16841708 debug ! ( "override local fingerprints deps {}" , unit. pkg) ;
1685- return (
1709+ return Ok ( (
16861710 Box :: new (
16871711 move |_: & BuildDeps , _: Option < & dyn Fn ( ) -> CargoResult < String > > | {
16881712 Ok ( Some ( vec ! [ fingerprint] ) )
16891713 } ,
16901714 ) ,
16911715 true , // this is an overridden build script
1692- ) ;
1716+ ) ) ;
16931717 }
16941718
16951719 // ... Otherwise this is a "real" build script and we need to return a real
@@ -1701,6 +1725,7 @@ fn build_script_local_fingerprints(
17011725 // obvious.
17021726 let pkg_root = unit. pkg . root ( ) . to_path_buf ( ) ;
17031727 let target_dir = target_root ( build_runner) ;
1728+ let env_config = Arc :: clone ( build_runner. bcx . gctx . env_config ( ) ?) ;
17041729 let calculate =
17051730 move |deps : & BuildDeps , pkg_fingerprint : Option < & dyn Fn ( ) -> CargoResult < String > > | {
17061731 if deps. rerun_if_changed . is_empty ( ) && deps. rerun_if_env_changed . is_empty ( ) {
@@ -1730,11 +1755,16 @@ fn build_script_local_fingerprints(
17301755 // Ok so now we're in "new mode" where we can have files listed as
17311756 // dependencies as well as env vars listed as dependencies. Process
17321757 // them all here.
1733- Ok ( Some ( local_fingerprints_deps ( deps, & target_dir, & pkg_root) ) )
1758+ Ok ( Some ( local_fingerprints_deps (
1759+ deps,
1760+ & target_dir,
1761+ & pkg_root,
1762+ & env_config,
1763+ ) ) )
17341764 } ;
17351765
17361766 // Note that `false` == "not overridden"
1737- ( Box :: new ( calculate) , false )
1767+ Ok ( ( Box :: new ( calculate) , false ) )
17381768}
17391769
17401770/// Create a [`LocalFingerprint`] for an overridden build script.
@@ -1765,6 +1795,7 @@ fn local_fingerprints_deps(
17651795 deps : & BuildDeps ,
17661796 target_root : & Path ,
17671797 pkg_root : & Path ,
1798+ env_config : & Arc < HashMap < String , OsString > > ,
17681799) -> Vec < LocalFingerprint > {
17691800 debug ! ( "new local fingerprints deps {:?}" , pkg_root) ;
17701801 let mut local = Vec :: new ( ) ;
@@ -1785,11 +1816,11 @@ fn local_fingerprints_deps(
17851816 . collect ( ) ;
17861817 local. push ( LocalFingerprint :: RerunIfChanged { output, paths } ) ;
17871818 }
1788-
1819+ let env_config_insensitive = Arc :: new ( OnceCell :: new ( ) ) ;
17891820 local. extend (
17901821 deps. rerun_if_env_changed
17911822 . iter ( )
1792- . map ( LocalFingerprint :: from_env) ,
1823+ . map ( |s| LocalFingerprint :: from_env ( s , env_config , & env_config_insensitive ) ) ,
17931824 ) ;
17941825
17951826 local
0 commit comments