]> git.lizzy.rs Git - rust.git/commitdiff
Fix sysroot on macOS when cross-compiling and SDKROOT is set
authorAleksi Juvani <aleksi@aleksijuvani.com>
Sat, 7 Sep 2019 14:18:10 +0000 (17:18 +0300)
committerAleksi Juvani <aleksi@aleksijuvani.com>
Sat, 7 Sep 2019 14:20:12 +0000 (17:20 +0300)
Fixes rust-lang/cargo#7283
Closes rust-lang/cargo#7284

r? @alexcrichton

src/librustc_target/spec/apple_base.rs
src/librustc_target/spec/apple_ios_base.rs
src/librustc_target/spec/i686_apple_darwin.rs
src/librustc_target/spec/x86_64_apple_darwin.rs

index 53364e72bfe3ad70e71e49efe893799c8d4ed8b5..aa5080aaaf6e670371398d462d8a021b8ef76c4b 100644 (file)
@@ -1,4 +1,4 @@
-use std::env;
+use std::{env, io, path::Path, process::Command};
 
 use crate::spec::{LinkArgs, TargetOptions};
 
@@ -51,3 +51,46 @@ pub fn macos_llvm_target(arch: &str) -> String {
     let (major, minor) = macos_deployment_target();
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
+
+pub fn sysroot(sdk: &str) -> Result<String, String> {
+    let actual_sdk_path = sdk_path(sdk)?;
+    // Like Clang, allow the SDKROOT environment variable used by Xcode to define the sysroot
+    if let Some(sdk_root) = env::var("SDKROOT").ok() {
+        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(actual_sdk_path);
+        }
+        // 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
+        match sdk {
+            "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
+                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+            "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
+                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+            "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
+                || sdk_root.contains("iPhoneSimulator.platform") => return Ok(actual_sdk_path),
+            _ => return Ok(sdk_root),
+        }
+    }
+    Ok(actual_sdk_path)
+}
+
+fn sdk_path(sdk_name: &str) -> Result<String, String> {
+    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)),
+    }
+}
index 6d3900c0b203f372fe64112322a29d73d7cca658..db4a8180831834e96212ce8d302d13d8f7dc259c 100644 (file)
@@ -1,7 +1,3 @@
-use std::env;
-use std::io;
-use std::path::Path;
-use std::process::Command;
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
 
 use Arch::*;
@@ -30,42 +26,6 @@ pub fn to_string(self) -> &'static str {
     }
 }
 
-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",
@@ -75,7 +35,7 @@ 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 sdk_root = super::apple_base::sysroot(sdk_name)?;
 
     let mut args = LinkArgs::new();
     args.insert(LinkerFlavor::Gcc,
index 7d804ea53fb31aa7521ee5926397594ede17ff5f..a60c00721247413dd403c379b7b75cf2a4dd15fd 100644 (file)
@@ -1,10 +1,20 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
+    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
-    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
+    base.pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            "-m32".to_string(),
+            "-isysroot".to_string(),
+            sysroot.clone(),
+            "-Wl,-syslibroot".to_string(),
+            sysroot,
+        ],
+    );
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
index 182103440f035e9a0d47109131ad2ba7e3f96718..b72d037565b5b70b6ec744601d4ede7896d55122 100644 (file)
@@ -1,11 +1,21 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
+    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "core2".to_string();
     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()]);
+    base.pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            "-m64".to_string(),
+            "-isysroot".to_string(),
+            sysroot.clone(),
+            "-Wl,-syslibroot".to_string(),
+            sysroot,
+        ],
+    );
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on