mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
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:
commit
37df40bd1c
@ -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)),
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -57,7 +57,7 @@ Specifically, these platforms are required to have each of the following:
|
||||
|
||||
target | std | host | notes
|
||||
-------|-----|------|-------
|
||||
`aarch64-apple-ios` | ✓[^apple] | | ARM64 iOS
|
||||
`aarch64-apple-ios` | ✓ | | ARM64 iOS
|
||||
`aarch64-fuchsia` | ✓ | | ARM64 Fuchsia
|
||||
`aarch64-linux-android` | ✓ | | ARM64 Android
|
||||
`aarch64-pc-windows-msvc` | ✓ | | ARM64 Windows MSVC
|
||||
@ -122,7 +122,7 @@ target | std | host | notes
|
||||
`wasm32-unknown-emscripten` | ✓ | | WebAssembly via Emscripten
|
||||
`wasm32-unknown-unknown` | ✓ | | WebAssembly
|
||||
`wasm32-wasi` | ✓ | | WebAssembly with WASI
|
||||
`x86_64-apple-ios` | ✓[^apple] | | 64-bit x86 iOS
|
||||
`x86_64-apple-ios` | ✓ | | 64-bit x86 iOS
|
||||
`x86_64-fortanix-unknown-sgx` | ✓ | | [Fortanix ABI] for 64-bit Intel SGX
|
||||
`x86_64-fuchsia` | ✓ | | 64-bit Fuchsia
|
||||
`x86_64-linux-android` | ✓ | | 64-bit x86 Android
|
||||
@ -146,7 +146,7 @@ not available.
|
||||
target | std | host | notes
|
||||
-------|-----|------|-------
|
||||
`aarch64-apple-darwin` | ? | | ARM64 macOS
|
||||
`aarch64-apple-tvos` | *[^apple] | | ARM64 tvOS
|
||||
`aarch64-apple-tvos` | * | | ARM64 tvOS
|
||||
`aarch64-unknown-cloudabi` | ✓ | | ARM64 CloudABI
|
||||
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
|
||||
`aarch64-unknown-hermit` | ? | |
|
||||
@ -158,16 +158,16 @@ target | std | host | notes
|
||||
`armv4t-unknown-linux-gnueabi` | ? | |
|
||||
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
|
||||
`armv6-unknown-netbsd-eabihf` | ? | |
|
||||
`armv7-apple-ios` | ✓[^apple] | | ARMv7 iOS, Cortex-a8
|
||||
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
|
||||
`armv7-unknown-cloudabi-eabihf` | ✓ | | ARMv7 CloudABI, hardfloat
|
||||
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
|
||||
`armv7-unknown-netbsd-eabihf` | ? | |
|
||||
`armv7-wrs-vxworks-eabihf` | ? | |
|
||||
`armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat
|
||||
`armv7s-apple-ios` | ✓[^apple] | |
|
||||
`armv7s-apple-ios` | ✓ | |
|
||||
`avr-unknown-gnu-atmega328` | ✗ | | AVR. Requires `-Z build-std=core`
|
||||
`hexagon-unknown-linux-musl` | ? | |
|
||||
`i386-apple-ios` | ✓[^apple] | | 32-bit x86 iOS
|
||||
`i386-apple-ios` | ✓ | | 32-bit x86 iOS
|
||||
`i686-apple-darwin` | ✓ | ✓ | 32-bit OSX (10.7+, Lion+)
|
||||
`i686-pc-windows-msvc` | ✓ | | 32-bit Windows XP support
|
||||
`i686-unknown-cloudabi` | ✓ | | 32-bit CloudABI
|
||||
@ -203,8 +203,8 @@ target | std | host | notes
|
||||
`thumbv7a-uwp-windows-msvc` | ✓ | |
|
||||
`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL
|
||||
`thumbv4t-none-eabi` | * | | ARMv4T T32
|
||||
`x86_64-apple-ios-macabi` | ✓[^apple] | | Apple Catalyst
|
||||
`x86_64-apple-tvos` | *[^apple] | | x86 64-bit tvOS
|
||||
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst
|
||||
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
|
||||
`x86_64-linux-kernel` | * | | Linux kernel modules
|
||||
`x86_64-pc-solaris` | ? | |
|
||||
`x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support
|
||||
@ -221,4 +221,3 @@ target | std | host | notes
|
||||
`x86_64-wrs-vxworks` | ? | |
|
||||
|
||||
[runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
|
||||
[^apple]: These targets are only available on macOS.
|
||||
|
@ -25,8 +25,6 @@ fn main() {
|
||||
let doc_targets: HashSet<_> = doc_targets_md
|
||||
.lines()
|
||||
.filter(|line| line.starts_with('`') && line.contains('|'))
|
||||
// These platforms only exist on macos.
|
||||
.filter(|line| !line.contains("[^apple]") || cfg!(target_os = "macos"))
|
||||
.map(|line| line.split('`').skip(1).next().expect("expected target code span"))
|
||||
.collect();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user