@@ -290,19 +290,72 @@ impl Tool {
290
290
}
291
291
}
292
292
293
+ /// Returns preferred compiler for source file.
294
+ fn preferred_compiler_for_source ( & self , src : Option < & PathBuf > ) -> ( PathBuf , & [ OsString ] ) {
295
+ let mut path = self . path . clone ( ) ;
296
+ let mut extra_args: & [ OsString ] = & [ ] ;
297
+ if let Some ( src) = src {
298
+ let mut is_c = false ;
299
+ let mut is_cpp = false ;
300
+ if let Some ( ext) = src. extension ( ) . and_then ( |x| x. to_str ( ) ) {
301
+ match ext {
302
+ "c" => {
303
+ is_c = true ;
304
+ }
305
+ "cc" | "cpp" | "cxx" | "c++" => {
306
+ is_cpp = true ;
307
+ }
308
+ _ => { }
309
+ }
310
+ }
311
+ match self . family {
312
+ ToolFamily :: Clang { zig_cc } if !zig_cc => {
313
+ let s = path. to_string_lossy ( ) . to_string ( ) ;
314
+ if is_c {
315
+ path = PathBuf :: from ( s. replace ( "clang++" , "clang" ) ) ;
316
+ extra_args = & self . c_args ;
317
+ }
318
+ if is_cpp {
319
+ if s. ends_with ( "clang" ) {
320
+ path = PathBuf :: from ( s. replace ( "clang" , "clang++" ) ) ;
321
+ }
322
+ extra_args = & self . cpp_args ;
323
+ }
324
+ }
325
+ ToolFamily :: Gnu => {
326
+ let s = path. to_string_lossy ( ) . to_string ( ) ;
327
+ if is_c {
328
+ path = PathBuf :: from ( s. replace ( "g++" , "gcc" ) ) ;
329
+ extra_args = & self . c_args ;
330
+ }
331
+ if is_cpp {
332
+ path = PathBuf :: from ( s. replace ( "gcc" , "g++" ) ) ;
333
+ extra_args = & self . cpp_args ;
334
+ }
335
+ }
336
+ _ => { }
337
+ }
338
+ }
339
+ ( path, extra_args)
340
+ }
341
+
293
342
/// Converts this compiler into a `Command` that's ready to be run.
294
343
///
295
344
/// This is useful for when the compiler needs to be executed and the
296
345
/// command returned will already have the initial arguments and environment
297
346
/// variables configured.
298
- pub fn to_command ( & self ) -> Command {
347
+ ///
348
+ /// The `src` argument is used to determine the preferred compiler for the
349
+ /// source file. If `None`, the default compiler is used.
350
+ pub fn to_command ( & self , src : Option < & PathBuf > ) -> Command {
351
+ let ( path, extra_args) = self . preferred_compiler_for_source ( src) ;
299
352
let mut cmd = match self . cc_wrapper_path {
300
353
Some ( ref cc_wrapper_path) => {
301
354
let mut cmd = Command :: new ( cc_wrapper_path) ;
302
- cmd. arg ( & self . path ) ;
355
+ cmd. arg ( & path) ;
303
356
cmd
304
357
}
305
- None => Command :: new ( & self . path ) ,
358
+ None => Command :: new ( & path) ,
306
359
} ;
307
360
cmd. args ( & self . cc_wrapper_args ) ;
308
361
@@ -313,6 +366,8 @@ impl Tool {
313
366
. collect :: < Vec < _ > > ( ) ;
314
367
cmd. args ( & value) ;
315
368
369
+ cmd. args ( extra_args) ;
370
+
316
371
for ( k, v) in self . env . iter ( ) {
317
372
cmd. env ( k, v) ;
318
373
}
0 commit comments