From 616ead9e24babc00c73fb405823de979d2408004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Rouleau?= Date: Sat, 25 Jul 2026 12:17:00 -0400 Subject: [PATCH] Add tvOS build support (reuse iOS event loop, widen Apple cfg guards) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `aarch64-apple-tvos` and `aarch64-apple-tvos-sim` are stable Rust tier-3 targets installable via plain `rustup target add`, but miniquad currently misses tvOS from every `target_os = "ios"` cfg gate, so a tvOS build fails to compile. This commit widens the Apple-family gates so tvOS reuses the iOS event loop (`native::ios::run`), UIKit link, Objective-C runtime, and Metal storage-mode selection. No new tvOS-specific code is added — the same iOS surface is compiled and dispatched for tvOS. Files touched: - `Cargo.toml` — pull `objc-rs` on tvOS as well. - `src/lib.rs` — `start()` dispatch and `apple_view_ctrl()`. Without the dispatch widen, `start()` returns immediately on tvOS (the enclosing app exits voluntarily on launch). - `src/native.rs` — `pub mod apple`, `pub mod ios`, and the `NativeDisplayData::view_ctrl` field + its initializer. - `src/native/apple/frameworks.rs` — UIKit link (GLKit stays iOS-only since tvOS has no OpenGL ES). - `src/graphics/metal.rs` — `UNIFORM_BUFFER_ALIGN` selection and the three `MTLResourceOptions` branches (matched to the post-#640 shape now on master). Verified with `cargo build` against all five Apple targets: - `aarch64-apple-darwin` — clean - `aarch64-apple-ios` — clean - `aarch64-apple-ios-sim` — clean - `aarch64-apple-tvos` — now builds - `aarch64-apple-tvos-sim` — now builds Not in scope (deliberate): - **Input.** miniquad's iOS event loop reacts to `UITouch` on the `MTKView`. On tvOS, touch events only arrive from the Siri Remote's touch surface; menu / D-pad navigation goes through `UIPress` + the focus engine and is not wired here. An app built with this patch will render but won't accept remote-native input yet. - **App-level scaffolding.** Info.plist scene manifest, `main.m` bridging, asset catalogs, LaunchScreen setup — all app-owned and out of scope for miniquad itself. Sibling PRs of the same shape: - raphamorim/objc-rs#3 — Apple runtime cfg widen (merged) - not-fl3/macroquad#1056 — `load_file` CWD chdir for tvOS --- Cargo.toml | 2 +- src/graphics/metal.rs | 17 ++++++++++++----- src/lib.rs | 4 ++-- src/native.rs | 8 ++++---- src/native/apple/frameworks.rs | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93fb6454..15ff1977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ winapi = { version = "0.3", features = [ libc = "0.2" ndk-sys = "0.2" -[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] +[target.'cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))'.dependencies] objc = { package = "objc-rs", version = "0.2" } [dev-dependencies] diff --git a/src/graphics/metal.rs b/src/graphics/metal.rs index c8837e7d..42f4c999 100644 --- a/src/graphics/metal.rs +++ b/src/graphics/metal.rs @@ -18,10 +18,17 @@ const NUM_INFLIGHT_FRAMES: usize = 3; // uniform-buffer offset alignment. #[cfg(any( target_os = "macos", - all(target_os = "ios", any(target_arch = "x86_64", target_abi = "sim")), + all( + any(target_os = "ios", target_os = "tvos"), + any(target_arch = "x86_64", target_abi = "sim"), + ), ))] const UNIFORM_BUFFER_ALIGN: u64 = 256; -#[cfg(all(target_os = "ios", target_arch = "aarch64", not(target_abi = "sim")))] +#[cfg(all( + any(target_os = "ios", target_os = "tvos"), + target_arch = "aarch64", + not(target_abi = "sim"), +))] const UNIFORM_BUFFER_ALIGN: u64 = 16; impl From for MTLVertexFormat { @@ -357,7 +364,7 @@ impl MetalContext { MTLResourceOptions::CPUCacheModeWriteCombined | MTLResourceOptions::StorageModeManaged }; - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] let options = { MTLResourceOptions::CPUCacheModeWriteCombined }; let uniform_buffers = [ @@ -655,7 +662,7 @@ impl RenderingBackend for MetalContext { MTLResourceOptions::CPUCacheModeWriteCombined | MTLResourceOptions::StorageModeManaged } - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] { MTLResourceOptions::CPUCacheModeWriteCombined } @@ -806,7 +813,7 @@ impl RenderingBackend for MetalContext { setResourceOptions: MTLResourceOptions::StorageModeManaged ]; } - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] { msg_send_![descriptor, setStorageMode: MTLStorageMode::Shared]; msg_send_![ diff --git a/src/lib.rs b/src/lib.rs index b670dddf..719b2c67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -435,7 +435,7 @@ pub mod window { let d = native_display().lock().unwrap(); d.view } - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] pub fn apple_view_ctrl() -> crate::native::apple::frameworks::ObjcId { let d = native_display().lock().unwrap(); d.view_ctrl @@ -510,7 +510,7 @@ where native::macos::run(conf, f); } - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] unsafe { native::ios::run(conf, f); } diff --git a/src/native.rs b/src/native.rs index f3820036..56f5ac7b 100644 --- a/src/native.rs +++ b/src/native.rs @@ -26,7 +26,7 @@ pub(crate) struct NativeDisplayData { #[cfg(target_vendor = "apple")] pub view: crate::native::apple::frameworks::ObjcId, - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] pub view_ctrl: crate::native::apple::frameworks::ObjcId, #[cfg(target_vendor = "apple")] pub gfx_api: crate::conf::AppleGfxApi, @@ -60,7 +60,7 @@ impl NativeDisplayData { gfx_api: crate::conf::AppleGfxApi::OpenGl, #[cfg(target_vendor = "apple")] view: std::ptr::null_mut(), - #[cfg(target_os = "ios")] + #[cfg(any(target_os = "ios", target_os = "tvos"))] view_ctrl: std::ptr::null_mut(), } } @@ -105,13 +105,13 @@ pub use android::*; #[cfg(target_arch = "wasm32")] pub mod wasm; -#[cfg(any(target_os = "macos", target_os = "ios"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))] pub mod apple; #[cfg(target_os = "macos")] pub mod macos; -#[cfg(target_os = "ios")] +#[cfg(any(target_os = "ios", target_os = "tvos"))] pub mod ios; #[cfg(any(target_os = "android", target_os = "linux"))] diff --git a/src/native/apple/frameworks.rs b/src/native/apple/frameworks.rs index b4da3141..b82187d7 100644 --- a/src/native/apple/frameworks.rs +++ b/src/native/apple/frameworks.rs @@ -134,7 +134,7 @@ pub enum GLKViewDrawableStencilFormat { FormatNone = 0, Format8, } -#[cfg(target_os = "ios")] +#[cfg(any(target_os = "ios", target_os = "tvos"))] #[link(name = "UIKit", kind = "framework")] extern "C" { pub static UIKeyboardDidShowNotification: ObjcId;