@@ -2999,8 +2999,27 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2999
2999
// the CLI, and what the target spec enables (as it can't disable components):
3000
3000
// - if the self-contained linker is enabled on the CLI or by the target spec,
3001
3001
// - and if the self-contained linker is not disabled on the CLI.
3002
- let self_contained_linker = sess. opts . cg . link_self_contained . is_linker_enabled ( )
3003
- || sess. target . options . link_self_contained . is_linker_enabled ( ) ;
3002
+ let self_contained_cli = sess. opts . cg . link_self_contained . is_linker_enabled ( ) ;
3003
+ let self_contained_target = sess. target . options . link_self_contained . is_linker_enabled ( ) ;
3004
+
3005
+ // FIXME: in the future, codegen backends may need to have more control over this process: they
3006
+ // don't always support all the features the linker expects here, and vice versa. For example,
3007
+ // at the time of writing this, lld expects a newer style of aarch64 TLS relocations that
3008
+ // cranelift doesn't implement yet. That in turn can impact whether linking would succeed on
3009
+ // such a target when using the `cg_clif` backend and lld.
3010
+ //
3011
+ // Until interactions between backends and linker features are expressible, we limit target
3012
+ // specs to opt-in to lld only when we're on the llvm backend, where it's expected to work and
3013
+ // tested on CI. As usual, the CLI still has precedence over this, so that users and developers
3014
+ // can still override this default when needed (e.g. for tests).
3015
+ let uses_llvm_backend =
3016
+ matches ! ( sess. opts. unstable_opts. codegen_backend. as_deref( ) , None | Some ( "llvm" ) ) ;
3017
+ if !uses_llvm_backend && !self_contained_cli && sess. opts . cg . linker_flavor . is_none ( ) {
3018
+ // We bail if we're not using llvm and lld was not explicitly requested on the CLI.
3019
+ return ;
3020
+ }
3021
+
3022
+ let self_contained_linker = self_contained_cli || self_contained_target;
3004
3023
if self_contained_linker && !sess. opts . cg . link_self_contained . is_linker_disabled ( ) {
3005
3024
for path in sess. get_tools_search_paths ( false ) {
3006
3025
cmd. arg ( {
0 commit comments