Defer Apple SDKROOT detection to link time.
This commit is contained in:
parent
b984ef6797
commit
c29a29cba0
10 changed files with 104 additions and 128 deletions
|
@ -1289,6 +1289,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor)
|
||||||
cmd.args(args);
|
cmd.args(args);
|
||||||
}
|
}
|
||||||
cmd.args(&sess.opts.debugging_opts.pre_link_args);
|
cmd.args(&sess.opts.debugging_opts.pre_link_args);
|
||||||
|
add_apple_sdk(cmd, sess, flavor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a link script embedded in the target, if applicable.
|
/// Add a link script embedded in the target, if applicable.
|
||||||
|
@ -2083,3 +2084,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
|
||||||
config::Lto::No | config::Lto::ThinLocal => false,
|
config::Lto::No | config::Lto::ThinLocal => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
||||||
|
let arch = &sess.target.target.arch;
|
||||||
|
let os = &sess.target.target.target_os;
|
||||||
|
let llvm_target = &sess.target.target.llvm_target;
|
||||||
|
if sess.target.target.target_vendor != "apple"
|
||||||
|
|| !matches!(os.as_str(), "ios" | "tvos")
|
||||||
|
|| flavor != LinkerFlavor::Gcc
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let sdk_name = match (arch.as_str(), os.as_str()) {
|
||||||
|
("aarch64", "tvos") => "appletvos",
|
||||||
|
("x86_64", "tvos") => "appletvsimulator",
|
||||||
|
("arm", "ios") => "iphoneos",
|
||||||
|
("aarch64", "ios") => "iphoneos",
|
||||||
|
("x86", "ios") => "iphonesimulator",
|
||||||
|
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx10.15",
|
||||||
|
("x86_64", "ios") => "iphonesimulator",
|
||||||
|
_ => {
|
||||||
|
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let sdk_root = match get_apple_sdk_root(sdk_name) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
sess.err(&e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
|
||||||
|
cmd.args(&["-arch", arch_name, "-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_apple_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 Ok(sdkroot) = env::var("SDKROOT") {
|
||||||
|
let p = Path::new(&sdkroot);
|
||||||
|
match sdk_name {
|
||||||
|
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
|
||||||
|
"appletvos"
|
||||||
|
if sdkroot.contains("TVSimulator.platform")
|
||||||
|
|| sdkroot.contains("MacOSX.platform") => {}
|
||||||
|
"appletvsimulator"
|
||||||
|
if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {}
|
||||||
|
"iphoneos"
|
||||||
|
if sdkroot.contains("iPhoneSimulator.platform")
|
||||||
|
|| sdkroot.contains("MacOSX.platform") => {}
|
||||||
|
"iphonesimulator"
|
||||||
|
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => {
|
||||||
|
}
|
||||||
|
"macosx10.15"
|
||||||
|
if sdkroot.contains("iPhoneOS.platform")
|
||||||
|
|| sdkroot.contains("iPhoneSimulator.platform") => {}
|
||||||
|
// Ignore `SDKROOT` if it's not a valid path.
|
||||||
|
_ if !p.is_absolute() || p == Path::new("/") || !p.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)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::Arm64, AppleOS::iOS)?;
|
let base = opts(Arch::Arm64);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "arm64-apple-ios".to_string(),
|
llvm_target: "arm64-apple-ios".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::Arm64, AppleOS::tvOS)?;
|
let base = opts(Arch::Arm64);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "arm64-apple-tvos".to_string(),
|
llvm_target: "arm64-apple-tvos".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
|
use crate::spec::TargetOptions;
|
||||||
use std::env;
|
|
||||||
use std::io;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use Arch::*;
|
use Arch::*;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -16,108 +12,6 @@ pub enum Arch {
|
||||||
X86_64_macabi,
|
X86_64_macabi,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum AppleOS {
|
|
||||||
tvOS,
|
|
||||||
iOS,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Arch {
|
|
||||||
pub fn to_string(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Armv7 => "armv7",
|
|
||||||
Armv7s => "armv7s",
|
|
||||||
Arm64 => "arm64",
|
|
||||||
I386 => "i386",
|
|
||||||
X86_64 => "x86_64",
|
|
||||||
X86_64_macabi => "x86_64",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Ok(sdkroot) = env::var("SDKROOT") {
|
|
||||||
let p = Path::new(&sdkroot);
|
|
||||||
match sdk_name {
|
|
||||||
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
|
|
||||||
"appletvos"
|
|
||||||
if sdkroot.contains("TVSimulator.platform")
|
|
||||||
|| sdkroot.contains("MacOSX.platform") => {}
|
|
||||||
"appletvsimulator"
|
|
||||||
if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {}
|
|
||||||
"iphoneos"
|
|
||||||
if sdkroot.contains("iPhoneSimulator.platform")
|
|
||||||
|| sdkroot.contains("MacOSX.platform") => {}
|
|
||||||
"iphonesimulator"
|
|
||||||
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => {
|
|
||||||
}
|
|
||||||
"macosx10.15"
|
|
||||||
if sdkroot.contains("iPhoneOS.platform")
|
|
||||||
|| sdkroot.contains("iPhoneSimulator.platform") => {}
|
|
||||||
// Ignore `SDKROOT` if it's not a valid path.
|
|
||||||
_ if !p.is_absolute() || p == Path::new("/") || !p.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, os: AppleOS) -> Result<LinkArgs, String> {
|
|
||||||
let sdk_name = match (arch, os) {
|
|
||||||
(Arm64, AppleOS::tvOS) => "appletvos",
|
|
||||||
(X86_64, AppleOS::tvOS) => "appletvsimulator",
|
|
||||||
(Armv7, AppleOS::iOS) => "iphoneos",
|
|
||||||
(Armv7s, AppleOS::iOS) => "iphoneos",
|
|
||||||
(Arm64, AppleOS::iOS) => "iphoneos",
|
|
||||||
(I386, AppleOS::iOS) => "iphonesimulator",
|
|
||||||
(X86_64, AppleOS::iOS) => "iphonesimulator",
|
|
||||||
(X86_64_macabi, AppleOS::iOS) => "macosx10.15",
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
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(),
|
|
||||||
"-isysroot".to_string(),
|
|
||||||
sdk_root.clone(),
|
|
||||||
"-Wl,-syslibroot".to_string(),
|
|
||||||
sdk_root,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn target_cpu(arch: Arch) -> String {
|
fn target_cpu(arch: Arch) -> String {
|
||||||
match arch {
|
match arch {
|
||||||
Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
|
Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
|
||||||
|
@ -137,15 +31,13 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opts(arch: Arch, os: AppleOS) -> Result<TargetOptions, String> {
|
pub fn opts(arch: Arch) -> TargetOptions {
|
||||||
let pre_link_args = build_pre_link_args(arch, os)?;
|
TargetOptions {
|
||||||
Ok(TargetOptions {
|
|
||||||
cpu: target_cpu(arch),
|
cpu: target_cpu(arch),
|
||||||
executables: true,
|
executables: true,
|
||||||
pre_link_args,
|
|
||||||
link_env_remove: link_env_remove(arch),
|
link_env_remove: link_env_remove(arch),
|
||||||
has_elf_tls: false,
|
has_elf_tls: false,
|
||||||
eliminate_frame_pointer: false,
|
eliminate_frame_pointer: false,
|
||||||
..super::apple_base::opts()
|
..super::apple_base::opts()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::Armv7, AppleOS::iOS)?;
|
let base = opts(Arch::Armv7);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "armv7-apple-ios".to_string(),
|
llvm_target: "armv7-apple-ios".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::Armv7s, AppleOS::iOS)?;
|
let base = opts(Arch::Armv7s);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "armv7s-apple-ios".to_string(),
|
llvm_target: "armv7s-apple-ios".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::I386, AppleOS::iOS)?;
|
let base = opts(Arch::I386);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "i386-apple-ios".to_string(),
|
llvm_target: "i386-apple-ios".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::X86_64, AppleOS::iOS)?;
|
let base = opts(Arch::X86_64);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "x86_64-apple-ios".to_string(),
|
llvm_target: "x86_64-apple-ios".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::X86_64_macabi, AppleOS::iOS)?;
|
let base = opts(Arch::X86_64_macabi);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "x86_64-apple-ios13.0-macabi".to_string(),
|
llvm_target: "x86_64-apple-ios13.0-macabi".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::apple_sdk_base::{opts, AppleOS, Arch};
|
use super::apple_sdk_base::{opts, Arch};
|
||||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let base = opts(Arch::X86_64, AppleOS::iOS)?;
|
let base = opts(Arch::X86_64);
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
llvm_target: "x86_64-apple-tvos".to_string(),
|
llvm_target: "x86_64-apple-tvos".to_string(),
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue