@@ -410,6 +410,7 @@ impl Object {
410
410
}
411
411
}
412
412
413
+ /// Configure the builder.
413
414
impl Build {
414
415
/// Construct a new instance of a blank set of configuration.
415
416
///
@@ -612,144 +613,6 @@ impl Build {
612
613
self
613
614
}
614
615
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
-
753
616
/// Add an arbitrary flag to the invocation of the compiler if it supports it
754
617
///
755
618
/// # Example
@@ -1368,6 +1231,147 @@ impl Build {
1368
1231
self . env . push ( ( a. as_ref ( ) . into ( ) , b. as_ref ( ) . into ( ) ) ) ;
1369
1232
self
1370
1233
}
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
+ }
1371
1375
1372
1376
/// Run the compiler, generating the file `output`
1373
1377
///
0 commit comments