@@ -86,6 +86,7 @@ pub struct Config {
86
86
static_crt : Option < bool > ,
87
87
shared_flag : Option < bool > ,
88
88
static_flag : Option < bool > ,
89
+ check_file_created : bool ,
89
90
}
90
91
91
92
/// Configuration used to represent an invocation of a C compiler.
@@ -200,6 +201,7 @@ impl Config {
200
201
cargo_metadata : true ,
201
202
pic : None ,
202
203
static_crt : None ,
204
+ check_file_created : false ,
203
205
}
204
206
}
205
207
@@ -260,6 +262,51 @@ impl Config {
260
262
self
261
263
}
262
264
265
+ fn is_flag_supported ( & mut self , flag : & str ) -> io:: Result < bool > {
266
+ let out_dir = self . get_out_dir ( ) ;
267
+ let src = out_dir. join ( "flag_check.c" ) ;
268
+ if !self . check_file_created {
269
+ write ! ( fs:: File :: create( & src) ?, "int main(void) {{ return 0; }}" ) ?;
270
+ self . check_file_created = true ;
271
+ }
272
+
273
+ let obj = out_dir. join ( "flag_check" ) ;
274
+ let target = self . get_target ( ) ;
275
+ let mut cfg = Config :: new ( ) ;
276
+ cfg. flag ( flag)
277
+ . target ( & target)
278
+ . opt_level ( 0 )
279
+ . host ( & target)
280
+ . debug ( false )
281
+ . cpp ( self . cpp ) ;
282
+ let compiler = cfg. get_compiler ( ) ;
283
+ let mut cmd = compiler. to_command ( ) ;
284
+ command_add_output_file ( & mut cmd, & obj, target. contains ( "msvc" ) , false ) ;
285
+ cmd. arg ( & src) ;
286
+
287
+ let output = cmd. output ( ) ?;
288
+ Ok ( output. stderr . is_empty ( ) )
289
+ }
290
+
291
+ /// Add an arbitrary flag to the invocation of the compiler if it supports it
292
+ ///
293
+ /// # Example
294
+ ///
295
+ /// ```no_run
296
+ /// gcc::Config::new()
297
+ /// .file("src/foo.c")
298
+ /// .flag_if_supported("-Wlogical-op") // only supported by GCC
299
+ /// .flag_if_supported("-Wunreachable-code") // only supported by clang
300
+ /// .compile("foo");
301
+ /// ```
302
+ pub fn flag_if_supported ( & mut self , flag : & str ) -> & mut Config {
303
+ if self . is_flag_supported ( flag) . unwrap_or ( false ) {
304
+ self . flag ( flag)
305
+ } else {
306
+ self
307
+ }
308
+ }
309
+
263
310
/// Set the `-shared` flag.
264
311
///
265
312
/// When enabled, the compiler will produce a shared object which can
@@ -599,15 +646,7 @@ impl Config {
599
646
. to_string_lossy ( )
600
647
. into_owned ( ) )
601
648
} ;
602
- if msvc && is_asm {
603
- cmd. arg ( "/Fo" ) . arg ( dst) ;
604
- } else if msvc {
605
- let mut s = OsString :: from ( "/Fo" ) ;
606
- s. push ( & dst) ;
607
- cmd. arg ( s) ;
608
- } else {
609
- cmd. arg ( "-o" ) . arg ( & dst) ;
610
- }
649
+ command_add_output_file ( & mut cmd, dst, msvc, is_asm) ;
611
650
cmd. arg ( if msvc { "/c" } else { "-c" } ) ;
612
651
cmd. arg ( file) ;
613
652
@@ -1344,3 +1383,16 @@ fn fail(s: &str) -> ! {
1344
1383
println ! ( "\n \n {}\n \n " , s) ;
1345
1384
panic ! ( )
1346
1385
}
1386
+
1387
+
1388
+ fn command_add_output_file ( cmd : & mut Command , dst : & Path , msvc : bool , is_asm : bool ) {
1389
+ if msvc && is_asm {
1390
+ cmd. arg ( "/Fo" ) . arg ( dst) ;
1391
+ } else if msvc {
1392
+ let mut s = OsString :: from ( "/Fo" ) ;
1393
+ s. push ( & dst) ;
1394
+ cmd. arg ( s) ;
1395
+ } else {
1396
+ cmd. arg ( "-o" ) . arg ( & dst) ;
1397
+ }
1398
+ }
0 commit comments