diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 507af3f9aa7..72d6a0265ef 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -115,10 +115,16 @@ pub(crate) fn build_sysroot(
             }
         }
         SysrootKind::Clif => {
-            build_clif_sysroot_for_triple(channel, target_dir, target_triple);
+            build_clif_sysroot_for_triple(channel, target_dir, host_triple, None);
 
             if host_triple != target_triple {
-                build_clif_sysroot_for_triple(channel, target_dir, host_triple);
+                // When cross-compiling it is often necessary to manually pick the right linker
+                let linker = if target_triple == "aarch64-unknown-linux-gnu" {
+                    Some("aarch64-linux-gnu-gcc")
+                } else {
+                    None
+                };
+                build_clif_sysroot_for_triple(channel, target_dir, target_triple, linker);
             }
 
             // Copy std for the host to the lib dir. This is necessary for the jit mode to find
@@ -133,7 +139,12 @@ pub(crate) fn build_sysroot(
     }
 }
 
-fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str) {
+fn build_clif_sysroot_for_triple(
+    channel: &str,
+    target_dir: &Path,
+    triple: &str,
+    linker: Option<&str>,
+) {
     let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
 
     let keep_sysroot =
@@ -155,6 +166,10 @@ fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str)
         build_cmd.arg("--release");
         rustflags.push_str(" -Zmir-opt-level=3");
     }
+    if let Some(linker) = linker {
+        use std::fmt::Write;
+        write!(rustflags, " -Clinker={}", linker).unwrap();
+    }
     build_cmd.env("RUSTFLAGS", rustflags);
     build_cmd.env(
         "RUSTC",
diff --git a/src/lib.rs b/src/lib.rs
index 6e127ce23dc..50317b192ed 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -287,10 +287,12 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
         }
         None => {
             let mut builder =
-                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
-            // Don't use "haswell" as the default, as it implies `has_lzcnt`.
-            // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
-            builder.enable("nehalem").unwrap();
+                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant).unwrap();
+            if target_triple.architecture == target_lexicon::Architecture::X86_64 {
+                // Don't use "haswell" as the default, as it implies `has_lzcnt`.
+                // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
+                builder.enable("nehalem").unwrap();
+            }
             builder
         }
     };