@@ -264,19 +264,72 @@ impl Tool {
264
264
}
265
265
}
266
266
267
+ /// Returns preferred compiler for source file.
268
+ fn preferred_compiler_for_source ( & self , src : Option < & PathBuf > ) -> ( PathBuf , & [ OsString ] ) {
269
+ let mut path = self . path . clone ( ) ;
270
+ let mut extra_args: & [ OsString ] = & [ ] ;
271
+ if let Some ( src) = src {
272
+ let mut is_c = false ;
273
+ let mut is_cpp = false ;
274
+ if let Some ( ext) = src. extension ( ) . and_then ( |x| x. to_str ( ) ) {
275
+ match ext {
276
+ "c" => {
277
+ is_c = true ;
278
+ }
279
+ "cc" | "cpp" | "cxx" | "c++" => {
280
+ is_cpp = true ;
281
+ }
282
+ _ => { }
283
+ }
284
+ }
285
+ match self . family {
286
+ ToolFamily :: Clang { zig_cc } if !zig_cc => {
287
+ let s = path. to_string_lossy ( ) . to_string ( ) ;
288
+ if is_c {
289
+ path = PathBuf :: from ( s. replace ( "clang++" , "clang" ) ) ;
290
+ extra_args = & self . c_args ;
291
+ }
292
+ if is_cpp {
293
+ if s. ends_with ( "clang" ) {
294
+ path = PathBuf :: from ( s. replace ( "clang" , "clang++" ) ) ;
295
+ }
296
+ extra_args = & self . cpp_args ;
297
+ }
298
+ }
299
+ ToolFamily :: Gnu => {
300
+ let s = path. to_string_lossy ( ) . to_string ( ) ;
301
+ if is_c {
302
+ path = PathBuf :: from ( s. replace ( "g++" , "gcc" ) ) ;
303
+ extra_args = & self . c_args ;
304
+ }
305
+ if is_cpp {
306
+ path = PathBuf :: from ( s. replace ( "gcc" , "g++" ) ) ;
307
+ extra_args = & self . cpp_args ;
308
+ }
309
+ }
310
+ _ => { }
311
+ }
312
+ }
313
+ ( path, extra_args)
314
+ }
315
+
267
316
/// Converts this compiler into a `Command` that's ready to be run.
268
317
///
269
318
/// This is useful for when the compiler needs to be executed and the
270
319
/// command returned will already have the initial arguments and environment
271
320
/// variables configured.
272
- pub fn to_command ( & self ) -> Command {
321
+ ///
322
+ /// The `src` argument is used to determine the preferred compiler for the
323
+ /// source file. If `None`, the default compiler is used.
324
+ pub fn to_command ( & self , src : Option < & PathBuf > ) -> Command {
325
+ let ( path, extra_args) = self . preferred_compiler_for_source ( src) ;
273
326
let mut cmd = match self . cc_wrapper_path {
274
327
Some ( ref cc_wrapper_path) => {
275
328
let mut cmd = Command :: new ( cc_wrapper_path) ;
276
- cmd. arg ( & self . path ) ;
329
+ cmd. arg ( & path) ;
277
330
cmd
278
331
}
279
- None => Command :: new ( & self . path ) ,
332
+ None => Command :: new ( & path) ,
280
333
} ;
281
334
cmd. args ( & self . cc_wrapper_args ) ;
282
335
@@ -287,6 +340,8 @@ impl Tool {
287
340
. collect :: < Vec < _ > > ( ) ;
288
341
cmd. args ( & value) ;
289
342
343
+ cmd. args ( extra_args) ;
344
+
290
345
for ( k, v) in self . env . iter ( ) {
291
346
cmd. env ( k, v) ;
292
347
}
0 commit comments