about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksi Juvani <aleksi@aleksijuvani.com>2019-09-10 09:53:59 +0300
committerAleksi Juvani <aleksi@aleksijuvani.com>2019-09-10 16:41:56 +0300
commit2e9eba7f380f5fd99df92deaa03e00faa519b1a4 (patch)
tree0e5170e9b09ee594b8db572b37b35f0ba0a360c6
parent995d9857bdae6da200703e3aefbc39f5eded299b (diff)
Set environment variables for linker instead of sysroot
-rw-r--r--src/librustc_target/spec/apple_base.rs70
-rw-r--r--src/librustc_target/spec/apple_ios_base.rs61
-rw-r--r--src/librustc_target/spec/i686_apple_darwin.rs7
-rw-r--r--src/librustc_target/spec/x86_64_apple_darwin.rs7
4 files changed, 64 insertions, 81 deletions
diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index a8d6290aa43..e2632fc1414 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -1,4 +1,4 @@
-use std::{env, path::Path};
+use std::env;
 
 use crate::spec::{LinkArgs, TargetOptions};
 
@@ -52,62 +52,18 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
-#[cfg(target_os = "macos")]
-pub fn sysroot(sdk: &str) -> Result<Option<String>, String> {
-    // Like Clang, allow the `SDKROOT` environment variable used by Xcode to define the sysroot.
-    if let Some(sdk_root) = env::var("SDKROOT").ok() {
-        let actual_sdk_path = sdk_path(sdk)?;
-        let sdk_root_p = Path::new(&sdk_root);
-        // Ignore `SDKROOT` if it's not a valid path.
-        if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
-            return Ok(Some(actual_sdk_path));
+pub fn macos_link_env() -> Vec<(String, String)> {
+    let mut env = Vec::with_capacity(2);
+    // Ignore the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
+    // may occur when we're linking a custom build script while targeting iOS for example.
+    if let Some(sdkroot) = env::var("SDKROOT").ok() {
+        if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
+            env.push(("SDKROOT".to_string(), String::new()))
         }
-        // Ignore `SDKROOT` if it's clearly set for the wrong platform, which may occur when we're
-        // compiling a custom build script while targeting iOS for example.
-        return Ok(Some(match sdk {
-            "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
-                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
-            "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
-            "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("iPhoneSimulator.platform") => actual_sdk_path,
-            _ => sdk_root,
-        }))
-    }
-    Ok(None)
-}
-
-// `xcrun` is only available on macOS.
-#[cfg(not(target_os = "macos"))]
-pub fn sysroot(_sdk: &str) -> Result<Option<String>, String> {
-    if let Some(sdk_root) = env::var("SDKROOT").ok() {
-        let sdk_root_p = Path::new(&sdk_root);
-        // Use `SDKROOT` only if it's a valid path.
-        if sdk_root_p.is_absolute() && sdk_root_p != Path::new("/") && sdk_root_p.exists() {
-            return Ok(Some(sdk_root));
-        }
-    }
-    Ok(None)
-}
-
-#[cfg(target_os = "macos")]
-fn sdk_path(sdk_name: &str) -> Result<String, String> {
-    let res = std::process::Command::new("xcrun")
-        .arg("--show-sdk-path")
-        .arg("-sdk")
-        .arg(sdk_name)
-        .output()
-        .and_then(|output| {
-            if output.status.success() {
-                Ok(String::from_utf8(output.stdout).unwrap())
-            } else {
-                let error = String::from_utf8(output.stderr);
-                let error = format!("process exit with error: {}", error.unwrap());
-                Err(std::io::Error::new(std::io::ErrorKind::Other, &error[..]))
-            }
-        });
-    match res {
-        Ok(output) => Ok(output.trim().to_string()),
-        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
     }
+    // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
+    // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
+    // although this is apparently ignored when using the linker at "/usr/bin/ld".
+    env.push(("IPHONEOS_DEPLOYMENT_TARGET".to_string(), String::new()));
+    env
 }
diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index 801736944f4..6d3900c0b20 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -1,3 +1,7 @@
+use std::env;
+use std::io;
+use std::path::Path;
+use std::process::Command;
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
 
 use Arch::*;
@@ -26,6 +30,42 @@ impl Arch {
     }
 }
 
+pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
+    // Following what clang does
+    // (https://github.com/llvm/llvm-project/blob/
+    // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
+    // to allow the SDK path to be set. (For clang, xcrun sets
+    // SDKROOT; for rustc, the user or build system can set it, or we
+    // can fall back to checking for xcrun on PATH.)
+    if let Some(sdkroot) = env::var("SDKROOT").ok() {
+        let sdkroot_path = Path::new(&sdkroot);
+        if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {
+            return Ok(sdkroot);
+        }
+    }
+    let res = Command::new("xcrun")
+                      .arg("--show-sdk-path")
+                      .arg("-sdk")
+                      .arg(sdk_name)
+                      .output()
+                      .and_then(|output| {
+                          if output.status.success() {
+                              Ok(String::from_utf8(output.stdout).unwrap())
+                          } else {
+                              let error = String::from_utf8(output.stderr);
+                              let error = format!("process exit with error: {}",
+                                                  error.unwrap());
+                              Err(io::Error::new(io::ErrorKind::Other,
+                                                 &error[..]))
+                          }
+                      });
+
+    match res {
+        Ok(output) => Ok(output.trim().to_string()),
+        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e))
+    }
+}
+
 fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
     let sdk_name = match arch {
         Armv7 | Armv7s | Arm64 => "iphoneos",
@@ -35,19 +75,16 @@ fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
 
     let arch_name = arch.to_string();
 
+    let sdk_root = get_sdk_root(sdk_name)?;
+
     let mut args = LinkArgs::new();
-    args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), arch_name.to_string()]);
-    if let Some(sdk_root) = super::apple_base::sysroot(sdk_name)? {
-        args.insert(
-            LinkerFlavor::Gcc,
-            vec![
-                "-isysroot".to_string(),
-                sdk_root.clone(),
-                "-Wl,-syslibroot".to_string(),
-                sdk_root
-            ],
-        );
-    }
+    args.insert(LinkerFlavor::Gcc,
+                vec!["-arch".to_string(),
+                     arch_name.to_string(),
+                     "-isysroot".to_string(),
+                     sdk_root.clone(),
+                     "-Wl,-syslibroot".to_string(),
+                     sdk_root]);
 
     Ok(args)
 }
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index b08ed560252..ba44cdccb7c 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -5,12 +5,7 @@ pub fn target() -> TargetResult {
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
-    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
-        base.pre_link_args.insert(
-            LinkerFlavor::Gcc,
-            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
-        );
-    }
+    base.link_env.extend(super::apple_base::macos_link_env());
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index f299c27e7e1..442c2650bbb 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -6,12 +6,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
-    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
-        base.pre_link_args.insert(
-            LinkerFlavor::Gcc,
-            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
-        );
-    }
+    base.link_env.extend(super::apple_base::macos_link_env());
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on