From bfdf5329656cda035edb83f5af75471317f8eaba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 13 Oct 2026 01:15:41 +0200 Subject: [PATCH] CI: Build the tvOS app and the iOS and tvOS libretro cores Adds b-tvos.sh and b.sh --tvos. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/build.yml | 27 +++++++++++++++++++++++++-- b-tvos.sh | 23 +++++++++++++++++++++++ b.sh | 3 +++ docs/building.md | 16 ++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100755 b-tvos.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7017147e8a..eef05126ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -313,6 +313,24 @@ jobs: cxx: clang++ args: ./b-ios.sh id: ios + - os: macos-latest + extra: tvos + cc: clang + cxx: clang++ + args: ./b-tvos.sh + id: tvos + - os: macos-latest + extra: libretro_ios + cc: clang + cxx: clang++ + args: ./b.sh --ios --libretro + id: ios-libretro + - os: macos-latest + extra: libretro_tvos + cc: clang + cxx: clang++ + args: ./b.sh --tvos --libretro + id: tvos-libretro runs-on: ${{ matrix.os }} steps: @@ -425,7 +443,7 @@ jobs: --known-failures=${{ matrix.extra }} - name: Package build - if: matrix.extra == 'test' || matrix.id == 'ios' + if: matrix.extra == 'test' || matrix.id == 'ios' || matrix.id == 'tvos' run: | mkdir -p ppsspp if [ -e build*/$BUILD_CONFIGURATION/PPSSPPSDL ]; then @@ -443,6 +461,11 @@ jobs: find build -name 'PPSSPP*.xcarchive' -exec cp -a '{}' ppsspp/ \; find build -name 'PPSSPP*.deb' -exec cp -a '{}' ppsspp/ \; find build -name 'org.ppsspp*.deb' -exec cp -a '{}' ppsspp/ \; + elif [ -e build-tvos-xcode/Release-appletvos/PPSSPP.app ]; then + # Unsigned. Zipped, since artifact zipping loses symlinks and permissions. + pushd build-tvos-xcode/Release-appletvos + zip -qry ../../ppsspp/PPSSPP-tvOS.zip PPSSPP.app + popd elif [ -e build*/PPSSPPSDL ]; then cp build*/PPSSPPSDL ppsspp/ cp -r assets ppsspp/assets @@ -467,7 +490,7 @@ jobs: - name: Upload iOS build uses: actions/upload-artifact@v7 - if: matrix.id == 'ios' + if: matrix.id == 'ios' || matrix.id == 'tvos' with: name: ${{ matrix.id }} build path: ppsspp/ diff --git a/b-tvos.sh b/b-tvos.sh new file mode 100755 index 0000000000..8b92a290b6 --- /dev/null +++ b/b-tvos.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Builds the tvOS app (Apple TV, arm64). Without arguments it's an unsigned build, as in CI. +# To sign for a device, pass the signing settings, which then go to xcodebuild instead: +# ./b-tvos.sh -allowProvisioningUpdates DEVELOPMENT_TEAM= CODE_SIGN_STYLE=Automatic "CODE_SIGN_IDENTITY=Apple Development" + +set -e + +FOLDER_NAME="build-tvos-xcode" +CONFIGURATION="${CONFIGURATION:-Release}" + +if [[ ! -d $FOLDER_NAME ]]; then + cmake -S . -B $FOLDER_NAME -GXcode -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake -DIOS_PLATFORM=TVOS +fi +# Xcode looks for git-version.cpp before any script phase gets to generate it. +cmake -DSOURCE_DIR=. -DOUTPUT_DIR=$FOLDER_NAME -P git-version.cmake + +if [[ $# -eq 0 ]]; then + set -- CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO +fi + +xcodebuild -project $FOLDER_NAME/PPSSPP.xcodeproj -scheme PPSSPP -configuration $CONFIGURATION -destination 'generic/platform=tvOS' -quiet build "$@" + +echo "Built $FOLDER_NAME/$CONFIGURATION-appletvos/PPSSPP.app" diff --git a/b.sh b/b.sh index ff80e9bdd1..1f95a09e3f 100755 --- a/b.sh +++ b/b.sh @@ -8,6 +8,9 @@ do --ios) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake ${CMAKE_ARGS}" TARGET_OS=iOS ;; + --tvos) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake -DIOS_PLATFORM=TVOS ${CMAKE_ARGS}" + TARGET_OS=tvOS + ;; --ios-xcode) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake -DIOS_PLATFORM=OS -GXcode ${CMAKE_ARGS}" TARGET_OS=iOS-xcode ;; diff --git a/docs/building.md b/docs/building.md index b9eba1ae36..f63fc7f371 100644 --- a/docs/building.md +++ b/docs/building.md @@ -106,6 +106,22 @@ by default, but if you want to test-build it locally: - Example (POSIX): `cd android && NDK=/path/to/ndk ./ab.sh APP_ABI=arm64-v8a HEADLESS=1` - The `ppsspp_headless` executable ends up in `android/libs//`. +## tvOS + +The tvOS app is the iOS app with the iPhone-only parts compiled out, checked with +`PPSSPP_PLATFORM(TVOS)` (tvOS also gets `PPSSPP_PLATFORM(IOS)`). The CMake side is the iOS toolchain +with `-DIOS_PLATFORM=TVOS`, which sets `TVOS`. + +- `./b-tvos.sh` builds an unsigned app into `build-tvos-xcode/Release-appletvos/`. To run it on an + Apple TV, pass the signing settings, which replace the unsigned defaults: + `./b-tvos.sh -allowProvisioningUpdates DEVELOPMENT_TEAM= CODE_SIGN_STYLE=Automatic "CODE_SIGN_IDENTITY=Apple Development"`, + then `xcrun devicectl device install app --device `. +- `./b.sh --tvos --libretro` (and `./b.sh --ios --libretro`) build the libretro cores. tvOS has no + `sigaltstack`, among other things, so this is the build that catches it. +- There's no tvOS simulator build: FFmpeg has no tvOS simulator libraries. +- tvOS apps have no persistent storage except about 500 KB of `NSUserDefaults`. Anything else may be + purged, so the memory stick is in Caches for now. + ## libretro core build (Windows) Canonical instructions are in `libretro/README_WINDOWS.txt` - read that first, this is a summary plus