about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs23
1 files changed, 21 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 9a796356593..fb79df4f791 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2999,8 +2999,27 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
     // the CLI, and what the target spec enables (as it can't disable components):
     // - if the self-contained linker is enabled on the CLI or by the target spec,
     // - and if the self-contained linker is not disabled on the CLI.
-    let self_contained_linker = sess.opts.cg.link_self_contained.is_linker_enabled()
-        || sess.target.options.link_self_contained.is_linker_enabled();
+    let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
+    let self_contained_target = sess.target.options.link_self_contained.is_linker_enabled();
+
+    // FIXME: in the future, codegen backends may need to have more control over this process: they
+    // don't always support all the features the linker expects here, and vice versa. For example,
+    // at the time of writing this, lld expects a newer style of aarch64 TLS relocations that
+    // cranelift doesn't implement yet. That in turn can impact whether linking would succeed on
+    // such a target when using the `cg_clif` backend and lld.
+    //
+    // Until interactions between backends and linker features are expressible, we limit target
+    // specs to opt-in to lld only when we're on the llvm backend, where it's expected to work and
+    // tested on CI. As usual, the CLI still has precedence over this, so that users and developers
+    // can still override this default when needed (e.g. for tests).
+    let uses_llvm_backend =
+        matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm"));
+    if !uses_llvm_backend && !self_contained_cli && sess.opts.cg.linker_flavor.is_none() {
+        // We bail if we're not using llvm and lld was not explicitly requested on the CLI.
+        return;
+    }
+
+    let self_contained_linker = self_contained_cli || self_contained_target;
     if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
         for path in sess.get_tools_search_paths(false) {
             cmd.arg({