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 d0b379409369f..ddf6e84d8d035 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 6d4d54b7c78c5..b319527a541f5 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 5b54cc5f2e491..634c3cc4a15c4 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 6fe1111188aa8..401ec1e7a0130 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 bf2a51b5edb88..e20170873bbbd 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 95967eac29520..6a0cc2d2c48ff 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 e63a2fc248eb0..7c3a646ed939e 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 82edb11cbd146..6552d96ca6994 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 0efe2570d6775..f8fa81e6ef183 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 8c3ef88d8f8e0..929e9dae73868 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 d2fb6238387a1..f05ece17c3718 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 192fa216dfaf5..330b4affa896c 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 24566d96bcd61..0247b56935fc9 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 8edfd33130442..a68c14758ff79 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 d8b63546b9ed1..d471be33ed559 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 010015667f7a2..916390f3a6692 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 8bf4bae7a3f77..ae805d8439945 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 a9fbc7ab108a4..17b4130c20241 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 62ffee70becc3..61088ff16eddf 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 652c695fc57b0..2976a9f578ede 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 f6a68073b2f7e..ec24e137572d4 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 86ea154a8868e..7437722fd0625 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 69c93c9200367..85e020ae41328 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 330b4affa896c..2dc1b0c601e78 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 0247b56935fc9..1b72e21a83285 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 916390f3a6692..893f8b8df3f54 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 76de7d20c4c6f..ae0107efef62a 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 bb7c39ff26bdf..f7cdfa71c4b65 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 ff2246318288e..7bdd867e51b35 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 ae0107efef62a..2ec4d9569e3ea 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 f69dcd5983d33..62f628f822933 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 0000000000000..95256178cfdfd --- /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 3c90a5e7e93ea..3b23ddadcc47c 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 2b0431a159b1b..1e17a90a8428c 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 95256178cfdfd..2446c5fc10fce 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 7bdd867e51b35..8a8d1ab95e81e 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 22d9d6141f404..98564c11673c5 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 e2480bcbbc729..9ff01b9c35d18 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 7c3a646ed939e..dd99ecdd819a7 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 f05ece17c3718..9cf5cfcc8d552 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 b65e2572cc5e4..5d6b9e94ee91b 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 2446c5fc10fce..5a22402324c36 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 98564c11673c5..129e7643661f0 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 5a22402324c36..d87fd1959b49c 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