diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
index f01ff02da07..3ffc852d650 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
@@ -9,6 +9,7 @@ pub fn target() -> Target {
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
 
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
+    base.link_env.extend(super::apple_base::macos_link_env("arm64"));
     base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
 
     // Clang automatically chooses a more specific target based on
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index db6aee59a5d..ba8f9a8ce11 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -79,6 +79,18 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
+pub fn macos_link_env(arch: &str) -> Vec<(String, String)> {
+    // Use the default deployment target for linking just as with the LLVM target if not
+    // specified via MACOSX_DEPLOYMENT_TARGET, otherwise the system linker would use its
+    // default which varies with Xcode version.
+    if env::var("MACOSX_DEPLOYMENT_TARGET").is_err() {
+        let default = macos_default_deployment_target(arch);
+        vec![("MACOSX_DEPLOYMENT_TARGET".to_string(), format!("{}.{}", default.0, default.1))]
+    } else {
+        vec![]
+    }
+}
+
 pub fn macos_link_env_remove() -> Vec<String> {
     let mut env_remove = Vec::with_capacity(2);
     // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index f2635f0656d..05217c09aed 100644
--- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
@@ -5,6 +5,7 @@ pub fn target() -> Target {
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
+    base.link_env.extend(super::apple_base::macos_link_env("i686"));
     base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
     // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
     base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index 22fdaabfcb8..3e20cb0b272 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         LinkerFlavor::Gcc,
         vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
     );
+    base.link_env.extend(super::apple_base::macos_link_env("x86_64"));
     base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
     // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
     base.stack_probes = StackProbeType::Call;