1
Fork 0

Rollup merge of #77202 - ehuss:defer-apple-sdkroot, r=petrochenkov

Defer Apple SDKROOT detection to link time.

This defers the detection of the SDKROOT for Apple iOS/tvOS targets to link time, instead of when the `Target` is defined. This allows commands that don't need to link to work (like `rustdoc` or `rustc --print=target-list`). This also makes `--print=target-list` a bit faster.

This also removes the note in the platform support documentation about these targets being missing. When I wrote it, I misunderstood how the SDKROOT stuff worked.

Notes:
* This means that JSON spec targets can't explicitly override these flags. I think that is probably fine, as I believe the value is generally required, and can be set with the SDKROOT environment variable.
* This changes `x86_64-apple-tvos` to use `appletvsimulator`. I think the original code was wrong (it was using `iphonesimulator`). Also, `x86_64-apple-tvos` seems broken in general, and I cannot build it locally. The `data_layout` does not appear to be correct (it is a copy of the arm64 layout instead of the x86_64 layout). I have not tried building Apple's LLVM to see if that helps, but I suspect it is just wrong (I'm uncertain since I don't know how the tvOS simulator works with its bitcode-only requirements).
* I'm tempted to remove the use of `Result` for built-in target definitions, since I don't think they should be fallible. This was added in https://github.com/rust-lang/rust/pull/34980, but that only relates to JSON definitions. I think the built-in targets shouldn't fail. I can do this now, or not.

Fixes #36156
Fixes #76584
This commit is contained in:
Dylan DPC 2020-10-01 02:13:34 +02:00 committed by GitHub
commit 37df40bd1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 114 additions and 139 deletions

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::Arm64, AppleOS::iOS)?;
let base = opts(Arch::Arm64);
Ok(Target {
llvm_target: "arm64-apple-ios".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::Arm64, AppleOS::tvOS)?;
let base = opts(Arch::Arm64);
Ok(Target {
llvm_target: "arm64-apple-tvos".to_string(),
target_endian: "little".to_string(),

View file

@ -1,8 +1,4 @@
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::env;
use std::io;
use std::path::Path;
use std::process::Command;
use crate::spec::TargetOptions;
use Arch::*;
#[allow(non_camel_case_types)]
@ -16,108 +12,6 @@ pub enum Arch {
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 {
match arch {
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> {
let pre_link_args = build_pre_link_args(arch, os)?;
Ok(TargetOptions {
pub fn opts(arch: Arch) -> TargetOptions {
TargetOptions {
cpu: target_cpu(arch),
executables: true,
pre_link_args,
link_env_remove: link_env_remove(arch),
has_elf_tls: false,
eliminate_frame_pointer: false,
..super::apple_base::opts()
})
}
}

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::Armv7, AppleOS::iOS)?;
let base = opts(Arch::Armv7);
Ok(Target {
llvm_target: "armv7-apple-ios".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::Armv7s, AppleOS::iOS)?;
let base = opts(Arch::Armv7s);
Ok(Target {
llvm_target: "armv7s-apple-ios".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::I386, AppleOS::iOS)?;
let base = opts(Arch::I386);
Ok(Target {
llvm_target: "i386-apple-ios".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::X86_64, AppleOS::iOS)?;
let base = opts(Arch::X86_64);
Ok(Target {
llvm_target: "x86_64-apple-ios".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::X86_64_macabi, AppleOS::iOS)?;
let base = opts(Arch::X86_64_macabi);
Ok(Target {
llvm_target: "x86_64-apple-ios13.0-macabi".to_string(),
target_endian: "little".to_string(),

View file

@ -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};
pub fn target() -> TargetResult {
let base = opts(Arch::X86_64, AppleOS::iOS)?;
let base = opts(Arch::X86_64);
Ok(Target {
llvm_target: "x86_64-apple-tvos".to_string(),
target_endian: "little".to_string(),