From dc5c61028ab9e0a1985ccc913fcab88b5f50efb6 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Wed, 23 Mar 2022 14:54:58 +0000 Subject: [PATCH] Add Apple WatchOS compile targets --- compiler/rustc_codegen_llvm/src/back/write.rs | 3 +- compiler/rustc_codegen_ssa/src/back/link.rs | 14 ++++- .../src/spec/aarch64_apple_watchos_sim.rs | 38 +++++++++++++ compiler/rustc_target/src/spec/apple_base.rs | 9 +++ .../rustc_target/src/spec/apple_sdk_base.rs | 8 ++- .../src/spec/arm64_32_apple_watchos.rs | 28 ++++++++++ .../src/spec/armv7k_apple_watchos.rs | 28 ++++++++++ compiler/rustc_target/src/spec/mod.rs | 5 ++ .../src/spec/x86_64_apple_watchos_sim.rs | 35 ++++++++++++ src/bootstrap/native.rs | 7 ++- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 4 ++ .../src/platform-support/apple-watchos.md | 55 +++++++++++++++++++ .../ui/check-cfg/well-known-values.stderr | 2 +- src/tools/compiletest/src/raise_fd_limit.rs | 2 +- src/tools/compiletest/src/util.rs | 1 + 16 files changed, 231 insertions(+), 9 deletions(-) create mode 100644 compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs create mode 100644 compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs create mode 100644 compiler/rustc_target/src/spec/armv7k_apple_watchos.rs create mode 100644 compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs create mode 100644 src/doc/rustc/src/platform-support/apple-watchos.md diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 50f8949c897..c55a22ff23f 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1036,7 +1036,8 @@ unsafe fn embed_bitcode( // reason (see issue #90326 for historical background). let is_apple = cgcx.opts.target_triple.triple().contains("-ios") || cgcx.opts.target_triple.triple().contains("-darwin") - || cgcx.opts.target_triple.triple().contains("-tvos"); + || cgcx.opts.target_triple.triple().contains("-tvos") + || cgcx.opts.target_triple.triple().contains("-watchos"); if is_apple || cgcx.opts.target_triple.triple().starts_with("wasm") || cgcx.opts.target_triple.triple().starts_with("asmjs") diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1f5e2b76bf0..7986690cce2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2602,7 +2602,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { let os = &sess.target.os; let llvm_target = &sess.target.llvm_target; if sess.target.vendor != "apple" - || !matches!(os.as_ref(), "ios" | "tvos") + || !matches!(os.as_ref(), "ios" | "tvos" | "watchos") || flavor != LinkerFlavor::Gcc { return; @@ -2612,11 +2612,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { ("x86_64", "tvos") => "appletvsimulator", ("arm", "ios") => "iphoneos", ("aarch64", "ios") if llvm_target.contains("macabi") => "macosx", - ("aarch64", "ios") if llvm_target.contains("sim") => "iphonesimulator", + ("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator", ("aarch64", "ios") => "iphoneos", ("x86", "ios") => "iphonesimulator", ("x86_64", "ios") if llvm_target.contains("macabi") => "macosx", ("x86_64", "ios") => "iphonesimulator", + ("x86_64", "watchos") => "watchsimulator", + ("arm64_32", "watchos") => "watchos", + ("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator", + ("aarch64", "watchos") => "watchos", + ("arm", "watchos") => "watchos", _ => { sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os)); return; @@ -2663,6 +2668,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { "macosx10.15" if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") => {} + "watchos" + if sdkroot.contains("WatchSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "watchsimulator" + if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {} // Ignore `SDKROOT` if it's not a valid path. _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} _ => return Ok(sdkroot), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs new file mode 100644 index 00000000000..3059f42140b --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs @@ -0,0 +1,38 @@ +use super::apple_sdk_base::{opts, Arch}; +use crate::spec::{FramePointer, Target, TargetOptions}; + +pub fn target() -> Target { + let base = opts("watchos", Arch::Arm64_sim); + + // Clang automatically chooses a more specific target based on + // WATCHOS_DEPLOYMENT_TARGET. + // This is required for the simulator target to pick the right + // MACH-O commands, so we do too. + let arch = "arm64"; + let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); + + Target { + llvm_target: llvm_target.into(), + pointer_width: 64, + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+neon,+fp-armv8,+apple-a7".into(), + max_atomic_width: Some(128), + forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, + // Taken from a clang build on Xcode 11.4.1. + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + arm64-apple-watchos5.0-simulator\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 238d3f8bda5..e8460a509e2 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -114,3 +114,12 @@ pub fn ios_sim_llvm_target(arch: &str) -> String { let (major, minor) = ios_deployment_target(); format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor) } + +fn watchos_deployment_target() -> (u32, u32) { + deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0)) +} + +pub fn watchos_sim_llvm_target(arch: &str) -> String { + let (major, minor) = watchos_deployment_target(); + format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor) +} diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index e2d08955c08..ecb6cbd9f8a 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -6,8 +6,10 @@ use Arch::*; #[derive(Copy, Clone)] pub enum Arch { Armv7, + Armv7k, Armv7s, Arm64, + Arm64_32, I386, X86_64, X86_64_macabi, @@ -17,7 +19,7 @@ pub enum Arch { fn target_abi(arch: Arch) -> &'static str { match arch { - Armv7 | Armv7s | Arm64 | I386 | X86_64 => "", + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", X86_64_macabi | Arm64_macabi => "macabi", Arm64_sim => "sim", } @@ -26,8 +28,10 @@ fn target_abi(arch: Arch) -> &'static str { fn target_cpu(arch: Arch) -> &'static str { match arch { Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher + Armv7k => "cortex-a8", Armv7s => "cortex-a9", Arm64 => "apple-a7", + Arm64_32 => "apple-s4", I386 => "yonah", X86_64 => "core2", X86_64_macabi => "core2", @@ -38,7 +42,7 @@ fn target_cpu(arch: Arch) -> &'static str { fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> { match arch { - Armv7 | Armv7s | Arm64 | I386 | X86_64 | Arm64_sim => { + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs new file mode 100644 index 00000000000..7b23fe1c482 --- /dev/null +++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs @@ -0,0 +1,28 @@ +use super::apple_sdk_base::{opts, Arch}; +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + let base = opts("watchos", Arch::Arm64_32); + Target { + llvm_target: "arm64_32-apple-watchos".into(), + pointer_width: 32, + data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+neon,+fp-armv8,+apple-a7".into(), + max_atomic_width: Some(64), + forces_embed_bitcode: true, + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + arm64_32-apple-watchos5.0.0\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs new file mode 100644 index 00000000000..af5d1c2ff45 --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs @@ -0,0 +1,28 @@ +use super::apple_sdk_base::{opts, Arch}; +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + let base = opts("watchos", Arch::Armv7k); + Target { + llvm_target: "armv7k-apple-watchos".into(), + pointer_width: 32, + data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(), + arch: "arm".into(), + options: TargetOptions { + features: "+v7,+vfp4,+neon".into(), + max_atomic_width: Some(64), + forces_embed_bitcode: true, + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + armv7k-apple-watchos3.0.0\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4ede0677ab3..422af667875 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -928,6 +928,11 @@ supported_targets! { ("aarch64-apple-tvos", aarch64_apple_tvos), ("x86_64-apple-tvos", x86_64_apple_tvos), + ("armv7k-apple-watchos", armv7k_apple_watchos), + ("arm64_32-apple-watchos", arm64_32_apple_watchos), + ("x86_64-apple-watchos-sim", x86_64_apple_watchos_sim), + ("aarch64-apple-watchos-sim", aarch64_apple_watchos_sim), + ("armebv7r-none-eabi", armebv7r_none_eabi), ("armebv7r-none-eabihf", armebv7r_none_eabihf), ("armv7r-none-eabi", armv7r_none_eabi), diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs new file mode 100644 index 00000000000..4dff3c2f209 --- /dev/null +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -0,0 +1,35 @@ +use super::apple_sdk_base::{opts, Arch}; +use crate::spec::{StackProbeType, Target, TargetOptions}; + +pub fn target() -> Target { + let base = opts("watchos", Arch::X86_64); + + let arch = "x86_64"; + let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); + + Target { + llvm_target: llvm_target.into(), + pointer_width: 64, + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), + arch: "x86_64".into(), + options: TargetOptions { + max_atomic_width: Some(64), + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + stack_probes: StackProbeType::Call, + forces_embed_bitcode: true, + // Taken from a clang build on Xcode 11.4.1. + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + x86_64-apple-watchos5.0-simulator\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..base + }, + } +} diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 79f2338b7ab..541e56f4618 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -315,8 +315,11 @@ impl Step for Llvm { cfg.define("LLVM_ENABLE_ZLIB", "OFF"); } - // Are we compiling for iOS/tvOS? - if target.contains("apple-ios") || target.contains("apple-tvos") { + // Are we compiling for iOS/tvOS/watchOS? + if target.contains("apple-ios") + || target.contains("apple-tvos") + || target.contains("apple-watchos") + { // These two defines prevent CMake from automatically trying to add a MacOSX sysroot, which leads to a compiler error. cfg.define("CMAKE_OSX_SYSROOT", "/"); cfg.define("CMAKE_OSX_DEPLOYMENT_TARGET", ""); diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8e2d44c1812..e464564c120 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -16,6 +16,7 @@ - [Target Tier Policy](target-tier-policy.md) - [Template for Target-specific Documentation](platform-support/TEMPLATE.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) + - [\*-apple-watchos\*](platform-support/apple-watchos.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 4ac09711b0a..ec93bdd3fd3 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -207,6 +207,7 @@ target | std | host | notes -------|:---:|:----:|------- `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 `aarch64-apple-tvos` | * | | ARM64 tvOS +[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD @@ -220,6 +221,7 @@ target | std | host | notes `aarch64-wrs-vxworks` | ? | | `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS 64-bit with 32-bit pointers `armv4t-unknown-linux-gnueabi` | ? | | `armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD @@ -234,6 +236,7 @@ target | std | host | notes [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat `armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat +[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS `armv7s-apple-ios` | ✓ | | `avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` `bpfeb-unknown-none` | * | | BPF (big endian) @@ -290,6 +293,7 @@ target | std | host | notes [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS +[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md new file mode 100644 index 00000000000..fe4c7c0c88f --- /dev/null +++ b/src/doc/rustc/src/platform-support/apple-watchos.md @@ -0,0 +1,55 @@ +# *-apple-watchos +- arm64_32-apple-watchos +- armv7k-apple-watchos +- aarch64-apple-watchos-sim +- x86_64-apple-watchos-sim + +**Tier: 3** + +Apple WatchOS targets: +- Apple WatchOS on Arm 64_32 +- Apple WatchOS on Arm v7k +- Apple WatchOS Simulator on arm64 +- Apple WatchOS Simulator on x86_64 + +## Target maintainers + +* [@deg4uss3r](https://github.com/deg4uss3r) +* [@vladimir-ea](https://github.com/vladimir-ea) + +## Requirements + +These targets are cross-compiled. +To build these targets Xcode 12 or higher on macOS is required. + +## Building the target + +The targets can be built by enabling them for a `rustc` build, for example: + +```toml +[build] +build-stage = 1 +target = ["aarch64-apple-watchos-sim"] +``` + +## Building Rust programs + +*Note: Building for this target requires the corresponding WatchOS SDK, as provided by Xcode 12+.* + +Rust programs can be built for these targets, if `rustc` has been built with support for them, for example: + +```text +rustc --target aarch64-apple-watchos-sim your-code.rs +``` + +## Testing + +There is no support for running the Rust testsuite on WatchOS or the simulators. + +There is no easy way to run simple programs on WatchOS or the WatchOS simulators. Static library builds can be embedded into WatchOS applications. + +## Cross-compilation toolchains and C code + +This target can be cross-compiled from x86_64 or aarch64 macOS hosts. + +Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK. diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr index a1f7e17d778..24ce2280c8a 100644 --- a/src/test/ui/check-cfg/well-known-values.stderr +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -7,7 +7,7 @@ LL | #[cfg(target_os = "linuz")] | help: did you mean: `"linux"` | = note: `#[warn(unexpected_cfgs)]` on by default - = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, windows, xous + = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous warning: unexpected `cfg` condition value --> $DIR/well-known-values.rs:14:7 diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs index faded7c8024..bc2946e2c13 100644 --- a/src/tools/compiletest/src/raise_fd_limit.rs +++ b/src/tools/compiletest/src/raise_fd_limit.rs @@ -4,7 +4,7 @@ /// on the number of cores available. /// /// This fixes issue #7772. -#[cfg(any(target_os = "macos", target_os = "ios"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] #[allow(non_camel_case_types)] pub unsafe fn raise_fd_limit() { use std::cmp; diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index bed509d77be..215af347f17 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -31,6 +31,7 @@ const OS_TABLE: &[(&str, &str)] = &[ ("redox", "redox"), ("sgx", "sgx"), ("solaris", "solaris"), + ("watchos", "watchos"), ("win32", "windows"), ("windows", "windows"), ("vxworks", "vxworks"),