From bdc3db944cf8da99d80e67e7bb52917512d0a5a7 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 11 Oct 2022 17:22:12 -0700 Subject: [PATCH 01/14] wip: Support Apple tvOS in libstd --- library/std/build.rs | 2 +- library/std/src/os/ios/fs.rs | 2 +- library/std/src/os/mod.rs | 3 ++ library/std/src/os/unix/mod.rs | 3 ++ library/std/src/os/unix/net/stream.rs | 3 ++ library/std/src/os/unix/ucred.rs | 4 +-- library/std/src/os/unix/ucred/tests.rs | 1 + library/std/src/personality/gcc.rs | 2 +- library/std/src/sys/unix/args.rs | 4 +-- library/std/src/sys/unix/env.rs | 11 +++++++ library/std/src/sys/unix/fs.rs | 32 ++++++++++++++++--- .../std/src/sys/unix/locks/pthread_condvar.rs | 2 ++ library/std/src/sys/unix/mod.rs | 2 +- library/std/src/sys/unix/os.rs | 12 +++++-- library/std/src/sys/unix/rand.rs | 3 +- library/std/src/sys/unix/thread.rs | 3 +- .../src/sys/unix/thread_parking/pthread.rs | 3 ++ library/std/src/sys/unix/time.rs | 6 ++-- library/std/src/sys/unix/weak.rs | 4 +-- library/std/src/sys_common/net.rs | 2 +- library/unwind/src/libunwind.rs | 2 +- 21 files changed, 84 insertions(+), 22 deletions(-) diff --git a/library/std/build.rs b/library/std/build.rs index d0b379409369..ddf6e84d8d03 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -18,6 +18,7 @@ fn main() { || target.contains("illumos") || target.contains("apple-darwin") || target.contains("apple-ios") + || target.contains("apple-tvos") || target.contains("apple-watchos") || target.contains("uwp") || target.contains("windows") @@ -48,7 +49,6 @@ fn main() { // - mipsel-sony-psp // - nvptx64-nvidia-cuda // - arch=avr - // - tvos (aarch64-apple-tvos, x86_64-apple-tvos) // - uefi (x86_64-unknown-uefi, i686-unknown-uefi) // - JSON targets // - Any new targets that have not been explicitly added above. diff --git a/library/std/src/os/ios/fs.rs b/library/std/src/os/ios/fs.rs index 6d4d54b7c78c..b319527a541f 100644 --- a/library/std/src/os/ios/fs.rs +++ b/library/std/src/os/ios/fs.rs @@ -6,7 +6,7 @@ use crate::sys_common::{AsInner, AsInnerMut, IntoInner}; use crate::time::SystemTime; #[allow(deprecated)] -use crate::os::ios::raw; +use super::raw; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 5b54cc5f2e49..634c3cc4a15c 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -137,6 +137,9 @@ pub mod redox; pub mod solaris; #[cfg(target_os = "solid_asp3")] pub mod solid; +#[cfg(target_os = "tvos")] +#[path = "ios/mod.rs"] +pub(crate) mod tvos; #[cfg(target_os = "vita")] pub mod vita; #[cfg(target_os = "vxworks")] diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 6fe1111188aa..401ec1e7a013 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -73,6 +73,8 @@ mod platform { pub use crate::os::redox::*; #[cfg(target_os = "solaris")] pub use crate::os::solaris::*; + #[cfg(target_os = "tvos")] + pub use crate::os::tvos::*; #[cfg(target_os = "vita")] pub use crate::os::vita::*; #[cfg(target_os = "vxworks")] @@ -96,6 +98,7 @@ pub mod thread; target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "macos", target_os = "netbsd", diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index bf2a51b5edb8..e20170873bbb 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -11,6 +11,7 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "netbsd", @@ -30,6 +31,7 @@ use crate::time::Duration; target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "netbsd", @@ -238,6 +240,7 @@ impl UnixStream { target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "netbsd", diff --git a/library/std/src/os/unix/ucred.rs b/library/std/src/os/unix/ucred.rs index 95967eac2952..6a0cc2d2c48f 100644 --- a/library/std/src/os/unix/ucred.rs +++ b/library/std/src/os/unix/ucred.rs @@ -36,7 +36,7 @@ pub use self::impl_linux::peer_cred; ))] pub use self::impl_bsd::peer_cred; -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub use self::impl_mac::peer_cred; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -98,7 +98,7 @@ pub mod impl_bsd { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub mod impl_mac { use super::UCred; use crate::os::unix::io::AsRawFd; diff --git a/library/std/src/os/unix/ucred/tests.rs b/library/std/src/os/unix/ucred/tests.rs index e63a2fc248eb..7c3a646ed939 100644 --- a/library/std/src/os/unix/ucred/tests.rs +++ b/library/std/src/os/unix/ucred/tests.rs @@ -8,6 +8,7 @@ use libc::{getegid, geteuid, getpid}; target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "openbsd" diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs index 82edb11cbd14..6552d96ca699 100644 --- a/library/std/src/personality/gcc.rs +++ b/library/std/src/personality/gcc.rs @@ -85,7 +85,7 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c cfg_if::cfg_if! { - if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "watchos"), not(target_os = "netbsd")))] { + if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "netbsd")))] { // ARM EHABI personality routine. // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf // diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index 0efe2570d677..f8fa81e6ef18 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -168,7 +168,7 @@ mod imp { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] mod imp { use super::Args; use crate::ffi::CStr; @@ -209,7 +209,7 @@ mod imp { // for i in (0..[args count]) // res.push([args objectAtIndex:i]) // res - #[cfg(any(target_os = "ios", target_os = "watchos"))] + #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn args() -> Args { use crate::ffi::OsString; use crate::mem; diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs index 8c3ef88d8f8e..929e9dae7386 100644 --- a/library/std/src/sys/unix/env.rs +++ b/library/std/src/sys/unix/env.rs @@ -31,6 +31,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "tvos")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "tvos"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".dylib"; + pub const DLL_EXTENSION: &str = "dylib"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} + #[cfg(target_os = "watchos")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index d2fb6238387a..f05ece17c371 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -32,6 +32,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; all(target_os = "linux", target_env = "gnu"), target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", ))] use crate::sys::weak::syscall; @@ -43,6 +44,7 @@ use libc::{c_int, mode_t}; #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "solaris", all(target_os = "linux", target_env = "gnu") @@ -519,6 +521,7 @@ impl FileAttr { target_os = "openbsd", target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", ))] pub fn created(&self) -> io::Result { @@ -530,6 +533,7 @@ impl FileAttr { target_os = "openbsd", target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "vita", )))] @@ -895,6 +899,7 @@ impl DirEntry { #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "linux", target_os = "emscripten", @@ -928,6 +933,7 @@ impl DirEntry { #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "netbsd", target_os = "openbsd", @@ -946,6 +952,7 @@ impl DirEntry { #[cfg(not(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "netbsd", target_os = "openbsd", @@ -1107,11 +1114,21 @@ impl File { cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?; return Ok(()); - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + ))] unsafe fn os_fsync(fd: c_int) -> c_int { libc::fcntl(fd, libc::F_FULLFSYNC) } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))] + #[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + )))] unsafe fn os_fsync(fd: c_int) -> c_int { libc::fsync(fd) } @@ -1121,7 +1138,12 @@ impl File { cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?; return Ok(()); - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + ))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fcntl(fd, libc::F_FULLFSYNC) } @@ -1140,6 +1162,7 @@ impl File { target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -1709,6 +1732,7 @@ fn open_to_and_set_permissions( target_os = "android", target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", )))] pub fn copy(from: &Path, to: &Path) -> io::Result { @@ -1736,7 +1760,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::sync::atomic::{AtomicBool, Ordering}; diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 192fa216dfaf..330b4affa896 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -124,6 +124,7 @@ impl Condvar { #[cfg(not(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "android", target_os = "espidf", @@ -158,6 +159,7 @@ impl Condvar { #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "android", target_os = "espidf", diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 24566d96bcd6..0247b56935fc 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -387,7 +387,7 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "macos")] { #[link(name = "System")] extern "C" {} - } else if #[cfg(any(target_os = "ios", target_os = "watchos"))] { + } else if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos"))] { #[link(name = "System")] #[link(name = "objc")] #[link(name = "Security", kind = "framework")] diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 8edfd3313044..a68c14758ff7 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -63,7 +63,13 @@ extern "C" { #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")] #[cfg_attr( - any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "watchos"), + any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "freebsd", + target_os = "watchos" + ), link_name = "__error" )] #[cfg_attr(target_os = "haiku", link_name = "_errnop")] @@ -375,7 +381,7 @@ pub fn current_exe() -> io::Result { Ok(PathBuf::from(OsString::from_vec(e))) } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn current_exe() -> io::Result { unsafe { let mut sz: u32 = 0; @@ -609,6 +615,7 @@ pub fn home_dir() -> Option { #[cfg(any( target_os = "android", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "emscripten", target_os = "redox", @@ -623,6 +630,7 @@ pub fn home_dir() -> Option { #[cfg(not(any( target_os = "android", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "emscripten", target_os = "redox", diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index d8b63546b9ed..d471be33ed55 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -14,6 +14,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { unix, not(target_os = "macos"), not(target_os = "ios"), + not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "openbsd"), not(target_os = "freebsd"), @@ -198,7 +199,7 @@ mod imp { // once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is // only used on iOS where direct access to `/dev/urandom` is blocked by the // sandbox. -#[cfg(any(target_os = "ios", target_os = "watchos"))] +#[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos"))] mod imp { use crate::io; use crate::ptr; diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 010015667f7a..916390f3a669 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -150,7 +150,7 @@ impl Thread { } } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn set_name(name: &CStr) { unsafe { let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name); @@ -299,6 +299,7 @@ pub fn available_parallelism() -> io::Result { target_os = "emscripten", target_os = "fuchsia", target_os = "ios", + target_os = "tvos", target_os = "linux", target_os = "macos", target_os = "solaris", diff --git a/library/std/src/sys/unix/thread_parking/pthread.rs b/library/std/src/sys/unix/thread_parking/pthread.rs index 8bf4bae7a3f7..ae805d843994 100644 --- a/library/std/src/sys/unix/thread_parking/pthread.rs +++ b/library/std/src/sys/unix/thread_parking/pthread.rs @@ -46,6 +46,7 @@ unsafe fn wait_timeout( #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "espidf", target_os = "horizon", @@ -73,6 +74,7 @@ unsafe fn wait_timeout( #[cfg(not(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "espidf", target_os = "horizon", @@ -120,6 +122,7 @@ impl Parker { if #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "l4re", target_os = "android", diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index a9fbc7ab108a..17b4130c2024 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -219,7 +219,8 @@ impl From<__timespec64> for Timespec { #[cfg(any( all(target_os = "macos", any(not(target_arch = "aarch64"))), target_os = "ios", - target_os = "watchos" + target_os = "watchos", + target_os = "tvos" ))] mod inner { use crate::sync::atomic::{AtomicU64, Ordering}; @@ -339,7 +340,8 @@ mod inner { #[cfg(not(any( all(target_os = "macos", any(not(target_arch = "aarch64"))), target_os = "ios", - target_os = "watchos" + target_os = "watchos", + target_os = "tvos" )))] mod inner { use crate::fmt; diff --git a/library/std/src/sys/unix/weak.rs b/library/std/src/sys/unix/weak.rs index 62ffee70becc..61088ff16edd 100644 --- a/library/std/src/sys/unix/weak.rs +++ b/library/std/src/sys/unix/weak.rs @@ -28,7 +28,7 @@ use crate::ptr; use crate::sync::atomic::{self, AtomicPtr, Ordering}; // We can use true weak linkage on ELF targets. -#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos")))] pub(crate) macro weak { (fn $name:ident($($t:ty),*) -> $ret:ty) => ( let ref $name: ExternWeak $ret> = { @@ -43,7 +43,7 @@ pub(crate) macro weak { } // On non-ELF targets, use the dlsym approximation of weak linkage. -#[cfg(any(target_os = "macos", target_os = "ios"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))] pub(crate) use self::dlsym as weak; pub(crate) struct ExternWeak { diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 652c695fc57b..2976a9f578ed 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -18,7 +18,7 @@ use crate::ffi::{c_int, c_void}; cfg_if::cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", target_os = "macos", target_os = "watchos", + target_os = "ios", target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "openbsd", target_os = "netbsd", target_os = "illumos", target_os = "solaris", target_os = "haiku", target_os = "l4re", target_os = "nto"))] { use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index f6a68073b2f7..ec24e137572d 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -117,7 +117,7 @@ extern "C" { } cfg_if::cfg_if! { -if #[cfg(any(target_os = "ios", target_os = "watchos", target_os = "netbsd", not(target_arch = "arm")))] { +if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "netbsd", not(target_arch = "arm")))] { // Not ARM EHABI #[repr(C)] #[derive(Copy, Clone, PartialEq)] From f978d7ea427b1e9e8ea23eb0bd8cd03b21092720 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2023 20:02:42 -0700 Subject: [PATCH 02/14] Finish up preliminary tvos support in libstd --- library/core/src/ffi/mod.rs | 23 +++++++++++++------ library/std/src/sys/unix/fd.rs | 6 +++++ .../std/src/sys/unix/locks/pthread_condvar.rs | 1 + library/std/src/sys/unix/mod.rs | 1 + library/std/src/sys/unix/thread.rs | 8 ++++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 86ea154a8868..7437722fd062 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -238,7 +238,7 @@ impl fmt::Debug for c_void { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), + all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), target_family = "wasm", target_arch = "asmjs", target_os = "uefi", @@ -267,7 +267,7 @@ pub struct VaListImpl<'f> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), + all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), target_family = "wasm", target_arch = "asmjs", target_os = "uefi", @@ -292,7 +292,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> { /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf #[cfg(all( target_arch = "aarch64", - not(any(target_os = "macos", target_os = "ios")), + not(any(target_os = "macos", target_os = "ios", target_os = "tvos")), not(target_os = "uefi"), not(windows), ))] @@ -389,7 +389,10 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), + all( + target_arch = "aarch64", + any(target_os = "macos", target_os = "ios", target_os = "tvos") + ), target_family = "wasm", target_arch = "asmjs", target_os = "uefi", @@ -404,7 +407,10 @@ pub struct VaList<'a, 'f: 'a> { target_arch = "s390x", target_arch = "x86_64" ), - any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), + any( + not(target_arch = "aarch64"), + not(any(target_os = "macos", target_os = "ios", target_os = "tvos")) + ), not(target_family = "wasm"), not(target_arch = "asmjs"), not(target_os = "uefi"), @@ -422,7 +428,7 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), + all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), target_family = "wasm", target_arch = "asmjs", target_os = "uefi", @@ -449,7 +455,10 @@ impl<'f> VaListImpl<'f> { target_arch = "s390x", target_arch = "x86_64" ), - any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))), + any( + not(target_arch = "aarch64"), + not(any(target_os = "macos", target_os = "ios", target_os = "tvos")) + ), not(target_family = "wasm"), not(target_arch = "asmjs"), not(target_os = "uefi"), diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 69c93c920036..85e020ae4132 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -44,6 +44,7 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize; target_os = "dragonfly", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "macos", target_os = "netbsd", target_os = "openbsd", @@ -69,6 +70,7 @@ const fn max_iov() -> usize { target_os = "emscripten", target_os = "freebsd", target_os = "ios", + target_os = "tvos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -181,6 +183,7 @@ impl FileDesc { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "tvos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -222,6 +225,7 @@ impl FileDesc { #[cfg(any( all(target_os = "android", target_pointer_width = "32"), target_os = "ios", + target_os = "tvos", target_os = "macos", ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { @@ -320,6 +324,7 @@ impl FileDesc { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "tvos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -361,6 +366,7 @@ impl FileDesc { #[cfg(any( all(target_os = "android", target_pointer_width = "32"), target_os = "ios", + target_os = "tvos", target_os = "macos", ))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 330b4affa896..2dc1b0c601e7 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -32,6 +32,7 @@ impl LazyInit for AllocatedCondvar { if #[cfg(any( target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "l4re", target_os = "android", diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 0247b56935fc..1b72e21a8328 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -87,6 +87,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { // The poll on Darwin doesn't set POLLNVAL for closed fds. target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos", target_os = "redox", target_os = "l4re", diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 916390f3a669..893f8b8df3f5 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -283,7 +283,13 @@ impl Drop for Thread { } } -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", +))] fn truncate_cstr(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] { let mut result = [0; MAX_WITH_NUL]; for (src, dst) in cstr.to_bytes().iter().zip(&mut result[..MAX_WITH_NUL - 1]) { From 3785a17dd93271543cf532776d209648e1c38cb3 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2023 20:03:21 -0700 Subject: [PATCH 03/14] =?UTF-8?q?Fix=20busted=20data=5Flayout=C2=A0(mismat?= =?UTF-8?q?ch=20vs=20LLVM)=20in=20x86=5F64=20tvOS=20simulator=20target?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_target/src/spec/x86_64_apple_tvos.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 76de7d20c4c6..ae0107efef62 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-apple-tvos".into(), pointer_width: 64, - data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".into(), + 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: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(128), From abb191168222e57c2adb3874b7955b37d3021abb Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2023 21:24:15 -0700 Subject: [PATCH 04/14] Fix the tvOS targets to use the right LLVM target and respect the deployment target environment variables --- .../rustc_target/src/spec/aarch64_apple_tvos.rs | 4 ++-- compiler/rustc_target/src/spec/apple_base.rs | 16 +++++++++++++++- .../rustc_target/src/spec/x86_64_apple_tvos.rs | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index bb7c39ff26bd..f7cdfa71c4b6 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -1,10 +1,10 @@ -use super::apple_base::{opts, Arch}; +use super::apple_base::{opts, tvos_llvm_target, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; Target { - llvm_target: "arm64-apple-tvos".into(), + llvm_target: tvos_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), arch: arch.target_arch(), diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index ff2246318288..7bdd867e51b3 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -240,7 +240,10 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which // may occur when we're linking a custom build script while targeting iOS for example. if let Ok(sdkroot) = env::var("SDKROOT") { - if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") + if sdkroot.contains("iPhoneOS.platform") + || sdkroot.contains("iPhoneSimulator.platform") + || sdkroot.contains("AppleTVOS.platform") + || sdkroot.contains("AppleTVSimulator.platform") { env_remove.push("SDKROOT".into()) } @@ -249,6 +252,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld", // although this is apparently ignored when using the linker at "/usr/bin/ld". env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into()); + env_remove.push("TVOS_DEPLOYMENT_TARGET".into()); env_remove.into() } else { // Otherwise if cross-compiling for a different OS/SDK, remove any part @@ -279,6 +283,16 @@ pub fn ios_llvm_target(arch: Arch) -> String { format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor) } +pub fn tvos_sim_llvm_target(arch: Arch) -> String { + let (major, minor) = tvos_deployment_target(); + format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor) +} + +pub fn tvos_llvm_target(arch: Arch) -> String { + let (major, minor) = tvos_deployment_target(); + format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor) +} + fn ios_lld_platform_version() -> String { let (major, minor) = ios_deployment_target(); format!("{major}.{minor}") 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 ae0107efef62..2ec4d9569e3e 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -1,10 +1,10 @@ -use super::apple_base::{opts, Arch}; +use super::apple_base::{opts, tvos_sim_llvm_target, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; Target { - llvm_target: "x86_64-apple-tvos".into(), + llvm_target: tvos_sim_llvm_target(arch).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(), From df9640211d5ba4d2fbafd8cd42c3fa61076185fc Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2023 21:24:49 -0700 Subject: [PATCH 05/14] Add a tvOS entry to the platform-support documentation --- src/doc/rustc/src/platform-support.md | 4 +- .../rustc/src/platform-support/apple-tvos.md | 70 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/apple-tvos.md diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index f69dcd5983d3..62f628f82293 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -214,7 +214,7 @@ host tools. target | std | host | notes -------|:---:|:----:|------- `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 -`aarch64-apple-tvos` | * | | ARM64 tvOS +[`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ? | | 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-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon @@ -316,7 +316,7 @@ target | std | host | notes `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL [`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-tvos`](platform-support/apple-tvos.md) | ? | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS | [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md new file mode 100644 index 000000000000..95256178cfdf --- /dev/null +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -0,0 +1,70 @@ +# `*-apple-tvos` +- aarch64-apple-tvos +- x86_64-apple-tvos + +**Tier: 3** + +Apple WatchOS targets: +- Apple tvOS on aarch64 +- Apple tvOS Simulator on x86_64 + +## Target maintainers + +* [@thomcc](https://github.com/thomcc) + +## Requirements + +These targets are cross-compiled. You will need appropriate versions of XCode +and the SDKs for tvOS (`AppleTVOS.sdk`) and/or the tvOS Simulator +(`AppleTVSimulator.sdk`) to build a toolchain and target these platforms. + +The targets support the full standard library including the allocator to the +best of my knowledge, however they are very new, not yet well-tested tested, and +it is possible that there are various bugs. + +In theory we support back to tvOS version 7.0, although the actual minimum +version you can target may be newer than this, for example due to the versions +of XCode and your SDKs. + +As with the other Apple targets, `rustc` respects the common environment +variables used by XCode to configure this, in this case +`TVOS_DEPLOYMENT_TARGET`. + +## 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-tvos", "x86_64-apple-tvos"] +``` + +It's possible that cargo under `-Zbuild-std` may also be used to target them. + +## Building Rust programs + +*Note: Building for this target requires the corresponding TVOS SDK, as provided by Xcode.* + +Rust programs can be built for these targets + +```text +$ rustc --target aarch64-apple-tvos your-code.rs +... +$ rustc --target x86_64-apple-tvos your-code.rs +``` + +## Testing + +There is no support for running the Rust or standard library testsuite on tvOS +or the simulators at the moment. Testing has mostly been done manually with +builds of static libraries called from XCode or a simulator. + +It hopefully will be possible to improve this in the future. + +## 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. From b18ff59690cbd9c5759712c312e0ee8cae04b5ed Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2023 22:15:49 -0700 Subject: [PATCH 06/14] Fix rustc_target::spec::apple::tests --- compiler/rustc_target/src/spec/apple/tests.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/apple/tests.rs b/compiler/rustc_target/src/spec/apple/tests.rs index 3c90a5e7e93e..3b23ddadcc47 100644 --- a/compiler/rustc_target/src/spec/apple/tests.rs +++ b/compiler/rustc_target/src/spec/apple/tests.rs @@ -30,6 +30,9 @@ fn macos_link_environment_unmodified() { for target in all_macos_targets { // macOS targets should only remove information for cross-compiling, but never // for the host. - assert_eq!(target.link_env_remove, crate::spec::cvs!["IPHONEOS_DEPLOYMENT_TARGET"]); + assert_eq!( + target.link_env_remove, + crate::spec::cvs!["IPHONEOS_DEPLOYMENT_TARGET", "TVOS_DEPLOYMENT_TARGET"], + ); } } From 6e62961474878c25464c748c41d951d1d4cff1a9 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 15 Mar 2023 20:21:20 -0700 Subject: [PATCH 07/14] Fix missing link in SUMMARY.md --- src/doc/rustc/src/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 2b0431a159b1..1e17a90a8428 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-tvos](platform-support/apple-tvos.md) - [\*-apple-watchos\*](platform-support/apple-watchos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) From a3f5566858aac8a41c3600d895626d0d2b0eeacd Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 08:51:07 -0700 Subject: [PATCH 08/14] Apply suggestions from code review Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- src/doc/rustc/src/platform-support/apple-tvos.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index 95256178cfdf..2446c5fc10fc 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -4,7 +4,7 @@ **Tier: 3** -Apple WatchOS targets: +Apple tvOS targets: - Apple tvOS on aarch64 - Apple tvOS Simulator on x86_64 @@ -14,25 +14,25 @@ Apple WatchOS targets: ## Requirements -These targets are cross-compiled. You will need appropriate versions of XCode +These targets are cross-compiled. You will need appropriate versions of Xcode and the SDKs for tvOS (`AppleTVOS.sdk`) and/or the tvOS Simulator (`AppleTVSimulator.sdk`) to build a toolchain and target these platforms. The targets support the full standard library including the allocator to the -best of my knowledge, however they are very new, not yet well-tested tested, and +best of my knowledge, however they are very new, not yet well-tested, and it is possible that there are various bugs. In theory we support back to tvOS version 7.0, although the actual minimum version you can target may be newer than this, for example due to the versions -of XCode and your SDKs. +of Xcode and your SDKs. As with the other Apple targets, `rustc` respects the common environment -variables used by XCode to configure this, in this case +variables used by Xcode to configure this, in this case `TVOS_DEPLOYMENT_TARGET`. ## Building the target -The targets can be built by enabling them for a `rustc` build, for example: +The targets can be built by enabling them for a `rustc` build in `config.toml`, by adding, for example: ```toml [build] @@ -58,7 +58,7 @@ $ rustc --target x86_64-apple-tvos your-code.rs There is no support for running the Rust or standard library testsuite on tvOS or the simulators at the moment. Testing has mostly been done manually with -builds of static libraries called from XCode or a simulator. +builds of static libraries called from Xcode or a simulator. It hopefully will be possible to improve this in the future. From b80e0b7f53461a827fa007910e86560eec3a1180 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 08:57:27 -0700 Subject: [PATCH 09/14] Reorder `tvos_*` functions in apple_base.rs to avoid breaking sorted order --- compiler/rustc_target/src/spec/apple_base.rs | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 7bdd867e51b3..8a8d1ab95e81 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -244,6 +244,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> || sdkroot.contains("iPhoneSimulator.platform") || sdkroot.contains("AppleTVOS.platform") || sdkroot.contains("AppleTVSimulator.platform") + || sdkroot.contains("WatchOS.platform") + || sdkroot.contains("WatchSimulator.platform") { env_remove.push("SDKROOT".into()) } @@ -283,16 +285,6 @@ pub fn ios_llvm_target(arch: Arch) -> String { format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor) } -pub fn tvos_sim_llvm_target(arch: Arch) -> String { - let (major, minor) = tvos_deployment_target(); - format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor) -} - -pub fn tvos_llvm_target(arch: Arch) -> String { - let (major, minor) = tvos_deployment_target(); - format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor) -} - fn ios_lld_platform_version() -> String { let (major, minor) = ios_deployment_target(); format!("{major}.{minor}") @@ -313,6 +305,16 @@ fn tvos_lld_platform_version() -> String { format!("{major}.{minor}") } +pub fn tvos_llvm_target(arch: Arch) -> String { + let (major, minor) = tvos_deployment_target(); + format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor) +} + +pub fn tvos_sim_llvm_target(arch: Arch) -> String { + let (major, minor) = tvos_deployment_target(); + format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor) +} + fn watchos_deployment_target() -> (u32, u32) { // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. from_set_deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0)) From 49da0acb7153f93a09f3f28461d4e4f23452df21 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 09:46:18 -0700 Subject: [PATCH 10/14] Avoid fork/exec spawning on tvOS/watchOS, as those functions are marked as prohibited --- .../std/src/sys/unix/process/process_unix.rs | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 22d9d6141f40..98564c11673c 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -15,6 +15,8 @@ use crate::sys::weak::raw_syscall; #[cfg(any( target_os = "macos", + target_os = "watchos", + target_os = "tvos", target_os = "freebsd", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), @@ -28,7 +30,12 @@ use libc::RTP_ID as pid_t; #[cfg(not(target_os = "vxworks"))] use libc::{c_int, pid_t}; -#[cfg(not(any(target_os = "vxworks", target_os = "l4re")))] +#[cfg(not(any( + target_os = "vxworks", + target_os = "l4re", + target_os = "tvos", + target_os = "watchos", +)))] use libc::{gid_t, uid_t}; cfg_if::cfg_if! { @@ -84,7 +91,6 @@ impl Command { if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? { return Ok((ret, ours)); } - let (input, output) = sys::pipe::anon_pipe()?; // Whatever happens after the fork is almost for sure going to touch or @@ -166,9 +172,32 @@ impl Command { crate::sys_common::process::wait_with_output(proc, pipes) } + // WatchOS and TVOS can theoretically spawn processes using `posix_spawn*` + // (although it just fails with a runtime error AFAICT, so we don't yet + // support it in `std`), but forbid use of `fork`/`exec*`. It's unclear the + // extent to which these is restricted, but the headers say + // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, so we go out of our way to + // avoid containing any calls to them at all, to avoid linking against their + // symbols on those targets. + #[cfg(any(target_os = "tvos", target_os = "watchos"))] + const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!( + ErrorKind::Unsupported, + "`fork`+`exec`-based process spawning is not supported on this target", + ); + + #[cfg(any(target_os = "tvos", target_os = "watchos"))] + unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { + return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC); + } + // Attempts to fork the process. If successful, returns Ok((0, -1)) // in the child, and Ok((child_pid, -1)) in the parent. - #[cfg(not(any(target_os = "linux", all(target_os = "nto", target_env = "nto71"))))] + #[cfg(not(any( + target_os = "linux", + target_os = "watchos", + target_os = "tvos", + all(target_os = "nto", target_env = "nto71"), + )))] unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { cvt(libc::fork()).map(|res| (res, -1)) } @@ -339,6 +368,7 @@ impl Command { // allocation). Instead we just close it manually. This will never // have the drop glue anyway because this code never returns (the // child will either exec() or invoke libc::exit) + #[cfg(not(any(target_os = "tvos", target_os = "watchos")))] unsafe fn do_exec( &mut self, stdio: ChildPipes, @@ -445,8 +475,19 @@ impl Command { Err(io::Error::last_os_error()) } + #[cfg(any(target_os = "tvos", target_os = "watchos"))] + unsafe fn do_exec( + &mut self, + _stdio: ChildPipes, + _maybe_envp: Option<&CStringArray>, + ) -> Result { + return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC); + } + #[cfg(not(any( target_os = "macos", + target_os = "tvos", + target_os = "watchos", target_os = "freebsd", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), @@ -464,6 +505,9 @@ impl Command { // directly. #[cfg(any( target_os = "macos", + // FIXME: `target_os = "ios"`? + target_os = "tvos", + target_os = "watchos", target_os = "freebsd", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), @@ -550,7 +594,7 @@ impl Command { } let addchdir = match self.get_cwd() { Some(cwd) => { - if cfg!(target_os = "macos") { + if cfg!(any(target_os = "macos", target_os = "tvos", target_os = "watchos")) { // There is a bug in macOS where a relative executable // path like "../myprogram" will cause `posix_spawn` to // successfully launch the program, but erroneously return From 37854aab76209788b0f402aa0ff0acb2a8d3acb7 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 09:46:43 -0700 Subject: [PATCH 11/14] Update tvOS support elsewhere in the stdlib --- library/std/src/fs/tests.rs | 28 +++++++++++++++++++++++--- library/std/src/os/unix/ucred/tests.rs | 8 +++++++- library/std/src/sys/unix/fs.rs | 6 +++--- library/std/src/thread/tests.rs | 1 + 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index e2480bcbbc72..9ff01b9c35d1 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1640,6 +1640,10 @@ fn test_file_times() { use crate::os::ios::fs::FileTimesExt; #[cfg(target_os = "macos")] use crate::os::macos::fs::FileTimesExt; + #[cfg(target_os = "tvos")] + use crate::os::tvos::fs::FileTimesExt; + #[cfg(target_os = "tvos")] + use crate::os::tvos::fs::FileTimesExt; #[cfg(target_os = "watchos")] use crate::os::watchos::fs::FileTimesExt; #[cfg(windows)] @@ -1651,9 +1655,21 @@ fn test_file_times() { let accessed = SystemTime::UNIX_EPOCH + Duration::from_secs(12345); let modified = SystemTime::UNIX_EPOCH + Duration::from_secs(54321); times = times.set_accessed(accessed).set_modified(modified); - #[cfg(any(windows, target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any( + windows, + target_os = "macos", + target_os = "ios", + target_os = "watchos", + target_os = "tvos", + ))] let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123); - #[cfg(any(windows, target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any( + windows, + target_os = "macos", + target_os = "ios", + target_os = "watchos", + target_os = "tvos", + ))] { times = times.set_created(created); } @@ -1678,7 +1694,13 @@ fn test_file_times() { let metadata = file.metadata().unwrap(); assert_eq!(metadata.accessed().unwrap(), accessed); assert_eq!(metadata.modified().unwrap(), modified); - #[cfg(any(windows, target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any( + windows, + target_os = "macos", + target_os = "ios", + target_os = "watchos", + target_os = "tvos", + ))] { assert_eq!(metadata.created().unwrap(), created); } diff --git a/library/std/src/os/unix/ucred/tests.rs b/library/std/src/os/unix/ucred/tests.rs index 7c3a646ed939..dd99ecdd819a 100644 --- a/library/std/src/os/unix/ucred/tests.rs +++ b/library/std/src/os/unix/ucred/tests.rs @@ -27,7 +27,13 @@ fn test_socket_pair() { } #[test] -#[cfg(any(target_os = "linux", target_os = "ios", target_os = "macos", target_os = "watchos"))] +#[cfg(any( + target_os = "linux", + target_os = "ios", + target_os = "macos", + target_os = "watchos", + target_os = "tvos", +))] fn test_socket_pair_pids(arg: Type) -> RetType { // Create two connected sockets and get their peer credentials. let (sock_a, sock_b) = UnixStream::pair().unwrap(); diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index f05ece17c371..9cf5cfcc8d55 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -362,7 +362,7 @@ pub struct FilePermissions { pub struct FileTimes { accessed: Option, modified: Option, - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "tvos"))] created: Option, } @@ -615,7 +615,7 @@ impl FileTimes { self.modified = Some(t); } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "tvos"))] pub fn set_created(&mut self, t: SystemTime) { self.created = Some(t); } @@ -1272,7 +1272,7 @@ impl File { io::ErrorKind::Unsupported, "setting file times not supported", )) - } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] { + } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] { let mut buf = [mem::MaybeUninit::::uninit(); 3]; let mut num_times = 0; let mut attrlist: libc::attrlist = unsafe { mem::zeroed() }; diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index b65e2572cc5e..5d6b9e94ee91 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -42,6 +42,7 @@ fn test_named_thread() { all(target_os = "linux", target_env = "gnu"), target_os = "macos", target_os = "ios", + target_os = "tvos", target_os = "watchos" ))] #[test] From a7ecc71a48be74882d2b159876911e6b9edb945d Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 10:08:10 -0700 Subject: [PATCH 12/14] Note the incomplete Command support in the apple-tvos.md document --- .../rustc/src/platform-support/apple-tvos.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index 2446c5fc10fc..5a22402324c3 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -18,9 +18,9 @@ These targets are cross-compiled. You will need appropriate versions of Xcode and the SDKs for tvOS (`AppleTVOS.sdk`) and/or the tvOS Simulator (`AppleTVSimulator.sdk`) to build a toolchain and target these platforms. -The targets support the full standard library including the allocator to the -best of my knowledge, however they are very new, not yet well-tested, and -it is possible that there are various bugs. +The targets support most (see below) of the standard library including the +allocator to the best of my knowledge, however they are very new, not yet +well-tested, and it is possible that there are various bugs. In theory we support back to tvOS version 7.0, although the actual minimum version you can target may be newer than this, for example due to the versions @@ -30,6 +30,19 @@ As with the other Apple targets, `rustc` respects the common environment variables used by Xcode to configure this, in this case `TVOS_DEPLOYMENT_TARGET`. +#### Incompletely supported library functionality + +As mentioned, "most" of the standard library is supported, which means that some portions +are known to be unsupported. The following APIs are currently known to have +missing or incomplete support: + +- `std::process::Command`'s API will return an error if it is configured in a + manner which cannot be performed using `posix_spawn` -- this is because the + more flexible `fork`/`exec`-based approach is prohibited on these platforms in + favor of `posix_spawn{,p}`. A concrete set of cases where this will occur is + difficult to enumerate (and would quickly become stale), but in some cases it + may be worked around by tweaking the manner in which `Command` is invoked. + ## Building the target The targets can be built by enabling them for a `rustc` build in `config.toml`, by adding, for example: From 5ef4d1fb2e39f835307c40d4cde45409e22d5750 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Jun 2023 10:13:16 -0700 Subject: [PATCH 13/14] Actually save all the files --- library/std/src/sys/unix/process/process_unix.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 98564c11673c..129e7643661f 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -172,13 +172,12 @@ impl Command { crate::sys_common::process::wait_with_output(proc, pipes) } - // WatchOS and TVOS can theoretically spawn processes using `posix_spawn*` - // (although it just fails with a runtime error AFAICT, so we don't yet - // support it in `std`), but forbid use of `fork`/`exec*`. It's unclear the - // extent to which these is restricted, but the headers say - // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, so we go out of our way to - // avoid containing any calls to them at all, to avoid linking against their - // symbols on those targets. + // WatchOS and TVOS headers mark the `fork`/`exec*` functions with + // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the + // `posix_spawn*` functions should be used instead. It isn't entirely clear + // what `PROHIBITED` means here (e.g. if calls to these functions are + // allowed to exist in dead code), but it sounds bad, so we go out of our + // way to avoid that all-together. #[cfg(any(target_os = "tvos", target_os = "watchos"))] const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!( ErrorKind::Unsupported, From af0662f18cf4334a267397a71c3fdb3f4297f35f Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 21 Jun 2023 15:01:12 -0700 Subject: [PATCH 14/14] Note that posix_spawnp probably still does not work the way people may want --- src/doc/rustc/src/platform-support/apple-tvos.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index 5a22402324c3..d87fd1959b49 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -39,9 +39,11 @@ missing or incomplete support: - `std::process::Command`'s API will return an error if it is configured in a manner which cannot be performed using `posix_spawn` -- this is because the more flexible `fork`/`exec`-based approach is prohibited on these platforms in - favor of `posix_spawn{,p}`. A concrete set of cases where this will occur is - difficult to enumerate (and would quickly become stale), but in some cases it - may be worked around by tweaking the manner in which `Command` is invoked. + favor of `posix_spawn{,p}` (which still probably will get you rejected from + app stores, so is likely sideloading-only). A concrete set of cases where this + will occur is difficult to enumerate (and would quickly become stale), but in + some cases it may be worked around by tweaking the manner in which `Command` + is invoked. ## Building the target