362
362
mod dep_info;
363
363
mod dirty_reason;
364
364
365
+ use std:: cell:: OnceCell ;
365
366
use std:: collections:: hash_map:: { Entry , HashMap } ;
366
367
use std:: env;
368
+ use std:: ffi:: OsString ;
367
369
use std:: fs;
368
370
use std:: fs:: File ;
369
371
use std:: hash:: { self , Hash , Hasher } ;
@@ -499,7 +501,7 @@ pub fn prepare_target(
499
501
// thunk we can invoke on a foreign thread to calculate this.
500
502
let build_script_outputs = Arc :: clone ( & build_runner. build_script_outputs ) ;
501
503
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) ? ;
503
505
let output_path = build_runner. build_explicit_deps [ unit]
504
506
. build_script_output
505
507
. clone ( ) ;
@@ -796,14 +798,36 @@ pub enum StaleItem {
796
798
impl LocalFingerprint {
797
799
/// Read the environment variable of the given env `key`, and creates a new
798
800
/// [`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.
802
801
#[ 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 {
804
807
let key = key. as_ref ( ) ;
805
808
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
+ } ;
807
831
LocalFingerprint :: RerunIfEnvChanged { var, val }
808
832
}
809
833
@@ -1573,7 +1597,7 @@ fn calculate_run_custom_build(
1573
1597
// the build script this means we'll be watching files and env vars.
1574
1598
// Otherwise if we haven't previously executed it we'll just start watching
1575
1599
// 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) ? ;
1577
1601
let deps = & build_runner. build_explicit_deps [ unit] ;
1578
1602
let local = ( gen_local) (
1579
1603
deps,
@@ -1667,7 +1691,7 @@ See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-change
1667
1691
fn build_script_local_fingerprints (
1668
1692
build_runner : & mut BuildRunner < ' _ , ' _ > ,
1669
1693
unit : & Unit ,
1670
- ) -> (
1694
+ ) -> CargoResult < (
1671
1695
Box <
1672
1696
dyn FnOnce (
1673
1697
& BuildDeps ,
@@ -1676,20 +1700,20 @@ fn build_script_local_fingerprints(
1676
1700
+ Send ,
1677
1701
> ,
1678
1702
bool ,
1679
- ) {
1703
+ ) > {
1680
1704
assert ! ( unit. mode. is_run_custom_build( ) ) ;
1681
1705
// First up, if this build script is entirely overridden, then we just
1682
1706
// return the hash of what we overrode it with. This is the easy case!
1683
1707
if let Some ( fingerprint) = build_script_override_fingerprint ( build_runner, unit) {
1684
1708
debug ! ( "override local fingerprints deps {}" , unit. pkg) ;
1685
- return (
1709
+ return Ok ( (
1686
1710
Box :: new (
1687
1711
move |_: & BuildDeps , _: Option < & dyn Fn ( ) -> CargoResult < String > > | {
1688
1712
Ok ( Some ( vec ! [ fingerprint] ) )
1689
1713
} ,
1690
1714
) ,
1691
1715
true , // this is an overridden build script
1692
- ) ;
1716
+ ) ) ;
1693
1717
}
1694
1718
1695
1719
// ... Otherwise this is a "real" build script and we need to return a real
@@ -1701,6 +1725,7 @@ fn build_script_local_fingerprints(
1701
1725
// obvious.
1702
1726
let pkg_root = unit. pkg . root ( ) . to_path_buf ( ) ;
1703
1727
let target_dir = target_root ( build_runner) ;
1728
+ let env_config = Arc :: clone ( build_runner. bcx . gctx . env_config ( ) ?) ;
1704
1729
let calculate =
1705
1730
move |deps : & BuildDeps , pkg_fingerprint : Option < & dyn Fn ( ) -> CargoResult < String > > | {
1706
1731
if deps. rerun_if_changed . is_empty ( ) && deps. rerun_if_env_changed . is_empty ( ) {
@@ -1730,11 +1755,16 @@ fn build_script_local_fingerprints(
1730
1755
// Ok so now we're in "new mode" where we can have files listed as
1731
1756
// dependencies as well as env vars listed as dependencies. Process
1732
1757
// 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
+ ) ) )
1734
1764
} ;
1735
1765
1736
1766
// Note that `false` == "not overridden"
1737
- ( Box :: new ( calculate) , false )
1767
+ Ok ( ( Box :: new ( calculate) , false ) )
1738
1768
}
1739
1769
1740
1770
/// Create a [`LocalFingerprint`] for an overridden build script.
@@ -1765,6 +1795,7 @@ fn local_fingerprints_deps(
1765
1795
deps : & BuildDeps ,
1766
1796
target_root : & Path ,
1767
1797
pkg_root : & Path ,
1798
+ env_config : & Arc < HashMap < String , OsString > > ,
1768
1799
) -> Vec < LocalFingerprint > {
1769
1800
debug ! ( "new local fingerprints deps {:?}" , pkg_root) ;
1770
1801
let mut local = Vec :: new ( ) ;
@@ -1785,11 +1816,11 @@ fn local_fingerprints_deps(
1785
1816
. collect ( ) ;
1786
1817
local. push ( LocalFingerprint :: RerunIfChanged { output, paths } ) ;
1787
1818
}
1788
-
1819
+ let env_config_insensitive = Arc :: new ( OnceCell :: new ( ) ) ;
1789
1820
local. extend (
1790
1821
deps. rerun_if_env_changed
1791
1822
. iter ( )
1792
- . map ( LocalFingerprint :: from_env) ,
1823
+ . map ( |s| LocalFingerprint :: from_env ( s , env_config , & env_config_insensitive ) ) ,
1793
1824
) ;
1794
1825
1795
1826
local
0 commit comments