diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-10-01 02:13:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-01 02:13:34 +0200 |
| commit | 37df40bd1c9374ca91112f2d1ea0e27127130c09 (patch) | |
| tree | b262ff0dcb381edea7a7ba38fdcc3746e7c65738 /compiler | |
| parent | 8ccc063fbc54e5fea3a4811310ff0bb0821d2992 (diff) | |
| parent | 7420d7a98044ea1bf727ab369cbc77232dd99694 (diff) | |
| download | rust-37df40bd1c9374ca91112f2d1ea0e27127130c09.tar.gz rust-37df40bd1c9374ca91112f2d1ea0e27127130c09.zip | |
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
Diffstat (limited to 'compiler')
10 files changed, 106 insertions, 128 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 87d539f748c..010fd4e9c5a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1524,6 +1524,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT add_pre_link_args(cmd, sess, flavor); + // NO-OPT-OUT, OBJECT-FILES-NO + add_apple_sdk(cmd, sess, flavor); + // NO-OPT-OUT add_link_script(cmd, sess, tmpdir, crate_type); @@ -2083,3 +2086,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { 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)), + } +} diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index 21dcec8d5e3..168cd01878e 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index 2b0cd6cabf8..5e2cab0df1e 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index 0d0a0da9d1c..e34277d5af0 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -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() - }) + } } diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs index 393843526a8..6dafcc2c345 100644 --- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs index 998a7b2e164..d6c99c4ade6 100644 --- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index a121d49769d..6cb209ab1c0 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index cfcf856836b..fd3e4e2f57b 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index c42d0911725..4cfbd9eba06 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -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(), diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index a56062c0b2b..664a3ed8816 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -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(), |
