name: Build and Release KytyPS5 on: workflow_dispatch: push: branches: [ main, master ] pull_request: jobs: windows: name: Build KytyPS5 (Windows) runs-on: windows-2022 steps: - name: Checkout repository uses: actions/checkout@v4 with: submodules: recursive - name: Setup Visual Studio environment uses: ilammy/msvc-dev-cmd@v1 - name: Setup Ninja uses: seanmiddleditch/gha-setup-ninja@v5 - name: Locate vcpkg id: vcpkg shell: pwsh run: | $vcpkgRoot = Split-Path (Get-Command vcpkg).Source $portHash = (Get-FileHash "$vcpkgRoot\ports\glslang\vcpkg.json" -Algorithm SHA256).Hash "root=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append "port_hash=$($portHash.ToLowerInvariant())" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Cache glslang id: glslang_cache uses: actions/cache@v4 with: path: ${{ steps.vcpkg.outputs.root }}\installed\x64-windows key: glslang-${{ runner.os }}-${{ runner.arch }}-${{ steps.vcpkg.outputs.port_hash }}-tools-opt - name: Install glslang shell: pwsh run: | $vcpkgRoot = "${{ steps.vcpkg.outputs.root }}" if ("${{ steps.glslang_cache.outputs.cache-hit }}" -ne "true") { vcpkg install glslang[tools,opt]:x64-windows } "$vcpkgRoot\installed\x64-windows\tools\glslang" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Install Qt 6.10.3 uses: jurplel/install-qt-action@v4 with: version: "6.10.3" host: windows target: desktop arch: win64_msvc2022_64 cache: true - name: Verify toolchain shell: cmd run: | git --version cmake --version ninja --version clang-cl --version glslangValidator --version echo Qt6_DIR=%Qt6_DIR% - name: Configure shell: cmd run: | cmake -S src -B _Build/windows ^ -G Ninja ^ -DCMAKE_BUILD_TYPE=Release ^ -DCMAKE_C_COMPILER=clang-cl ^ -DCMAKE_CXX_COMPILER=clang-cl ^ -DCMAKE_PREFIX_PATH="%Qt6_DIR%" - name: Build shell: cmd run: | cmake --build _Build/windows --target launcher --parallel - name: Install shell: cmd run: | cmake --install _Build/windows --prefix _Build/windows/install - name: Upload Windows artifacts uses: actions/upload-artifact@v4 with: name: KytyPS5-Windows-x64 path: _Build/windows/install/** if-no-files-found: error macos: name: Build KytyPS5 (macOS) runs-on: macos-15 steps: - name: Checkout repository uses: actions/checkout@v4 with: submodules: recursive - name: Select Xcode 26 shell: bash run: | xcode_path="$(ls -d /Applications/Xcode_26*.app | tail -n 1)" test -n "$xcode_path" sudo xcode-select --switch "$xcode_path/Contents/Developer" xcodebuild -version - name: Install build dependencies shell: bash run: brew install glslang ninja - name: Install Qt 6.10.3 uses: jurplel/install-qt-action@v4 with: version: "6.10.3" host: mac target: desktop arch: clang_64 cache: true - name: Verify toolchain shell: bash run: | git --version cmake --version ninja --version clang++ --version glslangValidator --version echo "Host architecture: $(uname -m)" echo "QT_ROOT_DIR=$QT_ROOT_DIR" - name: Configure shell: bash run: | cmake -S src -B _Build/macos \ -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_OSX_ARCHITECTURES=x86_64 \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_PREFIX_PATH="$QT_ROOT_DIR" - name: Build shell: bash run: | cmake --build _Build/macos --target launcher --parallel - name: Install shell: bash run: | cmake --install _Build/macos --prefix _Build/macos/install - name: Bundle MoltenVK shell: bash env: MOLTENVK_VERSION: v1.4.2 MOLTENVK_SHA256: f95765a6229cb7b915990a2890ce12ebe36a730b021545d3d52ae69ce4c4024e run: | archive="$RUNNER_TEMP/MoltenVK-macos.tar" package="$RUNNER_TEMP/MoltenVK" curl --fail --location --retry 3 \ --output "$archive" \ "https://github.com/KhronosGroup/MoltenVK/releases/download/$MOLTENVK_VERSION/MoltenVK-macos.tar" echo "$MOLTENVK_SHA256 $archive" | shasum -a 256 --check tar -xf "$archive" -C "$RUNNER_TEMP" install -m 755 \ "$package/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" \ _Build/macos/install/libMoltenVK.dylib install -m 644 "$package/LICENSE" _Build/macos/install/LICENSE.MoltenVK codesign --force --sign - --timestamp=none _Build/macos/install/libMoltenVK.dylib - name: Verify artifacts shell: bash run: | file _Build/macos/install/launcher file _Build/macos/install/kyty_emulator file _Build/macos/install/libMoltenVK.dylib lipo _Build/macos/install/launcher -verify_arch x86_64 lipo _Build/macos/install/kyty_emulator -verify_arch x86_64 lipo _Build/macos/install/libMoltenVK.dylib -verify_arch x86_64 codesign --verify --strict _Build/macos/install/kyty_emulator codesign --verify --strict _Build/macos/install/libMoltenVK.dylib - name: Upload macOS artifacts uses: actions/upload-artifact@v4 with: name: KytyPS5-macOS-x86_64 path: _Build/macos/install/** if-no-files-found: error linux: name: Build KytyPS5 (Linux) runs-on: ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v4 with: submodules: recursive - name: Install build dependencies shell: bash run: | sudo apt-get update sudo apt-get install --no-install-recommends --yes \ clang \ glslang-tools \ libasound2-dev \ libdbus-1-dev \ libgl1-mesa-dev \ libpulse-dev \ libudev-dev \ libwayland-dev \ libx11-dev \ libxcursor-dev \ libxext-dev \ libxfixes-dev \ libxi-dev \ libxkbcommon-dev \ libxrandr-dev \ libxss-dev \ lld \ ninja-build \ wayland-protocols - name: Install Qt 6.10.3 uses: jurplel/install-qt-action@v4 with: version: "6.10.3" host: linux target: desktop arch: linux_gcc_64 cache: true - name: Verify toolchain shell: bash run: | git --version cmake --version ninja --version clang++ --version ld.lld --version glslangValidator --version echo "Qt6_DIR=$Qt6_DIR" - name: Configure shell: bash run: | mkdir -p _Build cmake -S src -B _Build/linux \ -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_PREFIX_PATH="$Qt6_DIR" 2>&1 | tee _Build/configure.log exit "${PIPESTATUS[0]}" - name: Verify SDL2 backends shell: bash run: | status=0 for feature in SDL_ALSA SDL_PULSEAUDIO SDL_WAYLAND SDL_X11 SDL_LIBUDEV SDL_DBUS; do if grep -qE "^-- ${feature} +\\(Wanted: ON\\): ON" _Build/configure.log; then echo "ok ${feature}" else echo "FAIL ${feature} is not enabled" status=1 fi done exit "$status" - name: Build shell: bash run: | cmake --build _Build/linux \ --target launcher page_manager_tests memory_tracker_tests \ --parallel - name: Test shell: bash run: | ctest --test-dir _Build/linux --output-on-failure \ -R '^(page_manager|memory_tracker)$' - name: Install shell: bash run: | cmake --install _Build/linux --prefix _Build/linux/install - name: Verify artifacts shell: bash run: | file _Build/linux/install/launcher file _Build/linux/install/kyty_emulator file _Build/linux/install/kyty_emulator | grep -q "ELF 64-bit LSB .*x86-64" ldd _Build/linux/install/kyty_emulator > /dev/null readelf -d _Build/linux/install/launcher | grep -q 'RPATH.*\$ORIGIN/lib' while IFS= read -r -d '' binary; do while read -r dependency; do test -e "_Build/linux/install/lib/$dependency" done < <( readelf -d "$binary" | sed -n 's/.*Shared library: \[\(libQt6[^]]*\|libicu[^]]*\)\].*/\1/p' ) done < <( find _Build/linux/install/launcher _Build/linux/install/plugins \ -type f \( -name launcher -o -name '*.so' \) -print0 ) _Build/linux/install/kyty_emulator --help > /dev/null - name: Upload Linux artifacts uses: actions/upload-artifact@v4 with: name: KytyPS5-Linux-x86_64 path: _Build/linux/install/** if-no-files-found: error release: name: Release KytyPS5 if: github.event_name == 'push' && github.repository == 'KytyPS5/KytyPS5' needs: [windows, macos, linux] runs-on: ubuntu-latest permissions: contents: write steps: - name: Download builds uses: actions/download-artifact@v4 with: path: artifacts - name: Set release name shell: bash run: | echo "RELEASE_NAME=KytyPS5-$(date -u +'%Y-%m-%d')-${GITHUB_SHA::7}" >> "$GITHUB_ENV" - name: Package builds shell: bash run: | windows_dir="artifacts/KytyPS5-Windows-x64" macos_dir="artifacts/KytyPS5-macOS-x86_64" linux_dir="artifacts/KytyPS5-Linux-x86_64" test -d "$windows_dir" test -d "$macos_dir" test -d "$linux_dir" chmod a+x \ "$macos_dir/launcher" \ "$macos_dir/kyty_emulator" \ "$macos_dir/libMoltenVK.dylib" \ "$linux_dir/launcher" \ "$linux_dir/kyty_emulator" ( cd "$windows_dir" zip -r "$GITHUB_WORKSPACE/$RELEASE_NAME-Windows-x64.zip" . ) ( cd "$macos_dir" zip -r "$GITHUB_WORKSPACE/$RELEASE_NAME-macOS-x86_64.zip" . ) tar -C "$linux_dir" -czf \ "$GITHUB_WORKSPACE/$RELEASE_NAME-Linux-x86_64.tar.gz" . - name: Create release shell: bash env: GH_TOKEN: ${{ github.token }} run: | assets=( "$RELEASE_NAME-Windows-x64.zip" "$RELEASE_NAME-macOS-x86_64.zip" "$RELEASE_NAME-Linux-x86_64.tar.gz" ) if gh release view "$RELEASE_NAME" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then gh release upload "$RELEASE_NAME" "${assets[@]}" \ --clobber \ --repo "$GITHUB_REPOSITORY" else gh release create "$RELEASE_NAME" "${assets[@]}" \ --generate-notes \ --repo "$GITHUB_REPOSITORY" \ --target "$GITHUB_SHA" \ --title "$RELEASE_NAME" fi