@@ -410,6 +410,7 @@ impl Object {
410410 }
411411}
412412
413+ /// Configure the builder.
413414impl Build {
414415 /// Construct a new instance of a blank set of configuration.
415416 ///
@@ -612,144 +613,6 @@ impl Build {
612613 self
613614 }
614615
615- fn ensure_check_file ( & self ) -> Result < PathBuf , Error > {
616- let out_dir = self . get_out_dir ( ) ?;
617- let src = if self . cuda {
618- assert ! ( self . cpp) ;
619- out_dir. join ( "flag_check.cu" )
620- } else if self . cpp {
621- out_dir. join ( "flag_check.cpp" )
622- } else {
623- out_dir. join ( "flag_check.c" )
624- } ;
625-
626- if !src. exists ( ) {
627- let mut f = fs:: File :: create ( & src) ?;
628- write ! ( f, "int main(void) {{ return 0; }}" ) ?;
629- }
630-
631- Ok ( src)
632- }
633-
634- /// Run the compiler to test if it accepts the given flag.
635- ///
636- /// For a convenience method for setting flags conditionally,
637- /// see `flag_if_supported()`.
638- ///
639- /// It may return error if it's unable to run the compiler with a test file
640- /// (e.g. the compiler is missing or a write to the `out_dir` failed).
641- ///
642- /// Note: Once computed, the result of this call is stored in the
643- /// `known_flag_support` field. If `is_flag_supported(flag)`
644- /// is called again, the result will be read from the hash table.
645- pub fn is_flag_supported ( & self , flag : impl AsRef < OsStr > ) -> Result < bool , Error > {
646- self . is_flag_supported_inner (
647- flag. as_ref ( ) ,
648- & self . get_base_compiler ( ) ?,
649- & self . get_target ( ) ?,
650- )
651- }
652-
653- fn is_flag_supported_inner (
654- & self ,
655- flag : & OsStr ,
656- tool : & Tool ,
657- target : & TargetInfo < ' _ > ,
658- ) -> Result < bool , Error > {
659- let compiler_flag = CompilerFlag {
660- compiler : tool. path ( ) . into ( ) ,
661- flag : flag. into ( ) ,
662- } ;
663-
664- if let Some ( is_supported) = self
665- . build_cache
666- . known_flag_support_status_cache
667- . read ( )
668- . unwrap ( )
669- . get ( & compiler_flag)
670- . cloned ( )
671- {
672- return Ok ( is_supported) ;
673- }
674-
675- let out_dir = self . get_out_dir ( ) ?;
676- let src = self . ensure_check_file ( ) ?;
677- let obj = out_dir. join ( "flag_check" ) ;
678-
679- let mut compiler = {
680- let mut cfg = Build :: new ( ) ;
681- cfg. flag ( flag)
682- . compiler ( tool. path ( ) )
683- . cargo_metadata ( self . cargo_output . metadata )
684- . opt_level ( 0 )
685- . debug ( false )
686- . cpp ( self . cpp )
687- . cuda ( self . cuda )
688- . inherit_rustflags ( false )
689- . emit_rerun_if_env_changed ( self . emit_rerun_if_env_changed ) ;
690- if let Some ( target) = & self . target {
691- cfg. target ( target) ;
692- }
693- if let Some ( host) = & self . host {
694- cfg. host ( host) ;
695- }
696- cfg. try_get_compiler ( ) ?
697- } ;
698-
699- // Clang uses stderr for verbose output, which yields a false positive
700- // result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
701- if compiler. family . verbose_stderr ( ) {
702- compiler. remove_arg ( "-v" . into ( ) ) ;
703- }
704- if compiler. is_like_clang ( ) {
705- // Avoid reporting that the arg is unsupported just because the
706- // compiler complains that it wasn't used.
707- compiler. push_cc_arg ( "-Wno-unused-command-line-argument" . into ( ) ) ;
708- }
709-
710- let mut cmd = compiler. to_command ( ) ;
711- let is_arm = matches ! ( target. arch, "aarch64" | "arm" ) ;
712- let clang = compiler. is_like_clang ( ) ;
713- let gnu = compiler. family == ToolFamily :: Gnu ;
714- command_add_output_file (
715- & mut cmd,
716- & obj,
717- CmdAddOutputFileArgs {
718- cuda : self . cuda ,
719- is_assembler_msvc : false ,
720- msvc : compiler. is_like_msvc ( ) ,
721- clang,
722- gnu,
723- is_asm : false ,
724- is_arm,
725- } ,
726- ) ;
727-
728- if compiler. supports_path_delimiter ( ) {
729- cmd. arg ( "--" ) ;
730- }
731-
732- cmd. arg ( & src) ;
733-
734- // On MSVC skip the CRT by setting the entry point to `main`.
735- // This way we don't need to add the default library paths.
736- if compiler. is_like_msvc ( ) {
737- // Flags from _LINK_ are appended to the linker arguments.
738- cmd. env ( "_LINK_" , "-entry:main" ) ;
739- }
740-
741- let output = cmd. output ( ) ?;
742- let is_supported = output. status . success ( ) && output. stderr . is_empty ( ) ;
743-
744- self . build_cache
745- . known_flag_support_status_cache
746- . write ( )
747- . unwrap ( )
748- . insert ( compiler_flag, is_supported) ;
749-
750- Ok ( is_supported)
751- }
752-
753616 /// Add an arbitrary flag to the invocation of the compiler if it supports it
754617 ///
755618 /// # Example
@@ -1368,6 +1231,147 @@ impl Build {
13681231 self . env . push ( ( a. as_ref ( ) . into ( ) , b. as_ref ( ) . into ( ) ) ) ;
13691232 self
13701233 }
1234+ }
1235+
1236+ /// Invoke or fetch the compiler or archiver.
1237+ impl Build {
1238+ /// Run the compiler to test if it accepts the given flag.
1239+ ///
1240+ /// For a convenience method for setting flags conditionally,
1241+ /// see `flag_if_supported()`.
1242+ ///
1243+ /// It may return error if it's unable to run the compiler with a test file
1244+ /// (e.g. the compiler is missing or a write to the `out_dir` failed).
1245+ ///
1246+ /// Note: Once computed, the result of this call is stored in the
1247+ /// `known_flag_support` field. If `is_flag_supported(flag)`
1248+ /// is called again, the result will be read from the hash table.
1249+ pub fn is_flag_supported ( & self , flag : impl AsRef < OsStr > ) -> Result < bool , Error > {
1250+ self . is_flag_supported_inner (
1251+ flag. as_ref ( ) ,
1252+ & self . get_base_compiler ( ) ?,
1253+ & self . get_target ( ) ?,
1254+ )
1255+ }
1256+
1257+ fn ensure_check_file ( & self ) -> Result < PathBuf , Error > {
1258+ let out_dir = self . get_out_dir ( ) ?;
1259+ let src = if self . cuda {
1260+ assert ! ( self . cpp) ;
1261+ out_dir. join ( "flag_check.cu" )
1262+ } else if self . cpp {
1263+ out_dir. join ( "flag_check.cpp" )
1264+ } else {
1265+ out_dir. join ( "flag_check.c" )
1266+ } ;
1267+
1268+ if !src. exists ( ) {
1269+ let mut f = fs:: File :: create ( & src) ?;
1270+ write ! ( f, "int main(void) {{ return 0; }}" ) ?;
1271+ }
1272+
1273+ Ok ( src)
1274+ }
1275+
1276+ fn is_flag_supported_inner (
1277+ & self ,
1278+ flag : & OsStr ,
1279+ tool : & Tool ,
1280+ target : & TargetInfo < ' _ > ,
1281+ ) -> Result < bool , Error > {
1282+ let compiler_flag = CompilerFlag {
1283+ compiler : tool. path ( ) . into ( ) ,
1284+ flag : flag. into ( ) ,
1285+ } ;
1286+
1287+ if let Some ( is_supported) = self
1288+ . build_cache
1289+ . known_flag_support_status_cache
1290+ . read ( )
1291+ . unwrap ( )
1292+ . get ( & compiler_flag)
1293+ . cloned ( )
1294+ {
1295+ return Ok ( is_supported) ;
1296+ }
1297+
1298+ let out_dir = self . get_out_dir ( ) ?;
1299+ let src = self . ensure_check_file ( ) ?;
1300+ let obj = out_dir. join ( "flag_check" ) ;
1301+
1302+ let mut compiler = {
1303+ let mut cfg = Build :: new ( ) ;
1304+ cfg. flag ( flag)
1305+ . compiler ( tool. path ( ) )
1306+ . cargo_metadata ( self . cargo_output . metadata )
1307+ . opt_level ( 0 )
1308+ . debug ( false )
1309+ . cpp ( self . cpp )
1310+ . cuda ( self . cuda )
1311+ . inherit_rustflags ( false )
1312+ . emit_rerun_if_env_changed ( self . emit_rerun_if_env_changed ) ;
1313+ if let Some ( target) = & self . target {
1314+ cfg. target ( target) ;
1315+ }
1316+ if let Some ( host) = & self . host {
1317+ cfg. host ( host) ;
1318+ }
1319+ cfg. try_get_compiler ( ) ?
1320+ } ;
1321+
1322+ // Clang uses stderr for verbose output, which yields a false positive
1323+ // result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
1324+ if compiler. family . verbose_stderr ( ) {
1325+ compiler. remove_arg ( "-v" . into ( ) ) ;
1326+ }
1327+ if compiler. is_like_clang ( ) {
1328+ // Avoid reporting that the arg is unsupported just because the
1329+ // compiler complains that it wasn't used.
1330+ compiler. push_cc_arg ( "-Wno-unused-command-line-argument" . into ( ) ) ;
1331+ }
1332+
1333+ let mut cmd = compiler. to_command ( ) ;
1334+ let is_arm = matches ! ( target. arch, "aarch64" | "arm" ) ;
1335+ let clang = compiler. is_like_clang ( ) ;
1336+ let gnu = compiler. family == ToolFamily :: Gnu ;
1337+ command_add_output_file (
1338+ & mut cmd,
1339+ & obj,
1340+ CmdAddOutputFileArgs {
1341+ cuda : self . cuda ,
1342+ is_assembler_msvc : false ,
1343+ msvc : compiler. is_like_msvc ( ) ,
1344+ clang,
1345+ gnu,
1346+ is_asm : false ,
1347+ is_arm,
1348+ } ,
1349+ ) ;
1350+
1351+ if compiler. supports_path_delimiter ( ) {
1352+ cmd. arg ( "--" ) ;
1353+ }
1354+
1355+ cmd. arg ( & src) ;
1356+
1357+ // On MSVC skip the CRT by setting the entry point to `main`.
1358+ // This way we don't need to add the default library paths.
1359+ if compiler. is_like_msvc ( ) {
1360+ // Flags from _LINK_ are appended to the linker arguments.
1361+ cmd. env ( "_LINK_" , "-entry:main" ) ;
1362+ }
1363+
1364+ let output = cmd. output ( ) ?;
1365+ let is_supported = output. status . success ( ) && output. stderr . is_empty ( ) ;
1366+
1367+ self . build_cache
1368+ . known_flag_support_status_cache
1369+ . write ( )
1370+ . unwrap ( )
1371+ . insert ( compiler_flag, is_supported) ;
1372+
1373+ Ok ( is_supported)
1374+ }
13711375
13721376 /// Run the compiler, generating the file `output`
13731377 ///
0 commit comments