Files
Vita3K/.github/workflows/c-cpp.yml
Sergi・セルジ 908e3c162d Run the latest VitaAutotests, and implement the atomic calls (#4243)
* ci: let an autotest be skipped

Some VitaAutotests tests check timing, like how long a short delay takes,
and on Vita3K their outcome depends on how busy the CI runner is, so they
can pass on one run and fail on the next. The expectations file can now
mark such a test skip, which leaves it out of the run.

* ci: run the latest VitaAutotests

Move AUTOTESTS_REF to the latest VitaAutotests commit, which adds 28
scheduler and sync tests:
- stagnant_mask passes.
- delay_precision, timeout_threshold and timer_period check timing, so
  they're skipped.
- standby_handover_order is skipped too. Vita3K runs its threads at once,
  so the order it checks comes down to a race of about 1 ms.
- The other 24 fail, mostly because threads ignore their core and
  priority, and atomics because no sceKernelAtomic call is implemented.

* kernel: implement the atomic calls

Every sceKernelAtomic call was a stub that returned 0 and left memory
alone. They now work on the guest value with host atomics, the way the
atomics test shows a Vita does: the AndGet calls return the new value,
the GetAnd calls, CompareAndSet and DecIfPositive the old one. AddUnless
stores its last argument instead once the sum reaches it, comparing as
signed and wrapping only at 32 and 64 bits, and DecIfPositive takes 0
down to -1 at 8 and 16 bits.

* kernel: report an unlock of a deleted lightweight mutex as not owned

A delete clears the owner in a lightweight mutex's work area, so a Vita
fails a later unlock with LW_MUTEX_NOT_OWNED, while Vita3K said the
mutex was unknown. That's what cond_mutex_delete sees when a condition
wait ends because its mutex was deleted.
2026-10-15 12:56:53 +02:00

367 lines
13 KiB
YAML

name: Build CI
on:
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
env:
BUILD_CONFIG: Release
QT_VERSION: '6.11.0'
SCCACHE_GHA_ENABLED: "true"
# The VitaAutotests commit to test with. Bump it to pick up new tests.
AUTOTESTS_REF: 31f9e6e2c2a870640dd80ccbd98650cc1d86db5a
jobs:
desktop-build:
name: Desktop (${{ matrix.platform }})
runs-on: ${{ matrix.runs_on }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux-x64
runs_on: ubuntu-26.04
arch: x86_64
cmake_preset: ci-linux-clang-appimage
cache_path: ''
qt_install_deps: 'true'
- platform: linux-arm64
runs_on: ubuntu-26.04-arm
arch: aarch64
cmake_preset: ci-linux-clang-appimage
cache_path: ''
qt_install_deps: 'true'
- platform: windows-x64
runs_on: windows-latest
arch: x86_64
cmake_preset: ci-windows-msvc
vcpkg_root: C:\vcpkg
vcpkg_triplet: x64-windows-static-md
cache_path: C:\vcpkg-binary-cache
qt_install_deps: 'false'
- platform: windows-arm64
runs_on: windows-11-arm
cmake_preset: ci-windows-msys2-clang
msys2_env: CLANGARM64
cache_path: C:\msys2-ccache
qt_install_deps: 'false'
- platform: macos-x64
runs_on: macos-latest
cmake_preset: ci-macos-x64
cache_path: ~/Library/Caches/ccache
qt_install_deps: 'false'
- platform: macos-arm64
runs_on: macos-latest
cmake_preset: ci-macos-arm64
cache_path: ~/Library/Caches/ccache
qt_install_deps: 'false'
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
- name: Restore cache
uses: actions/cache@v6
if: ${{ matrix.cache_path != '' }}
with:
path: ${{ matrix.cache_path }}
key: cache-${{ matrix.platform }}-${{ env.BUILD_CONFIG }}-${{ hashFiles('CMakeLists.txt', 'CMakePresets.json', 'cmake/**', '.ci/**', '.github/workflows/c-cpp.yml', 'vcpkg.json') }}
restore-keys: |
cache-${{ matrix.platform }}-${{ env.BUILD_CONFIG }}-
- name: Set up build environment (Linux)
run: bash ./.ci/setup-linux.sh
if: startsWith(matrix.platform, 'linux-')
- name: Set up build environment (macOS)
run: bash ./.ci/setup-macos.sh
if: startsWith(matrix.platform, 'macos-')
- name: Set up build environment (Windows MSVC)
shell: pwsh
env:
VCPKG_ROOT: ${{ matrix.vcpkg_root }}
VCPKG_DEFAULT_BINARY_CACHE: ${{ matrix.cache_path }}
run: |
New-Item -ItemType Directory -Force -Path $env:VCPKG_DEFAULT_BINARY_CACHE | Out-Null
.\.ci\setup-windows-msvc.ps1 -VcpkgTriplet '${{ matrix.vcpkg_triplet }}'
if: matrix.platform == 'windows-x64'
- uses: TheMrMilchmann/setup-msvc-dev@v4
with:
arch: ${{ matrix.arch }}
if: matrix.platform == 'windows-x64'
- uses: mozilla-actions/sccache-action@v0.0.11
if: startsWith(matrix.platform, 'linux-') || matrix.platform == 'windows-x64'
with:
disable_annotations: true
- name: Set up MSYS2 (Windows ARM)
uses: msys2/setup-msys2@v2
if: matrix.platform == 'windows-arm64'
with:
msystem: ${{ matrix.msys2_env }}
update: true
cache: true
install: |
git
pacboy: |
clang:p
ccache:p
cmake:p
lld:p
ninja:p
boost:p
openssl:p
curl:p
zlib:p
qt6-base:p
qt6-multimedia:p
qt6-svg:p
qt6-tools:p
- name: Reset ccache statistics
run: ccache -z
if: startsWith(matrix.platform, 'macos-')
- name: Install Qt 6.11.0 (Windows MSVC)
uses: jurplel/install-qt-action@v4
if: matrix.platform == 'windows-x64'
with:
version: ${{ env.QT_VERSION }}
modules: qtmultimedia
host: windows
target: desktop
arch: win64_msvc2022_64
cache: true
install-deps: ${{ matrix.qt_install_deps }}
aqtsource: git+https://github.com/miurahr/aqtinstall.git@f383b3c7d9658e881bd8ce8810057393bd934ee1
- name: Install Qt 6.11.0
uses: jurplel/install-qt-action@v4
if: matrix.platform != 'windows-arm64' && matrix.platform != 'windows-x64'
with:
version: ${{ env.QT_VERSION }}
modules: qtmultimedia
cache: true
install-deps: ${{ matrix.qt_install_deps }}
- name: Build desktop target (Linux/macOS)
run: bash ./.ci/build-desktop.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
if: startsWith(matrix.platform, 'linux-') || startsWith(matrix.platform, 'macos-')
- name: Package Linux AppImage with Anylinux
run: bash ./.ci/package-appimage.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
if: startsWith(matrix.platform, 'linux-')
- name: Build desktop target (Windows MSVC)
shell: bash
env:
VCPKG_ROOT: ${{ matrix.vcpkg_root }}
VCPKG_DEFAULT_BINARY_CACHE: ${{ matrix.cache_path }}
run: bash ./.ci/build-desktop.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
if: matrix.platform == 'windows-x64'
- name: Build desktop target (Windows ARM MSYS2)
shell: msys2 {0}
run: bash ./.ci/build-windows-msys2.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
if: matrix.platform == 'windows-arm64'
- name: Compute artifact paths
shell: bash
run: |
echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
echo "ARTIFACT_NAME=vita3k-$(git rev-parse --short HEAD)-${{ matrix.platform }}" >> "$GITHUB_ENV"
echo "ARTIFACT_DIR=artifacts/vita3k-$(git rev-parse --short HEAD)-${{ matrix.platform }}" >> "$GITHUB_ENV"
- name: Stage desktop artifact (Linux/macOS)
run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
if: startsWith(matrix.platform, 'linux-') || startsWith(matrix.platform, 'macos-')
- name: Stage desktop artifact (Windows MSVC)
shell: bash
run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
if: matrix.platform == 'windows-x64'
- name: Stage desktop artifact (Windows ARM MSYS2)
shell: msys2 {0}
run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
if: matrix.platform == 'windows-arm64'
- name: Print ccache statistics
run: ccache -s
if: startsWith(matrix.platform, 'macos-')
- name: Print sccache statistics
run: sccache --show-stats
if: startsWith(matrix.platform, 'linux-') || matrix.platform == 'windows-x64'
- name: Upload desktop artifact
uses: actions/upload-artifact@v7
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_DIR }}
- name: Check out the autotests
uses: actions/checkout@v7
with:
repository: Vita3K/VitaAutotests
ref: ${{ env.AUTOTESTS_REF }}
path: autotests
if: matrix.platform == 'linux-x64'
- name: Run the autotests
run: bash ./.ci/run-autotests.sh "build/${{ matrix.cmake_preset }}/bin/${{ env.BUILD_CONFIG }}/Vita3K" autotests
if: matrix.platform == 'linux-x64'
android-build:
name: Android
runs-on: ubuntu-latest
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/.vcpkg-binary-cache
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
- name: Restore vcpkg binary cache
uses: actions/cache@v6
with:
path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
key: vcpkg-bincache-android-${{ hashFiles('vcpkg.json', 'CMakeLists.txt', 'cmake/**', '.ci/**', 'android/app/build.gradle', '.github/workflows/c-cpp.yml') }}
restore-keys: |
vcpkg-bincache-android-
- name: Set up Java
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '17'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
with:
add-job-summary: on-failure
cache-provider: basic
validate-wrappers: false
- name: Set up Android SDK tools
uses: android-actions/setup-android@v4
with:
packages: ''
- name: Set up Android build environment
env:
VCPKG_ROOT: /usr/local/share/vcpkg
run: |
mkdir -p "$VCPKG_DEFAULT_BINARY_CACHE"
bash ./.ci/setup-android.sh
- uses: hendrikmuhs/ccache-action@v1.2.24
- name: Decode Android keystore
env:
KEYSTORE_ENCODED: ${{ secrets.KEYSTORE }}
run: |
if [ -n "$KEYSTORE_ENCODED" ]; then
echo "$KEYSTORE_ENCODED" | base64 --decode > /home/runner/keystore.jks
fi
- name: Compute artifact paths
shell: bash
run: |
echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
echo "ARTIFACT_NAME=vita3k-$(git rev-parse --short HEAD)-android" >> "$GITHUB_ENV"
echo "ARTIFACT_DIR=artifacts/vita3k-$(git rev-parse --short HEAD)-android" >> "$GITHUB_ENV"
- name: Build Android target
env:
SIGNING_STORE_PATH: /home/runner/keystore.jks
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
VCPKG_ROOT: /usr/local/share/vcpkg
ANDROID_NDK_HOME: ${{ env.ANDROID_NDK_HOME }}
run: bash ./.ci/build-android.sh "${{ env.ARTIFACT_DIR }}"
- name: Print Android ccache statistics
run: ccache -s
- name: Upload Android artifact
uses: actions/upload-artifact@v7
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_DIR }}
create-release:
needs: [desktop-build, android-build]
runs-on: ubuntu-latest
concurrency:
group: create-release
cancel-in-progress: false
if: |
github.ref == 'refs/heads/master' &&
github.repository == 'Vita3K/Vita3K'
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v8
- name: Get commit info
run: |
echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
echo "BUILD_VARIABLE=$(git rev-list --count HEAD)" >> "$GITHUB_ENV"
echo "LAST_COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> "$GITHUB_ENV"
- name: Get last committer
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
COMMITTER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }} \
| jq -r '.commit.author.name')
echo "COMMITTER_NAME=$COMMITTER" >> "$GITHUB_ENV"
- name: Prepare release artifacts
run: bash ./.ci/release-collect.sh
- name: Upload to store repository
uses: tcnksm/ghr@v0
with:
tag: ${{ env.BUILD_VARIABLE }}
path: artifacts-store/
owner: ${{ github.repository_owner }}
repository: Vita3K-builds
name: "Build: ${{ env.BUILD_VARIABLE }}"
body: "Corresponding commit: [${{ env.LAST_COMMIT_MESSAGE }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }}) (${{ env.COMMITTER_NAME }})"
token: ${{ secrets.STORE_TOKEN }}
- name: Upload to master repository
uses: tcnksm/ghr@v0
with:
tag: continuous
path: artifacts-master/
delete: "true"
owner: ${{ github.repository_owner }}
repository: Vita3K
name: "Automatic CI builds"
body: "Corresponding commit: ${{ github.sha }}\nVita3K Build: ${{ env.BUILD_VARIABLE }}"