@@ -290,19 +290,72 @@ impl Tool {
290290 }
291291 }
292292
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+
293342 /// Converts this compiler into a `Command` that's ready to be run.
294343 ///
295344 /// This is useful for when the compiler needs to be executed and the
296345 /// command returned will already have the initial arguments and environment
297346 /// 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) ;
299352 let mut cmd = match self . cc_wrapper_path {
300353 Some ( ref cc_wrapper_path) => {
301354 let mut cmd = Command :: new ( cc_wrapper_path) ;
302- cmd. arg ( & self . path ) ;
355+ cmd. arg ( & path) ;
303356 cmd
304357 }
305- None => Command :: new ( & self . path ) ,
358+ None => Command :: new ( & path) ,
306359 } ;
307360 cmd. args ( & self . cc_wrapper_args ) ;
308361
@@ -313,6 +366,8 @@ impl Tool {
313366 . collect :: < Vec < _ > > ( ) ;
314367 cmd. args ( & value) ;
315368
369+ cmd. args ( extra_args) ;
370+
316371 for ( k, v) in self . env . iter ( ) {
317372 cmd. env ( k, v) ;
318373 }
0 commit comments