-use std::env;
+use std::{env, io, path::Path, process::Command};
use crate::spec::{LinkArgs, TargetOptions};
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)),
+ }
+}
-use std::env;
-use std::io;
-use std::path::Path;
-use std::process::Command;
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use 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",
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,
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;
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