@@ -261,7 +261,8 @@ init_hash_debug(Context& ctx,
261
261
}
262
262
263
263
#ifndef _WIN32
264
- std::string
264
+
265
+ static fs::path
265
266
follow_symlinks (const fs::path& path)
266
267
{
267
268
// Follow symlinks to the real compiler to learn its name. We're not using
@@ -279,8 +280,33 @@ follow_symlinks(const fs::path& path)
279
280
p = p.parent_path () / *symlink_target;
280
281
}
281
282
}
283
+ if (p != path) {
284
+ LOG (" Followed symlinks from {} to {} when guessing compiler type" , path, p);
285
+ }
282
286
return p;
283
287
}
288
+
289
+ static fs::path
290
+ probe_generic_compiler (const fs::path& path)
291
+ {
292
+ // Detect whether a generically named compiler (e.g. /usr/bin/cc) is a hard
293
+ // link to a compiler with a more specific name.
294
+ std::string name = util::pstr (path.filename ()).str ();
295
+ if (name == " cc" || name == " c++" ) {
296
+ static const char * candidate_names[] = {" gcc" , " g++" , " clang" , " clang++" };
297
+ for (const char * candidate_name : candidate_names) {
298
+ fs::path candidate = path.parent_path () / candidate_name;
299
+ if (fs::equivalent (candidate, path)) {
300
+ LOG (" Detected that {} is equivalent to {} when guessing compiler type" ,
301
+ path,
302
+ candidate);
303
+ return candidate;
304
+ }
305
+ }
306
+ }
307
+ return path;
308
+ }
309
+
284
310
#endif
285
311
286
312
static CompilerType
@@ -314,7 +340,7 @@ guess_compiler(const fs::path& path)
314
340
return type;
315
341
#else
316
342
if (type == CompilerType::other) {
317
- return do_guess_compiler (follow_symlinks (path));
343
+ return do_guess_compiler (probe_generic_compiler ( follow_symlinks (path) ));
318
344
} else {
319
345
return type;
320
346
}
0 commit comments