@@ -653,7 +653,12 @@ impl Build {
653653 /// ```
654654 ///
655655 pub fn try_flags_from_environment ( & mut self , environ_key : & str ) -> Result < & mut Build , Error > {
656- let flags = self . envflags ( environ_key) ?;
656+ let flags = self . envflags ( environ_key) ?. ok_or_else ( || {
657+ Error :: new (
658+ ErrorKind :: EnvVarNotFound ,
659+ format ! ( "could not find environment variable {environ_key}" ) ,
660+ )
661+ } ) ?;
657662 self . flags . extend (
658663 flags
659664 . into_iter ( )
@@ -1907,7 +1912,8 @@ impl Build {
19071912 cmd. args . push ( directory. as_os_str ( ) . into ( ) ) ;
19081913 }
19091914
1910- if let Ok ( flags) = self . envflags ( if self . cpp { "CXXFLAGS" } else { "CFLAGS" } ) {
1915+ let flags = self . envflags ( if self . cpp { "CXXFLAGS" } else { "CFLAGS" } ) ?;
1916+ if let Some ( flags) = & flags {
19111917 for arg in flags {
19121918 cmd. push_cc_arg ( arg. into ( ) ) ;
19131919 }
@@ -1918,12 +1924,12 @@ impl Build {
19181924 // CFLAGS/CXXFLAGS, since those variables presumably already contain
19191925 // the desired set of warnings flags.
19201926
1921- if self . warnings . unwrap_or ( ! self . has_flags ( ) ) {
1927+ if self . warnings . unwrap_or ( flags . is_none ( ) ) {
19221928 let wflags = cmd. family . warnings_flags ( ) . into ( ) ;
19231929 cmd. push_cc_arg ( wflags) ;
19241930 }
19251931
1926- if self . extra_warnings . unwrap_or ( ! self . has_flags ( ) ) {
1932+ if self . extra_warnings . unwrap_or ( flags . is_none ( ) ) {
19271933 if let Some ( wflags) = cmd. family . extra_warnings_flags ( ) {
19281934 cmd. push_cc_arg ( wflags. into ( ) ) ;
19291935 }
@@ -2443,12 +2449,6 @@ impl Build {
24432449 Ok ( ( ) )
24442450 }
24452451
2446- fn has_flags ( & self ) -> bool {
2447- let flags_env_var_name = if self . cpp { "CXXFLAGS" } else { "CFLAGS" } ;
2448- let flags_env_var_value = self . getenv_with_target_prefixes ( flags_env_var_name) ;
2449- flags_env_var_value. is_ok ( )
2450- }
2451-
24522452 fn msvc_macro_assembler ( & self ) -> Result < Command , Error > {
24532453 let target = self . get_target ( ) ?;
24542454 let tool = if target. arch == "x86_64" {
@@ -3115,8 +3115,8 @@ impl Build {
31153115 fn try_get_archiver_and_flags ( & self ) -> Result < ( Command , PathBuf , bool ) , Error > {
31163116 let ( mut cmd, name) = self . get_base_archiver ( ) ?;
31173117 let mut any_flags = false ;
3118- if let Ok ( flags) = self . envflags ( "ARFLAGS" ) {
3119- any_flags |= !flags . is_empty ( ) ;
3118+ if let Some ( flags) = self . envflags ( "ARFLAGS" ) ? {
3119+ any_flags = true ;
31203120 cmd. args ( flags) ;
31213121 }
31223122 for flag in & self . ar_flags {
@@ -3162,7 +3162,7 @@ impl Build {
31623162 /// see [`Self::get_ranlib`] for the complete description.
31633163 pub fn try_get_ranlib ( & self ) -> Result < Command , Error > {
31643164 let mut cmd = self . get_base_ranlib ( ) ?;
3165- if let Ok ( flags) = self . envflags ( "RANLIBFLAGS" ) {
3165+ if let Some ( flags) = self . envflags ( "RANLIBFLAGS" ) ? {
31663166 cmd. args ( flags) ;
31673167 }
31683168 Ok ( cmd)
@@ -3643,41 +3643,64 @@ impl Build {
36433643 } )
36443644 }
36453645
3646- fn getenv_with_target_prefixes ( & self , var_base : & str ) -> Result < Arc < OsStr > , Error > {
3646+ /// The list of environment variables to check for a given env, in order of priority.
3647+ fn target_envs ( & self , env : & str ) -> Result < [ String ; 4 ] , Error > {
36473648 let target = self . get_raw_target ( ) ?;
36483649 let kind = if self . get_is_cross_compile ( ) ? {
36493650 "TARGET"
36503651 } else {
36513652 "HOST"
36523653 } ;
36533654 let target_u = target. replace ( '-' , "_" ) ;
3655+
3656+ Ok ( [
3657+ format ! ( "{env}_{target}" ) ,
3658+ format ! ( "{env}_{target_u}" ) ,
3659+ format ! ( "{kind}_{env}" ) ,
3660+ env. to_string ( ) ,
3661+ ] )
3662+ }
3663+
3664+ /// Get a single-valued environment variable with target variants.
3665+ fn getenv_with_target_prefixes ( & self , env : & str ) -> Result < Arc < OsStr > , Error > {
3666+ // Take from first environment variable in the environment.
36543667 let res = self
3655- . getenv ( & format ! ( "{}_{}" , var_base , target ) )
3656- . or_else ( || self . getenv ( & format ! ( "{}_{}" , var_base , target_u ) ) )
3657- . or_else ( | | self . getenv ( & format ! ( "{}_{}" , kind , var_base ) ) )
3658- . or_else ( || self . getenv ( var_base ) ) ;
3668+ . target_envs ( env ) ?
3669+ . iter ( )
3670+ . filter_map ( |env | self . getenv ( env ) )
3671+ . next ( ) ;
36593672
36603673 match res {
36613674 Some ( res) => Ok ( res) ,
36623675 None => Err ( Error :: new (
36633676 ErrorKind :: EnvVarNotFound ,
3664- format ! ( "Could not find environment variable {}." , var_base ) ,
3677+ format ! ( "could not find environment variable {env}" ) ,
36653678 ) ) ,
36663679 }
36673680 }
36683681
3669- fn envflags ( & self , name : & str ) -> Result < Vec < String > , Error > {
3670- let env_os = self . getenv_with_target_prefixes ( name) ?;
3671- let env = env_os. to_string_lossy ( ) ;
3672-
3673- if self . get_shell_escaped_flags ( ) {
3674- Ok ( Shlex :: new ( & env) . collect ( ) )
3675- } else {
3676- Ok ( env
3677- . split_ascii_whitespace ( )
3678- . map ( ToString :: to_string)
3679- . collect ( ) )
3682+ /// Get values from CFLAGS-style environment variable.
3683+ fn envflags ( & self , env : & str ) -> Result < Option < Vec < String > > , Error > {
3684+ // Collect from all environment variables, in reverse order as in
3685+ // `getenv_with_target_prefixes` precedence (so that `CFLAGS_$TARGET`
3686+ // can override flags in `TARGET_CFLAGS`, which overrides those in
3687+ // `CFLAGS`).
3688+ let mut any_set = false ;
3689+ let mut res = vec ! [ ] ;
3690+ for env in self . target_envs ( env) ?. iter ( ) . rev ( ) {
3691+ if let Some ( var) = self . getenv ( env) {
3692+ any_set = true ;
3693+
3694+ let var = var. to_string_lossy ( ) ;
3695+ if self . get_shell_escaped_flags ( ) {
3696+ res. extend ( Shlex :: new ( & var) ) ;
3697+ } else {
3698+ res. extend ( var. split_ascii_whitespace ( ) . map ( ToString :: to_string) ) ;
3699+ }
3700+ }
36803701 }
3702+
3703+ Ok ( if any_set { Some ( res) } else { None } )
36813704 }
36823705
36833706 fn fix_env_for_apple_os ( & self , cmd : & mut Command ) -> Result < ( ) , Error > {
0 commit comments