Parcourir la source

ci: merge all workflows

Anonymous Maarten il y a 4 mois
Parent
commit
ba433e4a5d

+ 93 - 0
.github/actions/setup-vita-gles/action.yml

@@ -0,0 +1,93 @@
+name: 'Setup GLES for PlayStation Vita'
+description: 'Download GLES for VITA (PVR or PIB), and copy it into the vita sdk'
+inputs:
+  pib-version:
+    description: 'PIB version'
+    default: '1.1.4'
+  pvr-version:
+    description: 'PVR_PSP2 version'
+    default: '3.9'
+  type:
+    description: '"pib" or "pvr"'
+    default: ''
+runs:
+  using: 'composite'
+  steps:
+    - name: 'Calculate variables'
+      id: calc
+      shell: sh
+      run: |
+        if test "x${VITASDK}" = "x"; then
+          echo "VITASDK must be defined"
+          exit 1;
+        fi
+        case "x${{ inputs.type }}" in
+          "xpvr")
+            echo "cache-key=SDL-vita-gles-pvr-${{ inputs.pvr-version}}" >> ${GITHUB_OUTPUT}
+            ;;
+          "xpib")
+            echo "cache-key=SDL-vita-gles-pib-${{ inputs.pib-version}}" >> ${GITHUB_OUTPUT}
+            ;;
+          *)
+            echo "Invalid type. Must be 'pib' or 'pvr'."
+            exit 1
+            ;;
+        esac
+    - uses: actions/cache/restore@v4
+      id: restore-cache
+      with:
+        path: /vita/dependencies
+        key: '${{ steps.calc.outputs.cache-key }}'
+    - name: 'Download PVR_PSP2 (GLES)'
+      if: ${{ !steps.restore-cache.outputs.cache-hit && inputs.type == 'pvr' }}
+      shell: sh
+      run: |
+        pvr_psp2_version=${{ inputs.pvr-version }}
+        
+        mkdir -p /vita/dependencies/include
+        mkdir -p /vita/dependencies/lib
+        
+        # Configure PVR_PSP2 headers
+        wget https://github.com/GrapheneCt/PVR_PSP2/archive/refs/tags/v$pvr_psp2_version.zip -P/tmp
+        unzip /tmp/v$pvr_psp2_version.zip -d/tmp
+        cp -r /tmp/PVR_PSP2-$pvr_psp2_version/include/* /vita/dependencies/include
+        rm /tmp/v$pvr_psp2_version.zip
+        
+        # include guard of PVR_PSP2's khrplatform.h does not match the usual one
+        sed -i -e s/__drvkhrplatform_h_/__khrplatform_h_/ /vita/dependencies/include/KHR/khrplatform.h
+        
+        # Configure PVR_PSP2 stub libraries
+        wget https://github.com/GrapheneCt/PVR_PSP2/releases/download/v$pvr_psp2_version/vitasdk_stubs.zip -P/tmp
+        unzip /tmp/vitasdk_stubs.zip -d/tmp/pvr_psp2_stubs
+        find /tmp/pvr_psp2_stubs -type f -name "*.a" -exec cp {} /vita/dependencies/lib \;
+        rm /tmp/vitasdk_stubs.zip
+        rm -rf /tmp/pvr_psp2_stubs
+
+    - name: 'Download gl4es4vita (OpenGL)'
+      if: ${{ !steps.restore-cache.outputs.cache-hit && inputs.type == 'pib' }}
+      shell: sh
+      run: |
+        gl4es4vita_version=${{ inputs.pib-version }}
+        
+        mkdir -p /vita/dependencies/include
+        mkdir -p /vita/dependencies/lib
+        
+        # Configure gl4es4vita headers
+        wget https://github.com/SonicMastr/gl4es4vita/releases/download/v$gl4es4vita_version-vita/include.zip -P/tmp
+        unzip -o /tmp/include.zip -d/vita/dependencies/include
+        rm /tmp/include.zip
+        
+        # Configure gl4es4vita stub libraries
+        wget https://github.com/SonicMastr/gl4es4vita/releases/download/v$gl4es4vita_version-vita/vitasdk_stubs.zip -P/tmp
+        unzip /tmp/vitasdk_stubs.zip -d/vita/dependencies/lib
+
+    - uses: actions/cache/save@v4
+      if: ${{ !steps.restore-cache.outputs.cache-hit }}
+      with:
+        path: /vita/dependencies
+        key: '${{ steps.calc.outputs.cache-key }}'
+
+    - name: Copy PVR_PSP2 (GLES) or gl4es4vita (OpenGL) to vita toolchain dir
+      shell: sh
+      run: |
+        cp -rv /vita/dependencies/* ${VITASDK}/arm-vita-eabi

+ 0 - 81
.github/workflows/android.yml

@@ -1,81 +0,0 @@
-name: Build (Android)
-
-on: [push, pull_request]
-
-jobs:
-  android:
-    name: ${{ matrix.platform.name }}
-    runs-on: ubuntu-latest
-
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-          - { name: Android.mk  }
-          - { name: CMake, cmake: 1, android_abi: "arm64-v8a", android_platform: 23, arch: "aarch64" }
-
-    steps:
-      - uses: actions/checkout@v4
-      - uses: nttld/setup-ndk@v1
-        id: setup_ndk
-        with:
-          ndk-version: r21e
-      - name: Build (Android.mk)
-        if: ${{ matrix.platform.name == 'Android.mk' }}
-        run: |
-          ./build-scripts/androidbuildlibs.sh
-      - name: Setup (CMake)
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          sudo apt-get update
-          sudo apt-get install ninja-build pkg-config
-      - name: Configure (CMake)
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          cmake -B build \
-            -DCMAKE_TOOLCHAIN_FILE=${{ steps.setup_ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake \
-            -DSDL_WERROR=ON \
-            -DANDROID_PLATFORM=${{ matrix.platform.android_platform }} \
-            -DANDROID_ABI=${{ matrix.platform.android_abi }} \
-            -DSDL_STATIC_PIC=ON \
-            -DSDL_VENDOR_INFO="Github Workflow" \
-            -DCMAKE_INSTALL_PREFIX=prefix \
-            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-            -GNinja
-      - name: Build (CMake)
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          cmake --build build --config RelWithDebInfo --parallel --verbose
-      - name: Install (CMake)
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          cmake --install build --config RelWithDebInfo
-          echo "SDL2_DIR=$(pwd)/prefix" >> $GITHUB_ENV
-          ( cd prefix; find ) | LC_ALL=C sort -u
-      - name: Verify CMake configuration files
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          cmake -S cmake/test -B cmake_config_build -G Ninja \
-            -DCMAKE_TOOLCHAIN_FILE=${{ steps.setup_ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake \
-            -DANDROID_PLATFORM=${{ matrix.platform.android_platform }} \
-            -DANDROID_ABI=${{ matrix.platform.android_abi }} \
-            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-            -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }}
-          cmake --build cmake_config_build --verbose
-      - name: Verify sdl2-config
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          export CC="${{ steps.setup_ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=${{ matrix.platform.arch }}-none-linux-androideabi${{ matrix.platform.android_platform }}"
-          export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-          cmake/test/test_sdlconfig.sh
-      - name: Verify sdl2.pc
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          export CC="${{ steps.setup_ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=${{ matrix.platform.arch }}-none-linux-androideabi${{ matrix.platform.android_platform }}"
-          export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-          cmake/test/test_pkgconfig.sh
-      - name: Verify Android.mk
-        if: ${{ matrix.platform.name == 'CMake' }}
-        run: |
-          export NDK_MODULE_PATH=${{ env.SDL2_DIR }}/share/ndk-modules
-          ndk-build -C ${{ github.workspace }}/cmake/test APP_PLATFORM=android-${{ matrix.platform.android_platform }} APP_ABI=${{ matrix.platform.android_abi }} NDK_OUT=$PWD NDK_LIBS_OUT=$PWD V=1

+ 48 - 0
.github/workflows/build.yml

@@ -0,0 +1,48 @@
+name: 'Build (All)'
+
+on: [push, pull_request]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
+  cancel-in-progress: true
+
+jobs:
+  controller:
+    name: 'Create test plan'
+    runs-on: 'ubuntu-latest'
+    outputs:
+      platforms-level1: ${{ steps.plan.outputs.platforms-level1 }}
+      platforms-others: ${{ steps.plan.outputs.platforms-others }}
+    steps:
+      - uses: actions/setup-python@main
+        with:
+          python-version: 3.x
+      - uses: actions/checkout@main
+        with:
+          sparse-checkout: '.github/workflows/create-test-plan.py'
+      - name: 'Create plan'
+        id: plan
+        run: |
+          # Adding [sdl-ci-filter GLOB] to the commit message will limit the jobs
+          # e.g. [sdl-ci-filter msvc-*]
+          EOF=$(openssl rand -hex 32)
+          cat >/tmp/commit_message.txt <<$EOF
+          ${{ github.event.head_commit.message }}
+          $EOF
+
+          python .github/workflows/create-test-plan.py \
+            --github-variable-prefix platforms \
+            --github-ci \
+            --verbose \
+            ${{ (github.repository_owner != 'libsdl-org' && '--no-artifact') || '' }} \
+            --commit-message-file /tmp/commit_message.txt
+  level1:
+    needs: [controller]
+    uses: './.github/workflows/generic.yml'
+    with:
+      platforms: ${{ needs.controller.outputs.platforms-level1 }}
+  level2:
+    needs: [controller, level1]
+    uses: './.github/workflows/generic.yml'
+    with:
+      platforms: ${{ needs.controller.outputs.platforms-others }}

+ 0 - 51
.github/workflows/cpactions.yml

@@ -1,51 +0,0 @@
-name: Build (C/P Actions)
-
-on: [push, pull_request]
-
-jobs:
-  freebsd:
-    runs-on: ubuntu-latest
-    name: FreeBSD
-    timeout-minutes: 30
-    steps:
-    - uses: actions/checkout@v4
-    - name: Build
-      uses: cross-platform-actions/action@v0.24.0
-      with:
-        operating_system: freebsd
-        version: '13.3'
-        shell: bash
-        run: |
-          sudo pkg update
-          sudo pkg install -y \
-              gmake \
-              pkgconf \
-              libXcursor \
-              libXext \
-              libXinerama \
-              libXi \
-              libXfixes \
-              libXrandr \
-              libXScrnSaver \
-              libXxf86vm \
-              wayland \
-              wayland-protocols \
-              libxkbcommon \
-              mesa-libs \
-              libglvnd \
-              evdev-proto \
-              libinotify \
-              alsa-lib \
-              jackit \
-              pipewire \
-              pulseaudio \
-              sndio \
-              dbus \
-              zh-fcitx \
-              ibus \
-              libudev-devd
-          mkdir build_autotools
-          export CPPFLAGS="-I/usr/local/include"
-          export LDFLAGS="-L/usr/local/lib"
-          (cd build_autotools && ../configure --disable-static)
-          gmake -C build_autotools -j`sysctl -n hw.ncpu` V=1

+ 801 - 0
.github/workflows/create-test-plan.py

@@ -0,0 +1,801 @@
+#!/usr/bin/env python
+import argparse
+import dataclasses
+import fnmatch
+from enum import Enum
+import json
+import logging
+import os
+import re
+from typing import Optional
+
+logger = logging.getLogger(__name__)
+
+
+class AppleArch(Enum):
+    ARM64 = "arm64"
+    X86_64 = "x86_64"
+
+
+class MsvcArch(Enum):
+    X86 = "x86"
+    X64 = "x64"
+    Arm32 = "arm"
+    Arm64 = "arm64"
+
+
+class JobOs(Enum):
+    WindowsLatest = "windows-latest"
+    UbuntuLatest = "ubuntu-latest"
+    MacosLatest = "macos-latest"
+    Ubuntu20_04 = "ubuntu-20.04"
+    Ubuntu22_04 = "ubuntu-22.04"
+    Ubuntu24_04 = "ubuntu-24.04"
+    Macos13 = "macos-13"
+
+
+class SdlPlatform(Enum):
+    Android = "android"
+    Emscripten = "emscripten"
+    Haiku = "haiku"
+    Msys2 = "msys2"
+    Linux = "linux"
+    MacOS = "macos"
+    Ios = "ios"
+    Tvos = "tvos"
+    Msvc = "msvc"
+    N3ds = "n3ds"
+    Ps2 = "ps2"
+    Psp = "psp"
+    Vita = "vita"
+    Riscos = "riscos"
+    FreeBSD = "freebsd"
+    NetBSD = "netbsd"
+    Watcom = "watcom"
+
+
+class Msys2Platform(Enum):
+    Mingw32 = "mingw32"
+    Mingw64 = "mingw64"
+    Clang32 = "clang32"
+    Clang64 = "clang64"
+    Ucrt64 = "ucrt64"
+
+
+class IntelCompiler(Enum):
+    Icc = "icc"
+    Icx = "icx"
+
+
+class VitaGLES(Enum):
+    Pib = "pib"
+    Pvr = "pvr"
+
+class WatcomPlatform(Enum):
+    Windows = "windows"
+    OS2 = "OS/2"
+
+
+@dataclasses.dataclass(slots=True)
+class JobSpec:
+    name: str
+    os: JobOs
+    platform: SdlPlatform
+    artifact: Optional[str]
+    container: Optional[str] = None
+    autotools: bool = False
+    no_cmake: bool = False
+    xcode: bool = False
+    android_mk: bool = False
+    lean: bool = False
+    android_arch: Optional[str] = None
+    android_abi: Optional[str] = None
+    android_platform: Optional[int] = None
+    msys2_platform: Optional[Msys2Platform] = None
+    intel: Optional[IntelCompiler] = None
+    apple_archs: Optional[set[AppleArch]] = None
+    msvc_project: Optional[str] = None
+    msvc_arch: Optional[MsvcArch] = None
+    msvc_static_crt: bool = False
+    clang_cl: bool = False
+    gdk: bool = False
+    uwp: bool = False
+    vita_gles: Optional[VitaGLES] = None
+    watcom_platform: Optional[WatcomPlatform] = None
+
+
+JOB_SPECS = {
+    "msys2-mingw32": JobSpec(name="Windows (msys2, mingw32)",               os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2,       artifact="SDL-mingw32",            msys2_platform=Msys2Platform.Mingw32, ),
+    "msys2-mingw64": JobSpec(name="Windows (msys2, mingw64)",               os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2,       artifact="SDL-mingw64",            msys2_platform=Msys2Platform.Mingw64, ),
+    "msys2-clang32": JobSpec(name="Windows (msys2, clang32)",               os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2,       artifact="SDL-mingw32-clang",      msys2_platform=Msys2Platform.Clang32, ),
+    "msys2-clang64": JobSpec(name="Windows (msys2, clang64)",               os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2,       artifact="SDL-mingw64-clang",      msys2_platform=Msys2Platform.Clang64, ),
+    "msys2-ucrt64": JobSpec(name="Windows (msys2, ucrt64)",                 os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2,       artifact="SDL-mingw64-ucrt",       msys2_platform=Msys2Platform.Ucrt64, ),
+    "msvc-x64": JobSpec(name="Windows (MSVC, x64)",                         os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-x64",             msvc_arch=MsvcArch.X64,   msvc_project="VisualC/SDL.sln", ),
+    "msvc-x86": JobSpec(name="Windows (MSVC, x86)",                         os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-x86",             msvc_arch=MsvcArch.X86,   msvc_project="VisualC/SDL.sln", ),
+    "msvc-static-x86": JobSpec(name="Windows (MSVC, static VCRT, x86)",     os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-x86",             msvc_arch=MsvcArch.X86,   msvc_static_crt=True, ),
+    "msvc-static-x64": JobSpec(name="Windows (MSVC, static VCRT, x64)",     os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-x64",             msvc_arch=MsvcArch.X64,   msvc_static_crt=True, ),
+    "msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)",          os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-clang-cl-x64",       msvc_arch=MsvcArch.X64,   clang_cl=True, ),
+    "msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)",          os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-clang-cl-x86",       msvc_arch=MsvcArch.X86,   clang_cl=True, ),
+    "msvc-arm32": JobSpec(name="Windows (MSVC, ARM)",                       os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-arm32",           msvc_arch=MsvcArch.Arm32, ),
+    "msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)",                     os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-arm64",           msvc_arch=MsvcArch.Arm64, ),
+    "msvc-uwp-x64": JobSpec(name="UWP (MSVC, x64)",                         os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-UWP",             msvc_arch=MsvcArch.X64,   msvc_project="VisualC-WinRT/SDL-UWP.sln", uwp=True, ),
+    "msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)",                         os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc,        artifact="SDL-VC-GDK",             msvc_arch=MsvcArch.X64,   msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
+    "ubuntu-20.04": JobSpec(name="Ubuntu 20.04",                            os=JobOs.Ubuntu20_04,   platform=SdlPlatform.Linux,       artifact="SDL-ubuntu20.04",        autotools=True),
+    "ubuntu-22.04": JobSpec(name="Ubuntu 22.04",                            os=JobOs.Ubuntu22_04,   platform=SdlPlatform.Linux,       artifact="SDL-ubuntu22.04",        autotools=True),
+    "steamrt-sniper": JobSpec(name="Steam Linux Runtime (Sniper)",          os=JobOs.UbuntuLatest,  platform=SdlPlatform.Linux,       artifact="SDL-slrsniper",          container="registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta", ),
+    "ubuntu-intel-icx": JobSpec(name="Ubuntu 20.04 (Intel oneAPI)",         os=JobOs.Ubuntu20_04,   platform=SdlPlatform.Linux,       artifact="SDL-ubuntu20.04-oneapi", intel=IntelCompiler.Icx, ),
+    "ubuntu-intel-icc": JobSpec(name="Ubuntu 20.04 (Intel Compiler)",       os=JobOs.Ubuntu20_04,   platform=SdlPlatform.Linux,       artifact="SDL-ubuntu20.04-icc",    intel=IntelCompiler.Icc, ),
+    "macos-gnu-arm64-x64": JobSpec(name="MacOS (GNU prefix)",               os=JobOs.MacosLatest,   platform=SdlPlatform.MacOS,       artifact="SDL-macos-arm64-x64-gnu",autotools=True, apple_archs={AppleArch.X86_64, AppleArch.ARM64, },  ),
+    "ios": JobSpec(name="iOS (CMake & xcode)",                              os=JobOs.MacosLatest,   platform=SdlPlatform.Ios,         artifact="SDL-ios-arm64",          xcode=True, ),
+    "tvos": JobSpec(name="tvOS (CMake & xcode)",                            os=JobOs.MacosLatest,   platform=SdlPlatform.Tvos,        artifact="SDL-tvos-arm64",         xcode=True, ),
+    "android-cmake": JobSpec(name="Android (CMake)",                        os=JobOs.UbuntuLatest,  platform=SdlPlatform.Android,     artifact="SDL-android-arm64",      android_abi="arm64-v8a", android_arch="aarch64", android_platform=23, ),
+    "android-mk": JobSpec(name="Android (Android.mk)",                      os=JobOs.UbuntuLatest,  platform=SdlPlatform.Android,     artifact=None,                     no_cmake=True, android_mk=True, ),
+    "emscripten": JobSpec(name="Emscripten",                                os=JobOs.UbuntuLatest,  platform=SdlPlatform.Emscripten,  artifact="SDL-emscripten", ),
+    "haiku": JobSpec(name="Haiku",                                          os=JobOs.UbuntuLatest,  platform=SdlPlatform.Haiku,       artifact="SDL-haiku-x64",          container="ghcr.io/haiku/cross-compiler:x86_64-r1beta5", ),
+    "n3ds": JobSpec(name="Nintendo 3DS",                                    os=JobOs.UbuntuLatest,  platform=SdlPlatform.N3ds,        artifact="SDL-n3ds",               container="devkitpro/devkitarm:latest", ),
+    "ps2": JobSpec(name="Sony PlayStation 2",                               os=JobOs.UbuntuLatest,  platform=SdlPlatform.Ps2,         artifact="SDL-ps2",                container="ps2dev/ps2dev:latest", ),
+    "psp": JobSpec(name="Sony PlayStation Portable",                        os=JobOs.UbuntuLatest,  platform=SdlPlatform.Psp,         artifact="SDL-psp",                container="pspdev/pspdev:latest", ),
+    "vita-pib": JobSpec(name="Sony PlayStation Vita (GLES w/ pib)",         os=JobOs.UbuntuLatest,  platform=SdlPlatform.Vita,        artifact="SDL-vita-pib",           container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pib,  ),
+    "vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)",    os=JobOs.UbuntuLatest,  platform=SdlPlatform.Vita,        artifact="SDL-vita-pvr",           container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ),
+    "riscos": JobSpec(name="RISC OS",                                       os=JobOs.UbuntuLatest,  platform=SdlPlatform.Riscos,      artifact="SDL-riscos",             container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
+    "netbsd": JobSpec(name="NetBSD",                                        os=JobOs.UbuntuLatest,  platform=SdlPlatform.NetBSD,      artifact="SDL-netbsd-x64",  autotools=True, ),
+    "freebsd": JobSpec(name="FreeBSD",                                      os=JobOs.UbuntuLatest,  platform=SdlPlatform.FreeBSD,     artifact="SDL-freebsd-x64", autotools=True, ),
+    "watcom-win32": JobSpec(name="Watcom (Windows)",                        os=JobOs.WindowsLatest, platform=SdlPlatform.Watcom,      artifact="SDL-watcom-win32",  no_cmake=True, watcom_platform=WatcomPlatform.Windows ),
+    "watcom-os2": JobSpec(name="Watcom (OS/2)",                             os=JobOs.WindowsLatest, platform=SdlPlatform.Watcom,      artifact="SDL-watcom-win32",  no_cmake=True, watcom_platform=WatcomPlatform.OS2 ),
+    # "watcom-win32"
+    # "watcom-os2"
+}
+
+
+class StaticLibType(Enum):
+    MSVC = "SDL2-static.lib"
+    A = "libSDL2.a"
+
+
+class SharedLibType(Enum):
+    WIN32 = "SDL2.dll"
+    SO_0 = "libSDL2-2.0.so.0"
+    SO = "libSDL2.so"
+    DYLIB = "libSDL2-2.0.0.dylib"
+    FRAMEWORK = "SDL2.framework/Versions/A/SDL2"
+
+
+@dataclasses.dataclass(slots=True)
+class JobDetails:
+    name: str
+    key: str
+    os: str
+    platform: str
+    artifact: str
+    no_autotools: bool
+    no_cmake: bool
+    build_autotools_tests: bool = True
+    build_tests: bool = True
+    container: str = ""
+    cmake_build_type: str = "RelWithDebInfo"
+    shell: str = "sh"
+    sudo: str = "sudo"
+    cmake_config_emulator: str = ""
+    apk_packages: list[str] = dataclasses.field(default_factory=list)
+    apt_packages: list[str] = dataclasses.field(default_factory=list)
+    brew_packages: list[str] = dataclasses.field(default_factory=list)
+    cmake_toolchain_file: str = ""
+    cmake_arguments: list[str] = dataclasses.field(default_factory=list)
+    cmake_build_arguments: list[str] = dataclasses.field(default_factory=list)
+    cppflags: list[str] = dataclasses.field(default_factory=list)
+    cc: str = ""
+    cxx: str = ""
+    cflags: list[str] = dataclasses.field(default_factory=list)
+    cxxflags: list[str] = dataclasses.field(default_factory=list)
+    ldflags: list[str] = dataclasses.field(default_factory=list)
+    pollute_directories: list[str] = dataclasses.field(default_factory=list)
+    use_cmake: bool = True
+    shared: bool = True
+    static: bool = True
+    shared_lib: Optional[SharedLibType] = None
+    static_lib: Optional[StaticLibType] = None
+    run_tests: bool = True
+    test_pkg_config: bool = True
+    cc_from_cmake: bool = False
+    source_cmd: str = ""
+    pretest_cmd: str = ""
+    android_apks: list[str] = dataclasses.field(default_factory=list)
+    android_ndk: bool = False
+    android_mk: bool = False
+    minidump: bool = False
+    intel: bool = False
+    msys2_msystem: str = ""
+    msys2_env: str = ""
+    msys2_no_perl: bool = False
+    werror: bool = True
+    msvc_vcvars_arch: str = ""
+    msvc_vcvars_sdk: str = ""
+    msvc_project: str = ""
+    msvc_project_flags: list[str] = dataclasses.field(default_factory=list)
+    setup_ninja: bool = False
+    setup_libusb_arch: str = ""
+    xcode_sdk: str = ""
+    xcode_target: str = ""
+    setup_gdk_folder: str = ""
+    cpactions: bool = False
+    cpactions_os: str = ""
+    cpactions_version: str = ""
+    cpactions_arch: str = ""
+    cpactions_setup_cmd: str = ""
+    cpactions_install_cmd: str = ""
+    setup_vita_gles_type: str = ""
+    check_sources: bool = False
+    watcom_makefile: str = ""
+
+    def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
+        data = {
+            "name": self.name,
+            "key": self.key,
+            "os": self.os,
+            "container": self.container if self.container else "",
+            "platform": self.platform,
+            "artifact": self.artifact,
+            "enable-artifacts": enable_artifacts,
+            "shell": self.shell,
+            "msys2-msystem": self.msys2_msystem,
+            "msys2-env": self.msys2_env,
+            "msys2-no-perl": self.msys2_no_perl,
+            "android-ndk": self.android_ndk,
+            "intel": self.intel,
+            "apk-packages": my_shlex_join(self.apk_packages),
+            "apt-packages": my_shlex_join(self.apt_packages),
+            "test-pkg-config": self.test_pkg_config,
+            "brew-packages": my_shlex_join(self.brew_packages),
+            "pollute-directories": my_shlex_join(self.pollute_directories),
+            "no-autotools": self.no_autotools,
+            "no-cmake": self.no_cmake,
+            "build-autotools-tests": self.build_autotools_tests,
+            "build-tests": self.build_tests,
+            "source-cmd": self.source_cmd,
+            "pretest-cmd": self.pretest_cmd,
+            "cmake-config-emulator": self.cmake_config_emulator,
+            "cc": self.cc,
+            "cxx": self.cxx,
+            "cflags": my_shlex_join(self.cppflags + self.cflags),
+            "cxxflags": my_shlex_join(self.cppflags + self.cxxflags),
+            "ldflags": my_shlex_join(self.ldflags),
+            "cmake-toolchain-file": self.cmake_toolchain_file,
+            "cmake-arguments": my_shlex_join(self.cmake_arguments),
+            "cmake-build-arguments": my_shlex_join(self.cmake_build_arguments),
+            "shared": self.shared,
+            "static": self.static,
+            "shared-lib": self.shared_lib.value if self.shared_lib else None,
+            "static-lib": self.static_lib.value if self.static_lib else None,
+            "cmake-build-type": self.cmake_build_type,
+            "run-tests": self.run_tests,
+            "android-apks": my_shlex_join(self.android_apks),
+            "android-mk": self.android_mk,
+            "werror": self.werror,
+            "sudo": self.sudo,
+            "msvc-vcvars-arch": self.msvc_vcvars_arch,
+            "msvc-vcvars-sdk": self.msvc_vcvars_sdk,
+            "msvc-project": self.msvc_project,
+            "msvc-project-flags": my_shlex_join(self.msvc_project_flags),
+            "setup-ninja": self.setup_ninja,
+            "setup-libusb-arch": self.setup_libusb_arch,
+            "cc-from-cmake": self.cc_from_cmake,
+            "xcode-sdk": self.xcode_sdk,
+            "xcode-target": self.xcode_target,
+            "cpactions": self.cpactions,
+            "cpactions-os": self.cpactions_os,
+            "cpactions-version": self.cpactions_version,
+            "cpactions-arch": self.cpactions_arch,
+            "cpactions-setup-cmd": self.cpactions_setup_cmd,
+            "cpactions-install-cmd": self.cpactions_install_cmd,
+            "setup-vita-gles-type": self.setup_vita_gles_type,
+            "setup-gdk-folder": self.setup_gdk_folder,
+            "check-sources": self.check_sources,
+            "watcom-makefile": self.watcom_makefile,
+        }
+        return {k: v for k, v in data.items() if v != ""}
+
+
+def my_shlex_join(s):
+    def escape(s):
+        if s[:1] == "'" and s[-1:] == "'":
+            return s
+        if set(s).intersection(set("; \t")):
+            s = s.replace("\\", "\\\\").replace("\"", "\\\"")
+            return f'"{s}"'
+        return s
+
+    return " ".join(escape(e) for e in s)
+
+
+def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDetails:
+    job = JobDetails(
+        name=spec.name,
+        key=key,
+        os=spec.os.value,
+        artifact=spec.artifact or "",
+        container=spec.container or "",
+        platform=spec.platform.value,
+        sudo="sudo",
+        no_autotools=not spec.autotools,
+        no_cmake=spec.no_cmake,
+    )
+    if job.os.startswith("ubuntu"):
+        job.apt_packages.extend([
+            "ninja-build",
+            "pkg-config",
+        ])
+    if spec.msvc_static_crt:
+        job.cmake_arguments.append("-DSDL_FORCE_STATIC_VCRT=ON")
+    pretest_cmd = []
+    if trackmem_symbol_names:
+        pretest_cmd.append("export SDL_TRACKMEM_SYMBOL_NAMES=1")
+    else:
+        pretest_cmd.append("export SDL_TRACKMEM_SYMBOL_NAMES=0")
+    win32 = spec.platform in (SdlPlatform.Msys2, SdlPlatform.Msvc)
+    fpic = None
+    build_parallel = True
+    if spec.lean:
+        job.cppflags.append("-DSDL_LEAN_AND_MEAN=1")
+    if win32:
+        job.cmake_arguments.append("-DSDLTEST_PROCDUMP=ON")
+        job.minidump = True
+    if spec.intel is not None:
+        match spec.intel:
+            case IntelCompiler.Icx:
+                job.cc = "icx"
+                job.cxx = "icpx"
+            case IntelCompiler.Icc:
+                job.cc = "icc"
+                job.cxx = "icpc"
+                job.cppflags.append("-diag-disable=10441")
+            case _:
+                raise ValueError(f"Invalid intel={spec.intel}")
+        job.source_cmd = f"source /opt/intel/oneapi/setvars.sh;"
+        job.intel = True
+        job.shell = "bash"
+        job.cmake_arguments.extend((
+            f"-DCMAKE_C_COMPILER={job.cc}",
+            f"-DCMAKE_CXX_COMPILER={job.cxx}",
+            "-DCMAKE_SYSTEM_NAME=Linux",
+        ))
+    match spec.platform:
+        case SdlPlatform.Msvc:
+            job.setup_ninja = not spec.gdk
+            job.msvc_project = spec.msvc_project if spec.msvc_project else ""
+            job.msvc_project_flags.append("-p:TreatWarningsAsError=true")
+            job.test_pkg_config = False
+            job.shared_lib = SharedLibType.WIN32
+            job.static_lib = StaticLibType.MSVC
+            job.cmake_arguments.extend((
+                "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase",
+                "-DCMAKE_EXE_LINKER_FLAGS=-DEBUG",
+                "-DCMAKE_SHARED_LINKER_FLAGS=-DEBUG",
+            ))
+            if spec.uwp:
+                job.cmake_arguments.append("'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>DLL'")
+            else:
+                job.cmake_arguments.append("'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>'")
+
+            if spec.clang_cl:
+                job.cmake_arguments.extend((
+                    "-DCMAKE_C_COMPILER=clang-cl",
+                    "-DCMAKE_CXX_COMPILER=clang-cl",
+                ))
+                match spec.msvc_arch:
+                    case MsvcArch.X86:
+                        job.cflags.append("/clang:-m32")
+                        job.ldflags.append("/MACHINE:X86")
+                    case MsvcArch.X64:
+                        job.cflags.append("/clang:-m64")
+                        job.ldflags.append("/MACHINE:X64")
+                    case _:
+                        raise ValueError(f"Unsupported clang-cl architecture (arch={spec.msvc_arch})")
+            if spec.msvc_project:
+                match spec.msvc_arch:
+                    case MsvcArch.X86:
+                        msvc_platform = "Win32"
+                    case MsvcArch.X64:
+                        msvc_platform = "x64"
+                    case _:
+                        raise ValueError(f"Unsupported vcxproj architecture (arch={spec.msvc_arch})")
+                if spec.gdk:
+                    msvc_platform = f"Gaming.Desktop.{msvc_platform}"
+                job.msvc_project_flags.append(f"-p:Platform={msvc_platform}")
+            match spec.msvc_arch:
+                case MsvcArch.X86:
+                    job.msvc_vcvars_arch = "x64_x86"
+                case MsvcArch.X64:
+                    job.msvc_vcvars_arch = "x64"
+                case MsvcArch.Arm32:
+                    job.msvc_vcvars_arch = "x64_arm"
+                    job.msvc_vcvars_sdk = "10.0.22621.0"  # 10.0.26100.0 dropped ARM32 um and ucrt libraries
+                    job.run_tests = False
+                case MsvcArch.Arm64:
+                    job.msvc_vcvars_arch = "x64_arm64"
+                    job.run_tests = False
+            if spec.uwp:
+                job.build_tests = False
+                job.cmake_arguments.extend((
+                    "-DCMAKE_SYSTEM_NAME=WindowsStore",
+                    "-DCMAKE_SYSTEM_VERSION=10.0",
+                ))
+                job.msvc_project_flags.append("-p:WindowsTargetPlatformVersion=10.0.17763.0")
+            elif spec.gdk:
+                job.setup_gdk_folder = "VisualC-GDK"
+            else:
+                match spec.msvc_arch:
+                    case MsvcArch.X86:
+                        job.setup_libusb_arch = "x86"
+                    case MsvcArch.X64:
+                        job.setup_libusb_arch = "x64"
+        case SdlPlatform.Linux:
+            if spec.name.startswith("Ubuntu"):
+                assert spec.os.value.startswith("ubuntu-")
+                job.apt_packages.extend((
+                    "gnome-desktop-testing",
+                    "libasound2-dev",
+                    "libpulse-dev",
+                    "libaudio-dev",
+                    "libjack-dev",
+                    "libsndio-dev",
+                    "libusb-1.0-0-dev",
+                    "libx11-dev",
+                    "libxext-dev",
+                    "libxrandr-dev",
+                    "libxcursor-dev",
+                    "libxfixes-dev",
+                    "libxi-dev",
+                    "libxss-dev",
+                    "libwayland-dev",
+                    "libxkbcommon-dev",
+                    "libdrm-dev",
+                    "libgbm-dev",
+                    "libgl1-mesa-dev",
+                    "libgles2-mesa-dev",
+                    "libegl1-mesa-dev",
+                    "libdbus-1-dev",
+                    "libibus-1.0-dev",
+                    "libudev-dev",
+                    "fcitx-libs-dev",
+                ))
+                ubuntu_year, ubuntu_month = [int(v) for v in spec.os.value.removeprefix("ubuntu-").split(".", 1)]
+                if ubuntu_year >= 22:
+                    job.apt_packages.extend(("libpipewire-0.3-dev", "libdecor-0-dev"))
+                job.apt_packages.extend((
+                    "libunwind-dev",  # For SDL_test memory tracking
+                ))
+            if trackmem_symbol_names:
+                # older libunwind is slow
+                job.cmake_arguments.append("-DSDLTEST_TIMEOUT_MULTIPLIER=2")
+            job.shared_lib = SharedLibType.SO_0
+            job.static_lib = StaticLibType.A
+            fpic = True
+        case SdlPlatform.Ios | SdlPlatform.Tvos:
+            job.brew_packages.extend([
+                "ninja",
+            ])
+            job.run_tests = False
+            job.test_pkg_config = False
+            job.shared_lib = SharedLibType.DYLIB
+            job.static_lib = StaticLibType.A
+            match spec.platform:
+                case SdlPlatform.Ios:
+                    if spec.xcode:
+                        job.xcode_sdk = "iphoneos"
+                        job.xcode_target = "Static Library-iOS"
+                    job.cmake_arguments.extend([
+                        "-DCMAKE_SYSTEM_NAME=iOS",
+                        "-DCMAKE_OSX_ARCHITECTURES=\"arm64\"",
+                        "-DCMAKE_OSX_DEPLOYMENT_TARGET=9.0",
+                    ])
+                case SdlPlatform.Tvos:
+                    if spec.xcode:
+                        job.xcode_sdk = "appletvos"
+                        job.xcode_target = "Static Library-tvOS"
+                    job.cmake_arguments.extend([
+                        "-DCMAKE_SYSTEM_NAME=tvOS",
+                        "-DCMAKE_OSX_ARCHITECTURES=\"arm64\"",
+                        "-DCMAKE_OSX_DEPLOYMENT_TARGET=9.0",
+                    ])
+        case SdlPlatform.MacOS:
+            osx_arch = ";".join(e.value for e in spec.apple_archs) if spec.apple_archs else "arm64"
+            job.cmake_arguments.extend((
+                f"'-DCMAKE_OSX_ARCHITECTURES={osx_arch}'",
+                "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.11",
+            ))
+            job.build_autotools_tests = False
+            job.shared_lib = SharedLibType.DYLIB
+            job.static_lib = StaticLibType.A
+            job.apt_packages = []
+            job.brew_packages.extend((
+                "autoconf",
+                "ninja",
+            ))
+            if spec.xcode:
+                job.xcode_sdk = "macosx"
+        case SdlPlatform.Android:
+            job.android_mk = spec.android_mk
+            job.run_tests = False
+            job.shared_lib = SharedLibType.SO
+            job.static_lib = StaticLibType.A
+            if spec.android_mk or not spec.no_cmake:
+                job.android_ndk = True
+            if spec.android_mk:
+                job.apt_packages = []
+            if not spec.no_cmake:
+                job.cmake_arguments.extend((
+                    f"-DANDROID_PLATFORM={spec.android_platform}",
+                    f"-DANDROID_ABI={spec.android_abi}",
+                ))
+                job.cmake_toolchain_file = "${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake"
+                job.cc = f"${{ANDROID_NDK_HOME}}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target={spec.android_arch}-none-linux-androideabi{spec.android_platform}"
+
+                job.android_apks = [
+                    "testaudiorecording-apk",
+                    "testautomation-apk",
+                    "testcontroller-apk",
+                    "testmultiaudio-apk",
+                    "testsprite-apk",
+                ]
+        case SdlPlatform.Emscripten:
+            job.run_tests = False
+            job.shared = False
+            job.cmake_config_emulator = "emcmake"
+            job.cmake_build_type = "Debug"
+            job.test_pkg_config = False
+            job.cmake_arguments.extend((
+                "-DSDLTEST_BROWSER=chrome",
+                "-DSDLTEST_TIMEOUT_MULTIPLIER=4",
+                "-DSDLTEST_CHROME_BINARY=${CHROME_BINARY}",
+            ))
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Ps2:
+            build_parallel = False
+            job.shared = False
+            job.sudo = ""
+            job.apt_packages = []
+            job.apk_packages = ["cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", "git", ]
+            job.cmake_toolchain_file = "${PS2DEV}/ps2sdk/ps2dev.cmake"
+            job.run_tests = False
+            job.shared = False
+            job.cc = "mips64r5900el-ps2-elf-gcc"
+            job.ldflags = ["-L${PS2DEV}/ps2sdk/ee/lib", "-L${PS2DEV}/gsKit/lib", "-L${PS2DEV}/ps2sdk/ports/lib", ]
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Psp:
+            build_parallel = False
+            job.sudo = ""
+            job.apt_packages = []
+            job.apk_packages = ["cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", ]
+            job.cmake_toolchain_file = "${PSPDEV}/psp/share/pspdev.cmake"
+            job.run_tests = False
+            job.shared = False
+            job.cc = "psp-gcc"
+            job.ldflags = ["-L${PSPDEV}/lib", "-L${PSPDEV}/psp/lib", "-L${PSPDEV}/psp/sdk/lib", ]
+            job.pollute_directories = ["${PSPDEV}/include", "${PSPDEV}/psp/include", "${PSPDEV}/psp/sdk/include", ]
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Vita:
+            job.sudo = ""
+            job.apt_packages = []
+            job.apk_packages = ["cmake", "ninja", "pkgconf", "bash", "tar"]
+            job.cmake_toolchain_file = "${VITASDK}/share/vita.toolchain.cmake"
+            assert spec.vita_gles is not None
+            job.setup_vita_gles_type = {
+                VitaGLES.Pib: "pib",
+                VitaGLES.Pvr: "pvr",
+            }[spec.vita_gles]
+            job.cmake_arguments.extend((
+                f"-DVIDEO_VITA_PIB={ 'true' if spec.vita_gles == VitaGLES.Pib else 'false' }",
+                f"-DVIDEO_VITA_PVR={ 'true' if spec.vita_gles == VitaGLES.Pvr else 'false' }",
+                "-DSDL_ARMNEON=ON",
+                "-DSDL_ARMSIMD=ON",
+                ))
+            # Fix vita.toolchain.cmake (https://github.com/vitasdk/vita-toolchain/pull/253)
+            job.source_cmd = r"""sed -i -E "s#set\\( PKG_CONFIG_EXECUTABLE \"\\$\\{VITASDK}/bin/arm-vita-eabi-pkg-config\" \\)#set\\( PKG_CONFIG_EXECUTABLE \"${VITASDK}/bin/arm-vita-eabi-pkg-config\" CACHE PATH \"Path of pkg-config executable\" \\)#" ${VITASDK}/share/vita.toolchain.cmake"""
+            job.run_tests = False
+            job.shared = False
+            job.cc = "arm-vita-eabi-gcc"
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Haiku:
+            fpic = False
+            job.build_autotools_tests = False
+            job.run_tests = False
+            job.cc = "x86_64-unknown-haiku-gcc"
+            job.cxx = "x86_64-unknown-haiku-g++"
+            job.sudo = ""
+            job.cmake_arguments.extend((
+                f"-DCMAKE_C_COMPILER={job.cc}",
+                f"-DCMAKE_CXX_COMPILER={job.cxx}",
+                "-DSDL_UNIX_CONSOLE_BUILD=ON",
+            ))
+            job.shared_lib = SharedLibType.SO_0
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.N3ds:
+            job.shared = False
+            job.apt_packages = ["ninja-build", "binutils"]
+            job.run_tests = False
+            job.cc_from_cmake = True
+            job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake"
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Msys2:
+            job.shell = "msys2 {0}"
+            assert spec.msys2_platform
+            job.msys2_msystem = spec.msys2_platform.value
+            job.msys2_env = {
+                "mingw32": "mingw-w64-i686",
+                "mingw64": "mingw-w64-x86_64",
+                "clang32": "mingw-w64-clang-i686",
+                "clang64": "mingw-w64-clang-x86_64",
+                "ucrt64": "mingw-w64-ucrt-x86_64",
+            }[spec.msys2_platform.value]
+            job.msys2_no_perl = spec.msys2_platform in (Msys2Platform.Mingw32, Msys2Platform.Clang32)
+            job.shared_lib = SharedLibType.WIN32
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.Riscos:
+            # FIXME: Enable SDL_WERROR
+            job.werror = False
+            job.build_autotools_tests = False
+            job.apt_packages = ["cmake", "ninja-build"]
+            job.test_pkg_config = False
+            job.shared = False
+            job.run_tests = False
+            job.sudo = ""
+            job.cmake_arguments.extend((
+                "-DRISCOS:BOOL=ON",
+                "-DCMAKE_DISABLE_PRECOMPILE_HEADERS:BOOL=ON",
+                "-DSDL_GCC_ATOMICS:BOOL=OFF",
+            ))
+            job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake"
+            job.static_lib = StaticLibType.A
+        case SdlPlatform.FreeBSD | SdlPlatform.NetBSD:
+            job.build_autotools_tests = False
+            job.cpactions = True
+            job.no_cmake = True
+            job.run_tests = False
+            job.apt_packages = []
+            job.shared_lib = SharedLibType.SO_0
+            job.static_lib = StaticLibType.A
+            match spec.platform:
+                case SdlPlatform.FreeBSD:
+                    job.cpactions_os = "freebsd"
+                    job.cpactions_version = "13.3"
+                    job.cpactions_arch = "x86-64"
+                    job.cpactions_setup_cmd = "sudo pkg update"
+                    job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
+                    job.cmake_arguments.extend((
+                        "-DSDL_CHECK_REQUIRED_INCLUDES=/usr/local/include",
+                        "-DSDL_CHECK_REQUIRED_LINK_OPTIONS=-L/usr/local/lib",
+                    ))
+                case SdlPlatform.NetBSD:
+                    job.cpactions_os = "netbsd"
+                    job.cpactions_version = "10.0"
+                    job.cpactions_arch = "x86-64"
+                    job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
+                    job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
+        case SdlPlatform.Watcom:
+            match spec.watcom_platform:
+                case WatcomPlatform.OS2:
+                    job.watcom_makefile = "Makefile.os2"
+                    job.run_tests = False
+                case WatcomPlatform.Windows:
+                    job.watcom_makefile = "Makefile.w32"
+                    job.run_tests = True
+                case _:
+                    raise ValueError(f"Unsupported watcom_platform=${spec.watcom_platform}")
+        case _:
+            raise ValueError(f"Unsupported platform={spec.platform}")
+
+    if "ubuntu" in spec.name.lower():
+        job.check_sources = True
+
+    if not build_parallel:
+        job.cmake_build_arguments.append("-j1")
+    if job.cflags:
+        job.cmake_arguments.append(f"-DCMAKE_C_FLAGS={my_shlex_join(job.cflags)}")
+    if job.cxxflags:
+        job.cmake_arguments.append(f"-DCMAKE_CXX_FLAGS={my_shlex_join(job.cxxflags)}")
+    if job.ldflags:
+        job.cmake_arguments.append(f"-DCMAKE_SHARED_LINKER_FLAGS={my_shlex_join(job.ldflags)}")
+        job.cmake_arguments.append(f"-DCMAKE_EXE_LINKER_FLAGS={my_shlex_join(job.ldflags)}")
+    job.pretest_cmd = "\n".join(pretest_cmd)
+    def tf(b):
+        return "ON" if b else "OFF"
+
+    if fpic is not None:
+        job.cmake_arguments.append(f"-DCMAKE_POSITION_INDEPENDENT_CODE={tf(fpic)}")
+
+    if job.no_cmake:
+        job.cmake_arguments = []
+
+    return job
+
+
+def spec_to_platform(spec: JobSpec, key: str, enable_artifacts: bool, trackmem_symbol_names: bool) -> dict[str, str|bool]:
+    logger.info("spec=%r", spec)
+    job = spec_to_job(spec, key=key, trackmem_symbol_names=trackmem_symbol_names)
+    logger.info("job=%r", job)
+    platform = job.to_workflow(enable_artifacts=enable_artifacts)
+    logger.info("platform=%r", platform)
+    return platform
+
+
+def main():
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument("--github-variable-prefix", default="platforms")
+    parser.add_argument("--github-ci", action="store_true")
+    parser.add_argument("--verbose", action="store_true")
+    parser.add_argument("--commit-message-file")
+    parser.add_argument("--no-artifact", dest="enable_artifacts", action="store_false")
+    parser.add_argument("--trackmem-symbol-names", dest="trackmem_symbol_names", action="store_true")
+    args = parser.parse_args()
+
+    logging.basicConfig(level=logging.INFO if args.verbose else logging.WARNING)
+
+    remaining_keys = set(JOB_SPECS.keys())
+
+    all_level_keys = (
+        # Level 1
+        (
+            "haiku",
+        ),
+    )
+
+    filters = []
+    if args.commit_message_file:
+        with open(args.commit_message_file, "r") as f:
+            commit_message = f.read()
+            for m in re.finditer(r"\[sdl-ci-filter (.*)]", commit_message, flags=re.M):
+                filters.append(m.group(1).strip(" \t\n\r\t'\""))
+
+            if re.search(r"\[sdl-ci-artifacts?]", commit_message, flags=re.M):
+                args.enable_artifacts = True
+
+            if re.search(r"\[sdl-ci-(full-)?trackmem(-symbol-names)?]", commit_message, flags=re.M):
+                args.trackmem_symbol_names = True
+
+    if not filters:
+        filters.append("*")
+
+    logger.info("filters: %r", filters)
+
+    all_level_platforms = {}
+
+    all_platforms = {key: spec_to_platform(spec, key=key, enable_artifacts=args.enable_artifacts, trackmem_symbol_names=args.trackmem_symbol_names) for key, spec in JOB_SPECS.items()}
+
+    for level_i, level_keys in enumerate(all_level_keys, 1):
+        level_key = f"level{level_i}"
+        logger.info("Level %d: keys=%r", level_i, level_keys)
+        assert all(k in remaining_keys for k in level_keys)
+        level_platforms = tuple(all_platforms[key] for key in level_keys)
+        remaining_keys.difference_update(level_keys)
+        all_level_platforms[level_key] = level_platforms
+        logger.info("=" * 80)
+
+    logger.info("Keys before filter: %r", remaining_keys)
+
+    filtered_remaining_keys = set()
+    for filter in filters:
+        filtered_remaining_keys.update(fnmatch.filter(remaining_keys, filter))
+
+    logger.info("Keys after filter: %r", filtered_remaining_keys)
+
+    remaining_keys = filtered_remaining_keys
+
+    logger.info("Remaining: %r", remaining_keys)
+    all_level_platforms["others"] = tuple(all_platforms[key] for key in remaining_keys)
+
+    if args.github_ci:
+        for level, platforms in all_level_platforms.items():
+            platforms_json = json.dumps(platforms)
+            txt = f"{args.github_variable_prefix}-{level}={platforms_json}"
+            logger.info("%s", txt)
+            if "GITHUB_OUTPUT" in os.environ:
+                with open(os.environ["GITHUB_OUTPUT"], "a") as f:
+                    f.write(txt)
+                    f.write("\n")
+            else:
+                logger.warning("GITHUB_OUTPUT not defined")
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 0 - 45
.github/workflows/emscripten.yml

@@ -1,45 +0,0 @@
-name: Build (Emscripten)
-
-on: [push, pull_request]
-
-jobs:
-  emscripten:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: mymindstorm/setup-emsdk@v14
-        with:
-          version: 3.1.35
-      - name: Install ninja
-        run: |
-          sudo apt-get -y update
-          sudo apt-get install -y ninja-build
-      - name: Configure CMake
-        run: |
-          emcmake cmake -S . -B build \
-            -DSDL_WERROR=ON \
-            -DSDL_TESTS=ON \
-            -DSDL_INSTALL_TESTS=ON \
-            -DCMAKE_BUILD_TYPE=Release \
-            -DCMAKE_INSTALL_PREFIX=prefix \
-            -GNinja
-      - name: Build
-        run: cmake --build build/ --verbose
-      - name: Run build-time tests
-        run: |
-          set -eu
-          export SDL_TESTS_QUICK=1
-          # FIXME: enable Emscripten build time tests
-          # ctest -VV --test-dir build/
-      - name: Install
-        run: |
-          echo "SDL2_DIR=$(pwd)/prefix" >> $GITHUB_ENV
-          cmake --install build/
-      - name: Verify CMake configuration files
-        run: |
-          emcmake cmake -S cmake/test -B cmake_config_build \
-            -DCMAKE_BUILD_TYPE=Release \
-            -DSDL_VENDOR_INFO="Github Workflow" \
-            -DTEST_SHARED=FALSE \
-            -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }}
-          cmake --build cmake_config_build --verbose

+ 352 - 0
.github/workflows/generic.yml

@@ -0,0 +1,352 @@
+name: 'Build'
+run-name: 'Configure, Build and Test SDL'
+
+on:
+  workflow_call:
+    inputs:
+      platforms:
+        description: 'JSON-encoded test properties'
+        type: string
+        required: true
+
+jobs:
+  build:
+    name: ${{ matrix.platform.name }}
+    runs-on: ${{ matrix.platform.os }}
+    container: ${{ matrix.platform.container }}
+    defaults:
+      run:
+        shell: ${{ matrix.platform.shell }}
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: ${{ fromJSON(inputs.platforms) }}
+    steps:
+      - name: 'Set up MSYS2'
+        if: ${{ matrix.platform.platform == 'msys2' }}
+        uses: msys2/setup-msys2@v2
+        with:
+          msystem: ${{ matrix.platform.msys2-msystem }}
+          install: >-
+            ${{ matrix.platform.msys2-env }}-cc
+            ${{ matrix.platform.msys2-env }}-cmake
+            ${{ matrix.platform.msys2-env }}-ninja
+            ${{ (!matrix.platform.msys2-no-perl && format('{0}-perl', matrix.platform.msys2-env)) || '' }}
+            ${{ matrix.platform.msys2-env }}-pkg-config
+            ${{ matrix.platform.msys2-env }}-clang-tools-extra
+      - name: 'About this job'
+        run: |
+          echo "key=${{ matrix.platform.key }}"
+          echo "name=${{ matrix.platform.name }}"
+          echo "os=${{ matrix.platform.os }}"
+          echo ""
+          echo "Add [sdl-ci-filter ${{ matrix.platform.key }}] to your commit message to reduce the number of jobs."
+      - uses: actions/checkout@v4
+      - name: 'Set up ninja'
+        if: ${{ matrix.platform.setup-ninja }}
+        uses: ./.github/actions/setup-ninja
+      - uses: mymindstorm/setup-emsdk@v14
+        if: ${{ matrix.platform.platform == 'emscripten' }}
+        with:
+          version: 3.1.35
+      - uses: nttld/setup-ndk@v1
+        if: ${{ matrix.platform.android-ndk }}
+        id: setup-ndk
+        with:
+          local-cache: true
+          ndk-version: r21e
+      - uses: ilammy/msvc-dev-cmd@v1
+        if: ${{ matrix.platform.platform == 'msvc' }}
+        with:
+          arch: ${{ matrix.platform.msvc-vcvars-arch }}
+          sdk: ${{ matrix.platform.msvc-vcvars-sdk }}
+      - name: 'Set up Windows GDK Desktop'
+        uses: ./.github/actions/setup-gdk-desktop
+        if: ${{ matrix.platform.setup-gdk-folder != '' }}
+        with:
+          folder: '${{ matrix.platform.setup-gdk-folder }}'
+      - name: 'Setup Intel oneAPI toolchain'
+        id: intel
+        if: ${{ matrix.platform.intel }}
+        run: |
+          # Download the key to system keyring
+          wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
+            | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
+          
+          # Add signed entry to apt sources and configure the APT client to use Intel repository:
+          echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
+          
+          # Update package list
+          sudo apt-get update -y
+          
+          # Install oneAPI
+          sudo apt-get install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic
+      - name: 'Install apk packages'
+        if: ${{ matrix.platform.apk-packages != '' }}
+        run: |
+          ${{ matrix.platform.sudo }} apk update
+          ${{ matrix.platform.sudo }} apk add ${{ matrix.platform.apk-packages }}
+      - name: 'Install apt packages'
+        if: ${{ matrix.platform.apt-packages != '' }}
+        run: |
+          ${{ matrix.platform.sudo }} apt-get update
+          ${{ matrix.platform.sudo }} apt-get install -y ${{ matrix.platform.apt-packages }}
+      - name: 'Install brew packages'
+        if: ${{ matrix.platform.brew-packages != '' }}
+        run: |
+          export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
+          brew update
+          brew install ${{ matrix.platform.brew-packages }}
+      - name: 'Set up GLES for VITA'  # Must be after apk
+        if: ${{ matrix.platform.setup-vita-gles-type != '' }}
+        uses: ./.github/actions/setup-vita-gles
+        with:
+          type: ${{ matrix.platform.setup-vita-gles-type }}
+
+      - name: 'Configure (Autotools)'
+        if: ${{ !matrix.platform.no-autotools }}
+        run: |
+          ${{ matrix.platform.source_cmd }}
+          set -eu
+          rm -rf build-autotools
+          mkdir build-autotools
+          ./autogen.sh
+          (
+            cd build-autotools
+            ../configure \
+              --enable-vendor-info="Github Workflow" \
+              --enable-werror \
+              --prefix=${{ github.workspace }}/autotools_prefix \
+          )
+          if test "x${{ (matrix.platform.build-autotools-tests && 'yes') || 'no' }}" = "xyes" ; then
+            curdir="$(pwd)"
+            multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
+            (
+              mkdir -p build-autotools/test
+              cd build-autotools/test
+              ../../test/configure \
+                --enable-werror \
+                --x-includes=/usr/include \
+                --x-libraries="/usr/lib/${multiarch}" \
+                --prefix=${{ github.workspace }}/autotools_prefix \
+                SDL_CFLAGS="-I${curdir}/include" \
+                SDL_LIBS="-L${curdir}/build-autotools/build/.libs -lSDL2" \
+                ac_cv_lib_SDL2_ttf_TTF_Init=no \
+                ${NULL+}
+          )
+          fi
+      - name: 'Build (Autotools)'
+        if: ${{ !matrix.platform.no-autotools }}
+        run: |
+          ${{ matrix.platform.source_cmd }}
+          set -eu
+          parallel="$(getconf _NPROCESSORS_ONLN)"
+          make -j"${parallel}" -C build-autotools V=1
+          if test "x${{ (matrix.platform.build-autotools-tests && 'yes') || 'no' }}" = "xyes" ; then
+            make -j"${parallel}" -C build-autotools/test V=1
+          fi
+      - name: 'Run build-time tests (Autotools)'
+        if: ${{ !matrix.platform.no-autotools && matrix.platform.build-autotools-tests && matrix.platform.run-tests }}
+        run: |
+          ${{ matrix.platform.source_cmd }}
+          set -eu
+          curdir="$(pwd)"
+          parallel="$(getconf _NPROCESSORS_ONLN)"
+          export SDL_TESTS_QUICK=1
+          make -j"${parallel}" -C build-autotools/test check LD_LIBRARY_PATH="${curdir}/build-autotools/build/.libs"
+          if test "${{ runner.os }}" = "Linux"; then
+            # This should show us the SDL_REVISION
+            strings "${curdir}/build-autotools/build/.libs/libSDL2-2.0.so.0" | grep SDL-
+          fi
+      - name: 'Install (Autotools)'
+        if: ${{ !matrix.platform.no-autotools }}
+        run: |
+          ${{ matrix.platform.source_cmd }}
+          set -eu
+          curdir="$(pwd)"
+          parallel="$(getconf _NPROCESSORS_ONLN)"
+          make -j"${parallel}" -C build-autotools install V=1
+          if test "x${{ (matrix.platform.build-autotools-tests && 'yes') || 'no' }}" = "xyes" ; then
+            make -j"${parallel}" -C build-autotools/test install V=1
+          fi
+          ( cd autotools_prefix; find . ) | LC_ALL=C sort -u
+          echo "prefix=$(pwd)/autotools_prefix" >> $GITHUB_OUTPUT
+
+      - name: 'Configure (CMake)'
+        if: ${{ !matrix.platform.no-cmake }}
+        #shell: ${{ matrix.platform.shell }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          ${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -GNinja \
+            -Wdeprecated -Wdev -Werror \
+            ${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
+            -DSDL_WERROR=${{ matrix.platform.werror }} \
+            -DSDL_TESTS=${{ matrix.platform.build-tests }} \
+            -DSDLTEST_TRACKMEM=OFF \
+            -DSDL_INSTALL_TESTS=${{ matrix.platform.build-tests }} \
+            -DSDL_DISABLE_INSTALL_DOCS=OFF \
+            -DSDL_DISABLE_INSTALL_DOCS=OFF \
+            ${{ matrix.platform.cmake-arguments }} \
+            -DSDL_SHARED=${{ matrix.platform.shared }} \
+            -DSDL_STATIC=${{ matrix.platform.static  }} \
+            -DSDL_TEST=ON \
+            -DSDL_VENDOR_INFO="Github Workflow" \
+            -DCMAKE_INSTALL_PREFIX=prefix \
+            -DCMAKE_INSTALL_LIBDIR=lib \
+            -DSDL_CMAKE_DEBUG_POSTFIX="" \
+            -DCMAKE_BUILD_TYPE=${{ matrix.platform.cmake-build-type }}
+      - name: 'Build (CMake)'
+        id: cmake-build
+        if: ${{ !matrix.platform.no-cmake }}
+#        shell: ${{ matrix.platform.shell }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          cmake --build build --config ${{ matrix.platform.cmake-build-type }} --verbose -- ${{ matrix.platform.cmake-build-arguments }}
+      - name: 'Verify SDL_REVISION'
+        if: ${{ !matrix.platform.no-cmake }}
+        run: |
+          echo "This should show us the SDL_REVISION"
+          echo "Shared library:"
+          ${{ (matrix.platform.shared-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
+          echo "Static library:"
+          ${{ (matrix.platform.static-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
+      - name: 'Run build-time tests (CMake)'
+        id: cmake-tests
+        if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }}
+#        shell: ${{ matrix.platform.shell }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          ${{ matrix.platform.pretest-cmd }}
+          set -eu
+          export SDL_TESTS_QUICK=1
+          ctest -VV --test-dir build/ -j2
+      - name: 'Install (CMake)'
+        id: cmake-install
+        if: ${{ steps.build.outcome == 'success' }}
+#        shell: ${{ matrix.platform.shell }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          cmake --install build --config ${{ matrix.platform.cmake-build-type }}
+          echo "prefix=$(pwd)/prefix" >> $GITHUB_OUTPUT
+          ( cd prefix; find . ) | LC_ALL=C sort -u
+      - name: 'Verify CMake configuration files (CMake)'
+        if: ${{ steps.cmake-install.outcome == 'success' }}
+#        shell: ${{ matrix.platform.shell }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          ${{ matrix.platform.cmake-config-emulator }} cmake -S cmake/test -B cmake_test_build -GNinja \
+            ${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
+            -DTEST_SHARED=${{ matrix.platform.shared }} \
+            -DTEST_STATIC=${{ matrix.platform.static }} \
+            ${{ matrix.platform.cmake-arguments }} \
+            -DCMAKE_BUILD_TYPE=${{ matrix.platform.cmake-build-type }} \
+            -DCMAKE_PREFIX_PATH="${{ steps.cmake-install.outputs.prefix }}"
+          cmake --build cmake_test_build --verbose --config ${{ matrix.platform.cmake-build-type }} -- ${{ matrix.platform.cmake-build-arguments }}
+      - name: 'Extract CC/CXX/CFLAGS/CXXFLAGS from CMake toolchain'
+        if: ${{ steps.cmake-install.outcome == 'success' && matrix.platform.cc-from-cmake }}
+#        shell: ${{ matrix.platform.shell }}
+        run: |
+          cmake -S .github/cmake -B /tmp/cmake_extract \
+            ${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
+            -DCMAKE_BUILD_TYPE=${{ matrix.platform.cmake-build-type }} \
+            -DVAR_PATH=/tmp/env.txt
+          cat /tmp/env.txt >> $GITHUB_ENV
+      - name: 'Verify sdl2.pc (CMake)'
+#        shell: ${{ matrix.platform.shell }}
+        if: ${{ steps.cmake-install.outcome == 'success' && matrix.platform.test-pkg-config }}
+        run: |
+          ${{ matrix.platform.source-cmd }}
+          ${{ matrix.platform.cc && format('export CC="{0}"', matrix.platform.cc) || '' }}
+          ${{ matrix.platform.cflags && format('export CFLAGS="{0}"', matrix.platform.cflags) || '' }}
+          ${{ matrix.platform.ldflags && format('export LDFLAGS="{0}"', matrix.platform.ldflags) || '' }}
+          export PKG_CONFIG_PATH=${{ steps.cmake-install.outputs.prefix }}/lib/pkgconfig
+          cmake/test/test_pkgconfig.sh
+      - name: 'Build (cross-platform-actions, BSD)'
+        id: cpactions
+        if: ${{ matrix.platform.cpactions }}
+        uses: cross-platform-actions/action@v0.25.0
+        with:
+          operating_system: ${{ matrix.platform.cpactions-os }}
+          architecture: ${{ matrix.platform.cpactions-arch }}
+          version: ${{ matrix.platform.cpactions-version }}
+          run: |
+            ${{ matrix.platform.cpactions-setup-cmd }}
+            ${{ matrix.platform.cpactions-install-cmd }}
+            cmake -S . -B build -GNinja  \
+              ${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
+              -Wdeprecated -Wdev -Werror \
+              -DSDL_WERROR=${{ matrix.platform.werror }} \
+              -DSDL_DISABLE_INSTALL_DOCS=OFF \
+              ${{ matrix.platform.cmake-arguments }} \
+              -DSDL_SHARED=${{ matrix.platform.shared }} \
+              -DSDL_STATIC=${{ matrix.platform.static  }} \
+              -DSDL_TEST=ON \
+              -DSDL_VENDOR_INFO="Github Workflow" \
+              -DCMAKE_INSTALL_PREFIX=prefix \
+              -DCMAKE_INSTALL_LIBDIR=lib \
+              -DCMAKE_BUILD_TYPE=${{ matrix.platform.cmake-build-type }}
+            cmake --build build/ --config ${{ matrix.platform.cmake-build-type }} --verbose
+
+            cmake --build build/ --config ${{ matrix.platform.cmake-build-type }} --target clean
+            rm -rf build/CMakeFiles
+            rm -rf build/docs
+      - name: 'Set up Watcom'
+        uses: open-watcom/setup-watcom@v0
+        if: ${{ matrix.platform.watcom-makefile != '' }}
+      - name: 'Build (Watcom)'
+        if: ${{ matrix.platform.watcom-makefile != '' }}
+        run: |
+          wmake -f ${{ matrix.platform.watcom-makefile }} ENABLE_WERROR=1
+      - name: 'Build tests (Watcom)'
+        if: ${{ matrix.platform.watcom-makefile != '' }}
+        run: |
+          cd test
+          wmake -f ${{ matrix.platform.watcom-makefile }} ENABLE_WERROR=1
+      - name: 'Run tests (Watcom)'
+        if: ${{ matrix.platform.watcom-makefile != '' && matrix.platform.run-tests }}
+        run: |
+          cd test
+          wmake -f ${{ matrix.platform.watcom-makefile }} check-quick
+      - name: 'Distclean (Watcom)'
+        if: ${{ matrix.platform.watcom-makefile != '' }}
+        run: |
+          wmake -f ${{ matrix.platform.watcom-makefile }} distclean
+          cd test
+          wmake -f ${{ matrix.platform.watcom-makefile }} distclean
+      - name: 'Add msbuild to PATH'
+        id: setup-msbuild
+        if: ${{ matrix.platform.msvc-project != '' }}
+        uses: microsoft/setup-msbuild@v2
+      - name: Build msbuild
+        if: ${{ matrix.platform.msvc-project != '' }}
+        run: |
+          "$(cygpath -u '${{ steps.setup-msbuild.outputs.msbuildPath }}\msbuild.exe')" ${{ matrix.platform.msvc-project }} -m -p:BuildInParallel=true -p:Configuration=Release ${{ matrix.platform.msvc-project-flags }}
+      - name: 'Build (Android.mk)'
+        if: ${{ matrix.platform.android-mk }}
+        run: |
+          ./build-scripts/androidbuildlibs.sh
+      - name: 'Build (xcode)'
+        if: ${{ matrix.platform.xcode-sdk != '' }}
+        run: |
+          xcodebuild -project Xcode/SDL/SDL.xcodeproj -target "${{ matrix.platform.xcode-target }}" -configuration Release -sdk ${{ matrix.platform.xcode-sdk }} clean build
+      - name: 'Setup Python'
+        uses: 'actions/setup-python@main'
+        if: ${{ matrix.platform.check-sources }}
+        with:
+          python-version: '3.x'
+      - name: 'Check Sources'
+        if: ${{ matrix.platform.check-sources }}
+        run: |
+          set -e
+          build-scripts/test-versioning.sh
+      - name: 'Upload binary package'
+        uses: actions/upload-artifact@v4
+        if: ${{ always() && steps.cmake-tests.outcome == 'failure' }}
+        with:
+          if-no-files-found: ignore
+          name: '${{ matrix.platform.artifact }}-minidumps'
+          path: |
+            build/**/*.dmp
+            build/**/*.exe
+            build/**/*.dll
+            build/**/*.pdb

+ 0 - 20
.github/workflows/ios.yml

@@ -1,20 +0,0 @@
-name: Build (iOS/tvOS)
-
-on: [push, pull_request]
-
-jobs:
-  Build:
-    name: ${{ matrix.platform.name }}
-    runs-on: macos-latest
-
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-        - { name: iOS, target: Static Library-iOS, sdk: iphoneos }
-        - { name: tvOS, target: Static Library-tvOS, sdk: appletvos }
-
-    steps:
-      - uses: actions/checkout@v4
-      - name: Build
-        run: xcodebuild -project Xcode/SDL/SDL.xcodeproj -target '${{ matrix.platform.target }}' -configuration Release -sdk ${{ matrix.platform.sdk }} clean build

+ 0 - 245
.github/workflows/main.yml

@@ -1,245 +0,0 @@
-name: Build
-
-on: [push, pull_request]
-
-jobs:
-  Build:
-    name: ${{ matrix.platform.name }}
-    runs-on: ${{ matrix.platform.os }}
-
-    defaults:
-      run:
-        shell: ${{ matrix.platform.shell }}
-
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-        - { name: Windows (mingw32),              os: windows-latest, shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686 }
-        - { name: Windows (mingw64),              os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64 }
-        - { name: Windows (clang32),              os: windows-latest, shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686 }
-        - { name: Windows (clang64),              os: windows-latest, shell: 'msys2 {0}', msystem: clang64, msys-env: mingw-w64-clang-x86_64 }
-        - { name: Windows (ucrt64),               os: windows-latest, shell: 'msys2 {0}', msystem: ucrt64,  msys-env: mingw-w64-ucrt-x86_64 }
-        - { name: Ubuntu 20.04 (CMake),           os: ubuntu-20.04,   shell: sh }
-        - { name: Ubuntu 20.04 (autotools),       os: ubuntu-20.04,   shell: sh,    autotools: true }
-        - { name: Intel oneAPI (Ubuntu 20.04),    os: ubuntu-20.04,   shell: bash, artifact: 'SDL-ubuntu20.04-oneapi', intel: true,
-            source_cmd: 'source /opt/intel/oneapi/setvars.sh; export CC=icx; export CXX=icx;'}
-        - { name: Intel Compiler (Ubuntu 20.04),  os: ubuntu-20.04,   shell: bash, artifact: 'SDL-ubuntu20.04-icc', intel: true, cmake: '-DSDL_CLANG_TIDY=OFF',
-             source_cmd: 'source /opt/intel/oneapi/setvars.sh; export CC=icc; export CXX=icpc; export CFLAGS=-diag-disable=10441; export CXXFLAGS=-diag-disable=10441; '}
-
-        - { name: Ubuntu 22.04 (CMake),           os: ubuntu-22.04,   shell: sh }
-        - { name: Ubuntu 22.04 (autotools),       os: ubuntu-22.04,   shell: sh,    autotools: true }
-        - { name: iOS (CMake),                    os: macos-latest,   shell: sh,    cmake: '-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES="arm64"', cross: true, test-pkg-config: false }
-        - { name: tvOS (CMake),                    os: macos-latest,   shell: sh,    cmake: '-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_ARCHITECTURES="arm64"', cross: true, test-pkg-config: false }
-        - { name: MacOS (CMake),                  os: macos-latest,   shell: sh,    cmake: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"' }
-        - { name: MacOS (autotools),              os: macos-latest,   shell: sh,    autotools: true }
-
-    steps:
-    - name: Set up MSYS2
-      if: matrix.platform.shell == 'msys2 {0}'
-      uses: msys2/setup-msys2@v2
-      with:
-        msystem: ${{ matrix.platform.msystem }}
-        install: >-
-          ${{ matrix.platform.msys-env }}-cc
-          ${{ matrix.platform.msys-env }}-cmake
-          ${{ matrix.platform.msys-env }}-ninja
-          ${{ matrix.platform.msys-env }}-pkg-config
-
-    - name: Setup Linux dependencies
-      if: runner.os == 'Linux'
-      run: |
-        sudo apt-get update
-        sudo apt-get install build-essential git make autoconf automake libtool \
-            pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
-            libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev \
-            libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libwayland-dev \
-            libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
-            libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
-
-    - name: Setup extra Ubuntu 22.04 dependencies
-      if: matrix.platform.os == 'ubuntu-22.04'
-      run: |
-        sudo apt-get install libpipewire-0.3-dev libdecor-0-dev
-
-    - name: Setup Macos dependencies
-      if: runner.os == 'macOS'
-      run: |
-        brew install \
-          autoconf \
-          ninja
-
-    - name: Setup Intel oneAPI
-      if: matrix.platform.intel
-      run: |
-        # Download the key to system keyring
-        wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
-          | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
-
-        # Add signed entry to apt sources and configure the APT client to use Intel repository:
-        echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
-
-        # Update package list
-        sudo apt-get update -y
-
-        # Install oneAPI
-        sudo apt-get install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic
-
-    - uses: actions/checkout@v4
-    - name: Check that versioning is consistent
-      # We only need to run this once: arbitrarily use the Linux/CMake build
-      if: "runner.os == 'Linux' && ! matrix.platform.autotools"
-      run: ./build-scripts/test-versioning.sh
-    - name: Configure (CMake)
-      if: "! matrix.platform.autotools"
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        cmake -S . -B build -G Ninja \
-        -DSDL_TESTS=ON \
-        -DSDL_WERROR=ON \
-        -DSDL_INSTALL_TESTS=ON \
-        -DSDL_VENDOR_INFO="Github Workflow" \
-        -DCMAKE_INSTALL_PREFIX=cmake_prefix \
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-        ${{ matrix.platform.cmake }}
-    - name: Build (CMake)
-      if: "! matrix.platform.autotools"
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        cmake --build build/ --config RelWithDebInfo --verbose --parallel
-    - name: Run build-time tests (CMake)
-      if: ${{ ! matrix.platform.autotools && !matrix.platform.cross }}
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        export SDL_TESTS_QUICK=1
-        ctest -VV --test-dir build/ -j2
-        if test "${{ runner.os }}" = "Linux"; then
-          # This should show us the SDL_REVISION
-          strings build/libSDL2-2.0.so.0 | grep SDL-
-        fi
-    - name: Install (CMake)
-      if: "! matrix.platform.autotools"
-      run: |
-        set -eu
-        cmake --install build/ --config RelWithDebInfo
-        echo "SDL2_DIR=$(pwd)/cmake_prefix" >> $GITHUB_ENV
-        ( cd cmake_prefix; find ) | LC_ALL=C sort -u
-    - name: Configure (Autotools)
-      if: matrix.platform.autotools
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        rm -fr build-autotools
-        mkdir build-autotools
-        ./autogen.sh
-        (
-          cd build-autotools
-          ${{ github.workspace }}/configure \
-            --enable-vendor-info="Github Workflow" \
-            --enable-werror \
-            --prefix=${{ github.workspace }}/autotools_prefix \
-        )
-        if test "${{ runner.os }}" != "macOS" ; then
-          curdir="$(pwd)"
-          multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
-          (
-            mkdir -p build-autotools/test
-            cd build-autotools/test
-            ${{ github.workspace }}/test/configure \
-              --enable-werror \
-              --x-includes=/usr/include \
-              --x-libraries="/usr/lib/${multiarch}" \
-              --prefix=${{ github.workspace }}/autotools_prefix \
-              SDL_CFLAGS="-I${curdir}/include" \
-              SDL_LIBS="-L${curdir}/build-autotools/build/.libs -lSDL2" \
-              ac_cv_lib_SDL2_ttf_TTF_Init=no \
-              ${NULL+}
-          )
-        fi
-    - name: Build (Autotools)
-      if: matrix.platform.autotools
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        parallel="$(getconf _NPROCESSORS_ONLN)"
-        make -j"${parallel}" -C build-autotools V=1
-        if test "${{ runner.os }}" != "macOS" ; then
-          make -j"${parallel}" -C build-autotools/test V=1
-        fi
-    - name: Run build-time tests (Autotools)
-      if: ${{ matrix.platform.autotools && (runner.os != 'macOS') }}
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        curdir="$(pwd)"
-        parallel="$(getconf _NPROCESSORS_ONLN)"
-        export SDL_TESTS_QUICK=1
-        make -j"${parallel}" -C build-autotools/test check LD_LIBRARY_PATH="${curdir}/build-autotools/build/.libs"
-        if test "${{ runner.os }}" = "Linux"; then
-          # This should show us the SDL_REVISION
-          strings "${curdir}/build-autotools/build/.libs/libSDL2-2.0.so.0" | grep SDL-
-        fi
-    - name: Install (Autotools)
-      if: matrix.platform.autotools
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        curdir="$(pwd)"
-        parallel="$(getconf _NPROCESSORS_ONLN)"
-        make -j"${parallel}" -C build-autotools install V=1
-        if test "${{ runner.os }}" != "macOS" ; then
-          make -j"${parallel}" -C build-autotools/test install V=1
-        fi
-        ( cd autotools_prefix; find . ) | LC_ALL=C sort -u
-        echo "SDL2_DIR=$(pwd)/autotools_prefix" >> $GITHUB_ENV
-    - name: Verify CMake configuration files
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        cmake -S cmake/test -B cmake_config_build -G Ninja \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-          ${{ matrix.platform.cmake }} \
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }}
-        cmake --build cmake_config_build --verbose
-    - name: Verify sdl2-config
-      if: ${{ !!matrix.platform.test-pkg-config }}
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-        cmake/test/test_sdlconfig.sh
-    - name: Verify sdl2.pc
-      if: ${{ !!matrix.platform.test-pkg-config }}
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-        cmake/test/test_pkgconfig.sh
-    - name: Distcheck (Autotools)
-      if: matrix.platform.autotools
-      run: |
-        set -eu
-        parallel="$(getconf _NPROCESSORS_ONLN)"
-        make -j"${parallel}" -C build-autotools dist V=1
-        # Similar to Automake `make distcheck`: check that the tarball
-        # release is sufficient to do a new build
-        mkdir distcheck
-        tar -C distcheck -zxf build-autotools/SDL2-*.tar.gz
-        ( cd distcheck/SDL2-* && ./configure )
-        make -j"${parallel}" -C distcheck/SDL2-*
-    - name: Run installed-tests (Autotools)
-      if: "runner.os == 'Linux' && matrix.platform.autotools"
-      run: |
-        ${{ matrix.platform.source_cmd }}
-        set -eu
-        parallel="$(getconf _NPROCESSORS_ONLN)"
-        sudo make -j"${parallel}" -C build-autotools install
-        sudo make -j"${parallel}" -C build-autotools/test install
-        export SDL_TESTS_QUICK=1
-        # We need to set LD_LIBRARY_PATH because it isn't in the default
-        # linker search path. We don't need to set XDG_DATA_DIRS for
-        # ginsttest-runner, because /usr/local/share *is* in the default
-        # search path for that.
-        env --chdir=/ \
-            LD_LIBRARY_PATH=/usr/local/lib \
-            SDL_AUDIODRIVER=dummy \
-            SDL_VIDEODRIVER=dummy \
-            ginsttest-runner --tap SDL2

+ 0 - 127
.github/workflows/msvc.yml

@@ -1,127 +0,0 @@
-name: Build (MSVC)
-
-on: [push, pull_request]
-
-jobs:
-  Build:
-    name: ${{ matrix.platform.name }}
-    runs-on: windows-latest
-
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-        - { name: 'Windows (x64)',                vcvars-arch: 'x64',        artifact: 'SDL-VC-x64',         project: 'VisualC/SDL.sln', projectflags: '/p:Platform=x64', }
-        - { name: 'Windows (x86)',                vcvars-arch: 'x64_x86',    artifact: 'SDL-VC-x86',         project: 'VisualC/SDL.sln', projectflags: '/p:Platform=Win32', }
-        - { name: 'Windows static VCRT (x64)',    vcvars-arch: 'x64',        artifact: 'SDL-static-crt-x64', cmake-args: '-DSDL_FORCE_STATIC_VCRT=ON', }
-        - { name: 'Windows static VCRT (x86)',    vcvars-arch: 'x64_x86',    artifact: 'SDL-static-crt-x86', cmake-args: '-DSDL_FORCE_STATIC_VCRT=ON', }
-        - { name: 'Windows (clang-cl x64)',       vcvars-arch: 'x64',        artifact: 'SDL-clang-cl-x64',   cmake-args: '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl', cppflags: '/clang:-m64', ldflags: '/MACHINE:X64',  }
-        - { name: 'Windows (clang-cl x86)',       vcvars-arch: 'x86',        artifact: 'SDL-clang-cl-x86',   cmake-args: '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl', cppflags: '/clang:-m32', ldflags: '/MACHINE:X86', }
-        - { name: 'Windows (ARM)',                vcvars-arch: 'x64_arm',    artifact: 'SDL-VC-arm32',       vcvars-sdk: '10.0.22621.0'}
-        - { name: 'Windows (ARM64)',              vcvars-arch: 'x64_arm64',  artifact: 'SDL-VC-arm64', }
-        - { name: 'UWP (x64)',                    vcvars-arch: 'x64',        artifact: 'SDL-VC-UWP',         cmake-args: '-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DSDL_TESTS=OFF',
-            project: 'VisualC-WinRT/SDL-UWP.sln', projectflags: '/p:Platform=x64 /p:WindowsTargetPlatformVersion=10.0.17763.0', }
-        - { name: 'GDK (x64)',                    vcvars-arch: 'x64',        artifact: '',                   no-cmake: true, gdk: true,
-            project: 'VisualC-GDK/SDL.sln', projectflags: '/p:Platform=Gaming.Desktop.x64', }
-
-    steps:
-    - uses: actions/checkout@v4
-    - name: Set up ninja
-      if: ${{ !matrix.platform.no-cmake }}
-      uses: ./.github/actions/setup-ninja
-    - uses: ilammy/msvc-dev-cmd@v1
-      with:
-        arch: ${{ matrix.platform.vcvars-arch }}
-        sdk: ${{ matrix.platform.vcvars-sdk }}
-
-    - name: 'Set up Windows GDK Desktop'
-      uses: ./.github/actions/setup-gdk-desktop
-      if: ${{ matrix.platform.gdk }}
-      with:
-        folder: '${{ github.workspace }}/VisualC-GDK'
-    - name: Create CMake project using SDL as a subproject
-      shell: python
-      if: ${{ !matrix.platform.no-cmake }}
-      run: |
-        import os
-        import textwrap
-        srcdir = r"${{ github.workspace }}".replace("\\", "/")
-        builddir = f"{ srcdir }/build"
-        os.makedirs(builddir)
-        with open(f"{ builddir }/CMakeLists.txt", "w") as f:
-          f.write(textwrap.dedent(f"""\
-            # Always build .PDB symbol file
-            set(CMAKE_POLICY_DEFAULT_CMP0141 "NEW" CACHE STRING "MSVC debug information format flags are selected by an abstraction")
-            set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "ProgramDatabase" CACHE STRING "MSVC debug information format")
-            set(CMAKE_EXE_LINKER_FLAGS "-DEBUG" CACHE STRING "Linker flags for executables")
-            set(CMAKE_SHARED_LINKER_FLAGS "-DEBUG" CACHE STRING "Linker flag for shared libraries")
-            cmake_minimum_required(VERSION 3.0...3.25)
-            project(sdl_user)
-            enable_testing()
-            add_subdirectory("{ srcdir }" SDL)
-          """))
-    - name: Configure (CMake)
-      id: cmake-configure
-      if: ${{ !matrix.platform.no-cmake }}
-      run: cmake -S build -B build -GNinja `
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo `
-        -DSDL_WERROR=ON `
-        -DSDL_TESTS=ON `
-        -DCMAKE_C_FLAGS="${{ matrix.platform.cppflags }}" `
-        -DCMAKE_CXX_FLAGS="${{ matrix.platform.cppflags }}" `
-        -DCMAKE_EXE_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-        -DCMAKE_SHARED_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-        -DCMAKE_STATIC_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-        -DSDL_INSTALL_TESTS=ON `
-        -DSDL_VENDOR_INFO="Github Workflow" `
-        -DSDL2_DISABLE_INSTALL=OFF `
-        -DSDLTEST_PROCDUMP=ON `
-        ${{ matrix.platform.cmake-args }} `
-        -DCMAKE_INSTALL_PREFIX=prefix
-    - name: Build (CMake)
-      id: cmake-build
-      if: ${{ steps.cmake-configure.outcome == 'success' }}
-      run: |
-        cmake --build build/ --config RelWithDebInfo --verbose --parallel -- -k0
-    - name: Run build-time tests
-      id: cmake-test
-      if: ${{ steps.cmake-build.outcome == 'success' && !contains(matrix.platform.name, 'ARM') && !contains(matrix.platform.name, 'UWP') }}
-      run: |
-        $env:SDL_TESTS_QUICK=1
-        ctest -VV --test-dir build/ -C RelWithDebInfo -j2
-    - name: Install (CMake)
-      id: cmake-install
-      if: ${{ steps.cmake-build.outcome == 'success' }}
-      run: |
-        echo "SDL2_DIR=$Env:GITHUB_WORKSPACE/prefix" >> $Env:GITHUB_ENV
-        cmake --install build/
-    - name: Verify CMake configuration files
-      if: ${{ steps.cmake-install.outcome == 'success' && !contains(matrix.platform.name, 'UWP') }}
-      run: |
-        cmake -S cmake/test -B cmake_config_build -GNinja `
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo `
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} `
-          -DCMAKE_C_FLAGS="${{ matrix.platform.cppflags }}" `
-          -DCMAKE_CXX_FLAGS="${{ matrix.platform.cppflags }}" `
-          -DCMAKE_EXE_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-          -DCMAKE_SHARED_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-          -DCMAKE_STATIC_LINKER_FLAGS="${{ matrix.platform.ldflags }}" `
-          ${{ matrix.platform.cmake-args }}
-        cmake --build cmake_config_build --config RelWithDebInfo
-    - name: Add msbuild to PATH
-      if: ${{ matrix.platform.project != '' }}
-      uses: microsoft/setup-msbuild@v2
-    - name: Build msbuild
-      if: ${{ matrix.platform.project != '' }}
-      run: |
-        msbuild ${{ matrix.platform.project }} /m /p:BuildInParallel=true /p:Configuration=Release ${{ matrix.platform.projectflags }}
-    - uses: actions/upload-artifact@v4
-      if: ${{ always() && steps.cmake-test.outcome == 'failure' }}
-      with:
-        if-no-files-found: ignore
-        name: '${{ matrix.platform.artifact }}-minidumps'
-        path: |
-          build/**/*.dmp
-          build/**/*.exe
-          build/**/*.dll
-          build/**/*.pdb

+ 0 - 55
.github/workflows/n3ds.yml

@@ -1,55 +0,0 @@
-name: Build (Nintendo 3DS)
-
-on: [push, pull_request]
-
-jobs:
-  n3ds:
-    runs-on: ubuntu-latest
-    container:
-      image: devkitpro/devkitarm:latest
-    steps:
-      - uses: actions/checkout@v4
-      - name: Install build requirements
-        run: |
-          apt update
-          apt install ninja-build
-      - name: Configure CMake
-        run: |
-          cmake -S . -B build -G Ninja \
-            -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/3DS.cmake \
-            -DSDL_WERROR=ON \
-            -DSDL_TESTS=ON \
-            -DSDL_INSTALL_TESTS=ON \
-            -DSDL_VENDOR_INFO="Github Workflow" \
-            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-            -DCMAKE_INSTALL_PREFIX=prefix
-      - name: Build
-        run: cmake --build build --verbose
-      - name: Install CMake
-        run: |
-          echo "SDL2_DIR=$(pwd)/prefix" >> $GITHUB_ENV
-          cmake --install build/
-          ( cd prefix; find ) | LC_ALL=C sort -u
-      - name: Verify CMake configuration files
-        run: |
-          cmake -S cmake/test -B cmake_config_build -G Ninja \
-            -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/3DS.cmake \
-            -DTEST_SHARED=FALSE \
-            -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} \
-            -DCMAKE_BUILD_TYPE=RelWithDebInfo
-          cmake --build cmake_config_build --verbose
-      - name: Extract CC/CXX/CFLAGS/CXXFLAGS from CMake toolchain
-        run: |
-          cmake -S .github/cmake -B /tmp/cmake_extract \
-            -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/3DS.cmake \
-            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-            -DVAR_PATH=/tmp/n3ds_env.txt
-          cat /tmp/n3ds_env.txt >> $GITHUB_ENV
-      - name: Verify sdl2-config
-        run: |
-          export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-          cmake/test/test_sdlconfig.sh
-      - name: Verify sdl2.pc
-        run: |
-          export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-          cmake/test/test_pkgconfig.sh

+ 0 - 73
.github/workflows/ps2.yaml

@@ -1,73 +0,0 @@
-name: Build (Sony Playstation 2)
-
-on: [push, pull_request]
-
-jobs:
-  ps2:
-    runs-on: ubuntu-latest
-    container: ps2dev/ps2dev:latest
-    steps:
-    - uses: actions/checkout@v4
-    - name: Setup dependencies
-      run: |
-        apk update 
-        apk add cmake gmp mpc1 mpfr4 ninja pkgconf make git
-
-    # To be removed once ps2_drivers is part of PS2DEV
-    - name: Install ps2_drivers lib
-      run: |
-        git clone https://github.com/fjtrujy/ps2_drivers.git
-        cd ps2_drivers
-        make -j $(getconf _NPROCESSORS_ONLN) clean
-        make -j $(getconf _NPROCESSORS_ONLN)
-        make -j $(getconf _NPROCESSORS_ONLN) install
-
-    - name: Configure (CMake)
-      run: |
-        cmake -S . -B build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake \
-          -DSDL_WERROR=ON \
-          -DSDL_TESTS=ON \
-          -DCMAKE_INSTALL_PREFIX=cmake_prefix \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo
-    - name: Build
-      run: cmake --build build --config RelWithDebInfo --verbose --parallel
-    - name: Install (CMake)
-      run: |
-        set -eu
-        cmake --install build/ --config RelWithDebInfo
-        echo "SDL2_DIR=$(pwd)/cmake_prefix" >> $GITHUB_ENV
-        ( cd cmake_prefix; find ) | LC_ALL=C sort -u
-
-    - name: Verify CMake configuration files
-      run: |
-        cmake -S cmake/test -B cmake_config_build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake \
-          -DTEST_SHARED=FALSE \
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo
-        cmake --build cmake_config_build --verbose
-    - name: Verify sdl2-config
-      run: |
-        export CC=mips64r5900el-ps2-elf-gcc
-        export LDFLAGS="-L$PS2DEV/ps2sdk/ee/lib -L$PS2DEV/gsKit/lib -L$PS2DEV/ps2sdk/ports/lib"
-        export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-        cmake/test/test_sdlconfig.sh
-    - name: Verify sdl2.pc
-      run: |
-        export CC=mips64r5900el-ps2-elf-gcc
-        export LDFLAGS="-L$PS2DEV/ps2sdk/ee/lib -L$PS2DEV/gsKit/lib -L$PS2DEV/ps2sdk/ports/lib"
-        export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-        cmake/test/test_pkgconfig.sh
-    
-    - name: Get short SHA
-      id: slug
-      run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
-
-    - name: Upload artifacts
-      if: ${{ success() }}
-      uses: actions/upload-artifact@v3
-      with:
-        name: tests-${{ steps.slug.outputs.sha8 }}
-        path: |
-          build/test

+ 0 - 50
.github/workflows/psp.yaml

@@ -1,50 +0,0 @@
-name: Build (Sony Playstation Portable)
-
-on: [push, pull_request]
-
-jobs:
-  psp:
-    runs-on: ubuntu-latest
-    container: pspdev/pspdev:latest
-    steps:
-    - uses: actions/checkout@v4
-    - name: Setup dependencies
-      run: |
-        apk update 
-        apk add cmake gmp mpc1 mpfr4 make pkgconf
-    - name: Configure CMake
-      run: |
-        cmake -S . -B build \
-          -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake \
-          -DSDL_WERROR=ON \
-          -DSDL_TESTS=ON \
-          -DSDL_INSTALL_TESTS=ON \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-          -DCMAKE_INSTALL_PREFIX=prefix
-    - name: Build
-      run: cmake --build build --config RelWithDebInfo
-    - name: Install
-      run: |
-        echo "SDL2_DIR=$(pwd)/prefix" >> $GITHUB_ENV
-        cmake --install build --config RelWithDebInfo
-        ( cd prefix; find ) | LC_ALL=C sort -u
-    - name: Verify CMake configuration files
-      run: |
-        cmake -S cmake/test -B cmake_config_build \
-          -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake \
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} \
-          -DTEST_SHARED=FALSE \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo
-        cmake --build cmake_config_build --verbose
-    - name: Verify sdl2-config
-      run: |
-        export CC=psp-gcc
-        export LDFLAGS="-L$PSPDEV/lib -L$PSPDEV/psp/lib -L$PSPDEV/psp/sdk/lib"
-        export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-        cmake/test/test_sdlconfig.sh
-    - name: Verify sdl2.pc
-      run: |
-        export CC=psp-gcc
-        export LDFLAGS="-L$PSPDEV/lib -L$PSPDEV/psp/lib -L$PSPDEV/psp/sdk/lib"
-        export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-        cmake/test/test_pkgconfig.sh

+ 0 - 68
.github/workflows/riscos.yml

@@ -1,68 +0,0 @@
-name: Build (RISC OS)
-
-on: [push, pull_request]
-
-jobs:
-  Build:
-    name: ${{ matrix.platform.name }}
-    runs-on: ubuntu-latest
-    container: riscosdotinfo/riscos-gccsdk-4.7:latest
-
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-          - { name: autotools, test_args: '-DTEST_SHARED=FALSE' } # FIXME: autotools should build and install shared libraries
-          - { name: CMake }
-
-    steps:
-    - name: Setup dependencies
-      run: apt-get update && apt-get install -y cmake ninja-build
-    - uses: actions/checkout@v4
-    - name: Configure (autotools)
-      if: ${{ contains(matrix.platform.name, 'autotools') }}
-      run: |
-        mkdir build_autotools
-        cd build_autotools
-        ../configure \
-          --host=arm-unknown-riscos \
-          --disable-gcc-atomics \
-          --prefix=${{ github.workspace }}/prefix_autotools
-    - name: Build (autotools)
-      if: ${{ contains(matrix.platform.name, 'autotools') }}
-      run: make -C build_autotools -j`nproc` V=1
-    - name: Install (autotools)
-      if: ${{ contains(matrix.platform.name, 'autotools') }}
-      run: |
-        echo "SDL2_DIR=${{ github.workspace }}/prefix_autotools" >> $GITHUB_ENV
-        make -C build_autotools install
-        ( cd ${{ github.workspace }}/prefix_autotools; find ) | LC_ALL=C sort -u
-    - name: Configure (CMake)
-      if: ${{ contains(matrix.platform.name, 'CMake') }}
-      run: |
-        cmake -S . -B build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=/home/riscos/env/toolchain-riscos.cmake \
-          -DRISCOS=ON \
-          -DSDL_GCC_ATOMICS=OFF \
-          -DSDL_TESTS=ON \
-          -DSDL_INSTALL_TESTS=ON \
-          -DSDL_VENDOR_INFO="Github Workflow" \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-          -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/prefix_cmake
-    - name: Build (CMake)
-      if: ${{ contains(matrix.platform.name, 'CMake') }}
-      run: cmake --build build --verbose
-    - name: Install (CMake)
-      if: ${{ contains(matrix.platform.name, 'CMake') }}
-      run: |
-        echo "SDL2_DIR=${{ github.workspace }}/prefix_cmake" >> $GITHUB_ENV
-        cmake --install build/
-        ( cd ${{ github.workspace }}/prefix_cmake; find ) | LC_ALL=C sort -u
-    - name: Verify CMake configuration files
-      run: |
-        cmake -S cmake/test -B cmake_config_build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=/home/riscos/env/toolchain-riscos.cmake \
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-          ${{ matrix.platform.test_args }}
-        cmake --build cmake_config_build --verbose

+ 0 - 95
.github/workflows/vita.yaml

@@ -1,95 +0,0 @@
-name: Build (Sony Playstation Vita)
-
-on: [push, pull_request]
-
-defaults:
-  run:
-    shell: sh
-
-jobs:
-  vita:
-    name: ${{ matrix.platform.name }}
-    runs-on: ubuntu-latest
-    container: 
-      image: vitasdk/vitasdk:latest
-    strategy:
-      fail-fast: false
-      matrix:
-        platform:
-          - { name: GLES (pib),                    os: windows-latest, pib: true }
-          - { name: GLES (PVR_PSP2 + gl4es4vita),  os: windows-latest, pvr: true }
-    steps:
-    - uses: actions/checkout@v4
-    - name: Install build requirements
-      run: |
-        apk update 
-        apk add cmake ninja pkgconf bash
-
-    - name: Configure PVR_PSP2 (GLES)
-      if: ${{ !!matrix.platform.pvr }}
-      run: |
-        pvr_psp2_version=3.9
-
-        # Configure PVR_PSP2 headers
-        wget https://github.com/GrapheneCt/PVR_PSP2/archive/refs/tags/v$pvr_psp2_version.zip -P/tmp
-        unzip /tmp/v$pvr_psp2_version.zip -d/tmp
-        cp -r /tmp/PVR_PSP2-$pvr_psp2_version/include/* ${VITASDK}/arm-vita-eabi/include
-        rm /tmp/v$pvr_psp2_version.zip
-
-        # Configure PVR_PSP2 stub libraries
-        wget https://github.com/GrapheneCt/PVR_PSP2/releases/download/v$pvr_psp2_version/vitasdk_stubs.zip -P/tmp
-        unzip /tmp/vitasdk_stubs.zip -d/tmp/pvr_psp2_stubs
-        find /tmp/pvr_psp2_stubs -type f -name "*.a" -exec cp {} ${VITASDK}/arm-vita-eabi/lib \;
-        rm /tmp/vitasdk_stubs.zip
-        rm -rf /tmp/pvr_psp2_stubs
-
-    - name: Configure gl4es4vita (OpenGL)
-      if: ${{ !!matrix.platform.pvr }}
-      run: |
-        gl4es4vita_version=1.1.4
-
-        # Configure gl4es4vita headers
-        wget https://github.com/SonicMastr/gl4es4vita/releases/download/v$gl4es4vita_version-vita/include.zip -P/tmp
-        unzip -o /tmp/include.zip -d${VITASDK}/arm-vita-eabi/include
-        rm /tmp/include.zip
-
-        # Configure gl4es4vita stub libraries
-        wget https://github.com/SonicMastr/gl4es4vita/releases/download/v$gl4es4vita_version-vita/vitasdk_stubs.zip -P/tmp
-        unzip /tmp/vitasdk_stubs.zip -d${VITASDK}/arm-vita-eabi/lib
-
-    - name: Configure CMake
-      run: |
-        cmake -S . -B build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake \
-          -DVIDEO_VITA_PIB=${{ !!matrix.platform.pib }} \
-          -DVIDEO_VITA_PVR=${{ !!matrix.platform.pvr }} \
-          -DSDL_WERROR=ON \
-          -DSDL_TESTS=ON \
-          -DSDL_INSTALL_TESTS=ON \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-          -DCMAKE_INSTALL_PREFIX=prefix
-    - name: Build
-      run: cmake --build build --verbose
-    - name: Install CMake
-      run: |
-        echo "SDL2_DIR=$(pwd)/prefix" >> $GITHUB_ENV
-        cmake --install build/
-        ( cd prefix; find ) | LC_ALL=C sort -u
-    - name: Verify CMake configuration files
-      run: |
-        cmake -S cmake/test -B cmake_config_build -G Ninja \
-          -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake \
-          -DTEST_SHARED=FALSE \
-          -DCMAKE_PREFIX_PATH=${{ env.SDL2_DIR }} \
-          -DCMAKE_BUILD_TYPE=RelWithDebInfo
-        cmake --build cmake_config_build --verbose
-    - name: Verify sdl2-config
-      run: |
-        export CC=arm-vita-eabi-gcc
-        export PATH=${{ env.SDL2_DIR }}/bin:$PATH
-        cmake/test/test_sdlconfig.sh
-    - name: Verify sdl2.pc
-      run: |
-        export CC=arm-vita-eabi-gcc
-        export PKG_CONFIG_PATH=${{ env.SDL2_DIR }}/lib/pkgconfig
-        cmake/test/test_pkgconfig.sh

+ 0 - 35
.github/workflows/watcom.yml

@@ -1,35 +0,0 @@
-name: Build (OpenWatcom)
-
-on: [push, pull_request]
-
-jobs:
-  os2:
-    name: ${{ matrix.platform.name }}
-    runs-on: windows-latest
-
-    strategy:
-      matrix:
-        platform:
-        - { name: Windows, makefile: Makefile.w32 }
-        - { name: OS/2,    makefile: Makefile.os2 }
-
-    steps:
-      - uses: actions/checkout@v4
-      - uses: open-watcom/setup-watcom@v0
-      - name: Build SDL2
-        run: |
-          wmake -f ${{ matrix.platform.makefile }} ENABLE_WERROR=1
-      - name: Build tests
-        run: |
-          cd test && wmake -f ${{ matrix.platform.makefile }} ENABLE_WERROR=1
-          cd ..
-      - name: Run tests
-        if: "matrix.platform.makefile == 'Makefile.w32'"
-        run: |
-          cd test && wmake -f ${{ matrix.platform.makefile }} check-quick
-          cd ..
-      - name: distclean
-        run: |
-          wmake -f ${{ matrix.platform.makefile }} distclean
-          cd test && wmake -f ${{ matrix.platform.makefile }} distclean
-          cd ..

+ 1 - 1
test/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0...3.5)
+cmake_minimum_required(VERSION 3.0...3.10)
 project(SDL2_test C)
 
 include(CheckCCompilerFlag)