@@ -264,19 +264,72 @@ impl Tool {
264264 }
265265 }
266266
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+
267316 /// Converts this compiler into a `Command` that's ready to be run.
268317 ///
269318 /// This is useful for when the compiler needs to be executed and the
270319 /// command returned will already have the initial arguments and environment
271320 /// 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) ;
273326 let mut cmd = match self . cc_wrapper_path {
274327 Some ( ref cc_wrapper_path) => {
275328 let mut cmd = Command :: new ( cc_wrapper_path) ;
276- cmd. arg ( & self . path ) ;
329+ cmd. arg ( & path) ;
277330 cmd
278331 }
279- None => Command :: new ( & self . path ) ,
332+ None => Command :: new ( & path) ,
280333 } ;
281334 cmd. args ( & self . cc_wrapper_args ) ;
282335
@@ -287,6 +340,8 @@ impl Tool {
287340 . collect :: < Vec < _ > > ( ) ;
288341 cmd. args ( & value) ;
289342
343+ cmd. args ( extra_args) ;
344+
290345 for ( k, v) in self . env . iter ( ) {
291346 cmd. env ( k, v) ;
292347 }
0 commit comments