about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Schwender <jonathan.schwender@huawei.com>2023-01-05 14:14:23 +0100
committerJonathan Schwender <jonathan.schwender@huawei.com>2023-01-13 17:20:37 +0100
commit3bc2970a2e5f80f04ac2c1b1c1e4ec06a001f151 (patch)
treedd48688a3eb86e4e0d5f91d131f8d09ee40435da
parent5ca6f7d2c34953ee360ccf7d3c84c7853ea2df4b (diff)
downloadrust-3bc2970a2e5f80f04ac2c1b1c1e4ec06a001f151.tar.gz
rust-3bc2970a2e5f80f04ac2c1b1c1e4ec06a001f151.zip
Improve linker-flavor detection
Linker drivers such as gcc, clang or lld often have a version postfix,
e.g clang-12. The previous logic would not account for this and would
fall back to guessing the linker flavor to be the default linker flavor
for the target, which causes linker errors when this is not the case.
By accounting for the possible version postfix and also considering
g++ and clang++, we considerably reduce the amount of times the
fallback guess has to be used.

To simplify matching check for a version postfix and match against the
linker stem without any version postfix.
In contrast to gcc, clang supports all architectures in one binary.
This means there are no variants like `aarch64-linux-gnu-clang` and
there is no need to check for `-clang` variants.
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 8ca7103ed48..342abf81f6a 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1231,12 +1231,21 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                     sess.emit_fatal(errors::LinkerFileStem);
                 });
 
+                // Remove any version postfix.
+                let stem = stem
+                    .rsplit_once('-')
+                    .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs))
+                    .unwrap_or(stem);
+
+                // GCC can have an optional target prefix.
                 let flavor = if stem == "emcc" {
                     LinkerFlavor::EmCc
                 } else if stem == "gcc"
                     || stem.ends_with("-gcc")
+                    || stem == "g++"
+                    || stem.ends_with("-g++")
                     || stem == "clang"
-                    || stem.ends_with("-clang")
+                    || stem == "clang++"
                 {
                     LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target)
                 } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {