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,38 @@ 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| str:: to_string ( s) ) ,
811+ None => {
812+ if cfg ! ( windows) {
813+ let env_config_insensitive = env_config_insensitive. get_or_init ( || {
814+ env_config
815+ . iter ( )
816+ . map ( |( k, v) | ( k. to_uppercase ( ) . clone ( ) , v. clone ( ) ) )
817+ . collect ( )
818+ } ) ;
819+ let val = env_config_insensitive
820+ . get ( & key. to_uppercase ( ) )
821+ . and_then ( |s| s. to_str ( ) . map ( |s| str:: to_string ( s) ) ) ;
822+
823+ val
824+ } else {
825+ None
826+ }
827+ }
828+ } {
829+ Some ( val)
830+ } else {
831+ env:: var ( key) . ok ( )
832+ } ;
807833 LocalFingerprint :: RerunIfEnvChanged { var, val }
808834 }
809835
@@ -1573,7 +1599,7 @@ fn calculate_run_custom_build(
15731599 // the build script this means we'll be watching files and env vars.
15741600 // Otherwise if we haven't previously executed it we'll just start watching
15751601 // the whole crate.
1576- let ( gen_local, overridden) = build_script_local_fingerprints ( build_runner, unit) ;
1602+ let ( gen_local, overridden) = build_script_local_fingerprints ( build_runner, unit) ? ;
15771603 let deps = & build_runner. build_explicit_deps [ unit] ;
15781604 let local = ( gen_local) (
15791605 deps,
@@ -1667,7 +1693,7 @@ See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-change
16671693fn build_script_local_fingerprints (
16681694 build_runner : & mut BuildRunner < ' _ , ' _ > ,
16691695 unit : & Unit ,
1670- ) -> (
1696+ ) -> CargoResult < (
16711697 Box <
16721698 dyn FnOnce (
16731699 & BuildDeps ,
@@ -1676,20 +1702,20 @@ fn build_script_local_fingerprints(
16761702 + Send ,
16771703 > ,
16781704 bool ,
1679- ) {
1705+ ) > {
16801706 assert ! ( unit. mode. is_run_custom_build( ) ) ;
16811707 // First up, if this build script is entirely overridden, then we just
16821708 // return the hash of what we overrode it with. This is the easy case!
16831709 if let Some ( fingerprint) = build_script_override_fingerprint ( build_runner, unit) {
16841710 debug ! ( "override local fingerprints deps {}" , unit. pkg) ;
1685- return (
1711+ return Ok ( (
16861712 Box :: new (
16871713 move |_: & BuildDeps , _: Option < & dyn Fn ( ) -> CargoResult < String > > | {
16881714 Ok ( Some ( vec ! [ fingerprint] ) )
16891715 } ,
16901716 ) ,
16911717 true , // this is an overridden build script
1692- ) ;
1718+ ) ) ;
16931719 }
16941720
16951721 // ... Otherwise this is a "real" build script and we need to return a real
@@ -1701,6 +1727,7 @@ fn build_script_local_fingerprints(
17011727 // obvious.
17021728 let pkg_root = unit. pkg . root ( ) . to_path_buf ( ) ;
17031729 let target_dir = target_root ( build_runner) ;
1730+ let env_config = Arc :: clone ( build_runner. bcx . gctx . env_config ( ) ?) ;
17041731 let calculate =
17051732 move |deps : & BuildDeps , pkg_fingerprint : Option < & dyn Fn ( ) -> CargoResult < String > > | {
17061733 if deps. rerun_if_changed . is_empty ( ) && deps. rerun_if_env_changed . is_empty ( ) {
@@ -1730,11 +1757,16 @@ fn build_script_local_fingerprints(
17301757 // Ok so now we're in "new mode" where we can have files listed as
17311758 // dependencies as well as env vars listed as dependencies. Process
17321759 // them all here.
1733- Ok ( Some ( local_fingerprints_deps ( deps, & target_dir, & pkg_root) ) )
1760+ Ok ( Some ( local_fingerprints_deps (
1761+ deps,
1762+ & target_dir,
1763+ & pkg_root,
1764+ & env_config,
1765+ ) ) )
17341766 } ;
17351767
17361768 // Note that `false` == "not overridden"
1737- ( Box :: new ( calculate) , false )
1769+ Ok ( ( Box :: new ( calculate) , false ) )
17381770}
17391771
17401772/// Create a [`LocalFingerprint`] for an overridden build script.
@@ -1765,6 +1797,7 @@ fn local_fingerprints_deps(
17651797 deps : & BuildDeps ,
17661798 target_root : & Path ,
17671799 pkg_root : & Path ,
1800+ env_config : & Arc < HashMap < String , OsString > > ,
17681801) -> Vec < LocalFingerprint > {
17691802 debug ! ( "new local fingerprints deps {:?}" , pkg_root) ;
17701803 let mut local = Vec :: new ( ) ;
@@ -1785,11 +1818,11 @@ fn local_fingerprints_deps(
17851818 . collect ( ) ;
17861819 local. push ( LocalFingerprint :: RerunIfChanged { output, paths } ) ;
17871820 }
1788-
1821+ let env_config_insensitive = Arc :: new ( OnceCell :: new ( ) ) ;
17891822 local. extend (
17901823 deps. rerun_if_env_changed
17911824 . iter ( )
1792- . map ( LocalFingerprint :: from_env) ,
1825+ . map ( |s| LocalFingerprint :: from_env ( s , env_config , & env_config_insensitive ) ) ,
17931826 ) ;
17941827
17951828 local
0 commit comments