SDL_mixer: Add parametrized release script

From c6ffe1d8feea579bc53ffd9477484e1fd918d4fa Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Sat, 28 Sep 2024 00:07:42 +0200
Subject: [PATCH] Add parametrized release script

[ci skip]
---
 .github/actions/setup-ninja/action.yml        |   62 +
 .github/workflows/release.yml                 |  538 ++++++
 VisualC/SDL_mixer.vcxproj                     |  139 +-
 VisualC/native_midi/native_midi.vcxproj       |    8 +-
 VisualC/timidity/timidity.vcxproj             |    8 +-
 Xcode/package                                 |  272 ---
 Xcode/pkg-support/build.xcconfig              |   32 +
 build-scripts/build-release.py                | 1485 +++++++++++++++++
 .../cmake-toolchain-mingw64-i686.cmake        |   18 +
 .../cmake-toolchain-mingw64-x86_64.cmake      |   18 +
 build-scripts/create-release.py               |   45 +
 build-scripts/release-info.json               |  155 ++
 build-scripts/test-versioning.sh              |  152 ++
 mingw/pkg-support/Makefile                    |   32 +
 14 files changed, 2613 insertions(+), 351 deletions(-)
 create mode 100644 .github/actions/setup-ninja/action.yml
 create mode 100644 .github/workflows/release.yml
 delete mode 100755 Xcode/package
 create mode 100644 Xcode/pkg-support/build.xcconfig
 create mode 100755 build-scripts/build-release.py
 create mode 100644 build-scripts/cmake-toolchain-mingw64-i686.cmake
 create mode 100644 build-scripts/cmake-toolchain-mingw64-x86_64.cmake
 create mode 100755 build-scripts/create-release.py
 create mode 100644 build-scripts/release-info.json
 create mode 100755 build-scripts/test-versioning.sh
 create mode 100644 mingw/pkg-support/Makefile

diff --git a/.github/actions/setup-ninja/action.yml b/.github/actions/setup-ninja/action.yml
new file mode 100644
index 000000000..b9283598d
--- /dev/null
+++ b/.github/actions/setup-ninja/action.yml
@@ -0,0 +1,62 @@
+name: 'Setup ninja'
+description: 'Download ninja and add it to the PATH environment variable'
+inputs:
+  version:
+    description: 'Ninja version'
+    default: '1.12.1'
+runs:
+  using: 'composite'
+  steps:
+    - name: 'Calculate variables'
+      id: calc
+      shell: sh
+      run: |
+        case "${{ runner.os }}-${{ runner.arch }}" in
+          "Linux-X86" | "Linux-X64")
+            archive="ninja-linux.zip"
+            ;;
+          "Linux-ARM64")
+            archive="ninja-linux-aarch64.zip"
+            ;;
+          "macOS-X86" | "macOS-X64" | "macOS-ARM64")
+            archive="ninja-mac.zip"
+            ;;
+          "Windows-X86" | "Windows-X64")
+            archive="ninja-win.zip"
+            ;;
+          "Windows-ARM64")
+            archive="ninja-winarm64.zip"
+            ;;
+          *)
+            echo "Unsupported ${{ runner.os }}-${{ runner.arch }}"
+            exit 1;
+            ;;
+        esac
+        echo "archive=${archive}" >> ${GITHUB_OUTPUT}
+        echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT}
+    - name: 'Restore cached ${{ steps.calc.outputs.archive }}'
+      id: cache-restore
+      uses: actions/cache/restore@v4
+      with:
+        path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}'
+        key: ${{ steps.calc.outputs.cache-key }}
+    - name: 'Download ninja ${{ inputs.version }} for ${{ runner.os }} (${{ runner.arch }})'
+      if: ${{ !steps.cache-restore.outputs.cache-hit }}
+      shell: pwsh
+      run: |
+        Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v${{ inputs.version }}/${{ steps.calc.outputs.archive }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}"
+    - name: 'Cache ${{ steps.calc.outputs.archive }}'
+      if: ${{ !steps.cache-restore.outputs.cache-hit }}
+      uses: actions/cache/save@v4
+      with:
+        path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}'
+        key: ${{ steps.calc.outputs.cache-key }}
+    - name: 'Extract libusb'
+      shell: pwsh
+      run: |
+        7z "-o${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" x "${{ runner.temp }}/${{ steps.calc.outputs.archive }}"
+    - name: 'Set output variables'
+      id: final
+      shell: pwsh
+      run: |
+        echo "${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" >> $env:GITHUB_PATH
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..801d01071
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,538 @@
+name: 'release'
+run-name: 'Create SDL_mixer release artifacts for ${{ inputs.commit }}'
+
+on:
+  workflow_dispatch:
+    inputs:
+      commit:
+        description: 'Commit of SDL_mixer'
+        required: true
+
+jobs:
+
+  src:
+    runs-on: ubuntu-latest
+    outputs:
+      project: ${{ steps.releaser.outputs.project }}
+      version: ${{ steps.releaser.outputs.version }}
+      src-tar-gz: ${{ steps.releaser.outputs.src-tar-gz }}
+      src-tar-xz: ${{ steps.releaser.outputs.src-tar-xz }}
+      src-zip: ${{ steps.releaser.outputs.src-zip }}
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Set up SDL sources'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          path: 'SDL'
+          fetch-depth: 0
+      - name: 'Build Source archive'
+        id: releaser
+        shell: bash
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions source \
+            --commit ${{ inputs.commit }} \
+            --root "${{ github.workspace }}/SDL" \
+            --github \
+            --debug
+      - name: 'Store source archives'
+        uses: actions/upload-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace}}/dist'
+
+  linux-verify:
+    needs: [src]
+    runs-on: ubuntu-latest
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '/tmp'
+      - name: 'Unzip ${{ needs.src.outputs.src-zip }}'
+        id: zip
+        run: |
+          set -e
+          mkdir /tmp/zipdir
+          cd /tmp/zipdir
+          unzip "/tmp/${{ needs.src.outputs.src-zip }}"
+          echo "path=/tmp/zipdir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
+        id: tar
+        run: |
+          set -e
+          mkdir -p /tmp/tardir
+          tar -C /tmp/tardir -v -x -f "/tmp/${{ needs.src.outputs.src-tar-gz }}"
+          echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Compare contents of ${{ needs.src.outputs.src-zip }} and  ${{ needs.src.outputs.src-tar-gz }}'
+        run: |
+          set -e
+          diff "${{ steps.zip.outputs.path }}" "${{ steps.tar.outputs.path }}"
+      - name: 'Test versioning'
+        shell: bash
+        run: |
+          ${{ steps.tar.outputs.path }}/build-scripts/test-versioning.sh
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Download dependencies'
+        id: deps
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions download \
+            --commit ${{ inputs.commit }} \
+            --root "${{ steps.tar.outputs.path }}" \
+            --github \
+            --debug
+      - name: 'Extract dependencies, build and install them'
+        id: deps-build
+        run: |
+          tar -C /tmp -v -x -f "${{ steps.deps.outputs.dep-path }}/SDL2-${{ steps.deps.outputs.dep-sdl-version }}.tar.gz"
+          cmake -S /tmp/SDL2-${{ steps.deps.outputs.dep-sdl-version }} -B /tmp/SDL-build -DCMAKE_INSTALL_PREFIX=/tmp/deps-prefix
+          cmake --build /tmp/SDL-build
+          cmake --install /tmp/SDL-build
+          echo "path=/tmp/deps-prefix" >>$GITHUB_OUTPUT
+      - name: 'CMake (configure + build)'
+        run: |
+          cmake \
+            -S ${{ steps.tar.outputs.path }} \
+            -B /tmp/build \
+            -DSDL2MIXER_SAMPLES=ON \
+            -DSDL2MIXER_MIDI=OFF \
+            -DSDL2MIXER_MOD=OFF \
+            -DSDL2MIXER_OPUS=OFF \
+            -DSDL2MIXER_WAVPACK=OFF \
+            -DCMAKE_PREFIX_PATH="${{ steps.deps-build.outputs.path }}"
+          cmake --build /tmp/build --verbose
+          # ctest --test-dir /tmp/build --no-tests=error --output-on-failure
+
+  dmg:
+    needs: [src]
+    runs-on: macos-latest
+    outputs:
+      dmg: ${{ steps.releaser.outputs.dmg }}
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
+        id: tar
+        run: |
+          mkdir -p "${{ github.workspace }}/tardir"
+          tar -C "${{ github.workspace }}/tardir" -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
+          echo "path=${{ github.workspace }}/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Download external dependencies'
+        run: |
+          sh "${{ steps.tar.outputs.path }}/external/download.sh" --depth 1
+      - name: 'Build SDL2_mixer.dmg'
+        id: releaser
+        shell: bash
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions dmg \
+            --commit ${{ inputs.commit }} \
+            --root "${{ steps.tar.outputs.path }}" \
+            --github \
+            --debug
+      - name: 'Store DMG image file'
+        uses: actions/upload-artifact@v4
+        with:
+          name: dmg
+          path: '${{ github.workspace }}/dist'
+
+  dmg-verify:
+    needs: [dmg, src]
+    runs-on: macos-latest
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
+        id: src
+        run: |
+          mkdir -p /tmp/tardir
+          tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
+          echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Download dependencies'
+        id: deps
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions download \
+            --commit ${{ inputs.commit }} \
+            --root "${{ steps.src.outputs.path }}" \
+            --github \
+            --debug
+      - name: 'Mount dependencies'
+        id: deps-mount
+        run: |
+          hdiutil attach "${{ steps.deps.outputs.dep-path }}/SDL2-${{ steps.deps.outputs.dep-sdl-version }}.dmg"
+          sdl_mount_pount="/Volumes/SDL2"
+          if [ ! -d "$sdl_mount_pount/SDL2.framework" ]; then
+            echo "Cannot find SDL2.framework!"
+            exit 1
+          fi
+          echo "path=${sdl_mount_pount}" >>$GITHUB_OUTPUT
+      - name: 'Download ${{ needs.dmg.outputs.dmg }}'
+        uses: actions/download-artifact@v4
+        with:
+          name: dmg
+          path: '${{ github.workspace }}'
+      - name: 'Mount ${{ needs.dmg.outputs.dmg }}'
+        id: mount
+        run: |
+          hdiutil attach '${{ github.workspace }}/${{ needs.dmg.outputs.dmg }}'
+          mount_point="/Volumes/${{ needs.src.outputs.project }}"
+          if [ ! -d "$mount_point/${{ needs.src.outputs.project }}.framework" ]; then
+            echo "Cannot find ${{ needs.src.outputs.project }}.framework!"
+            exit 1
+          fi
+          echo "path=${mount_point}">>$GITHUB_OUTPUT
+      - name: 'Verify presence of optional frameworks'
+        run: |
+          OPTIONAL_FRAMEWORKS="gme ogg opus wavpack xmp"
+          rc=0
+          for opt in $OPTIONAL_FRAMEWORKS; do
+            fw_path="${{ steps.mount.outputs.path }}/optional/${opt}.framework"
+            if [ -d "${fw_path}" ]; then
+              echo "$fw_path OK"
+            else
+              echo "$fw_path MISSING"
+              rc=1
+            fi
+          done
+          exit $rc
+      - name: 'CMake (configure + build) Darwin'
+        run: |
+          set -e
+          cmake -S "${{ steps.src.outputs.path }}/cmake/test"               \
+              -DTEST_SHARED=TRUE                                            \
+              -DTEST_STATIC=FALSE                                           \
+              -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.path }};${{ steps.deps-mount.outputs.path }}" \
+              -DCMAKE_SYSTEM_NAME=Darwin                                    \
+              -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"                      \
+              -Werror=dev                                                   \
+              -B build_darwin
+          cmake --build build_darwin --config Release --verbose
+
+  msvc:
+    needs: [src]
+    runs-on: windows-2019
+    outputs:
+      VC-x86: ${{ steps.releaser.outputs.VC-x86 }}
+      VC-x64: ${{ steps.releaser.outputs.VC-x64 }}
+      VC-devel: ${{ steps.releaser.outputs.VC-devel }}
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Unzip ${{ needs.src.outputs.src-zip }}'
+        id: zip
+        run: |
+          New-Item C:\temp -ItemType Directory -ErrorAction SilentlyContinue
+          cd C:\temp
+          unzip "${{ github.workspace }}/${{ needs.src.outputs.src-zip }}"
+          echo "path=C:\temp\${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$Env:GITHUB_OUTPUT
+      - name: 'Build MSVC binary archives'
+        id: releaser
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py `
+            --actions download msvc `
+            --commit ${{ inputs.commit }} `
+            --root "${{ steps.zip.outputs.path }}" `
+            --github `
+            --debug
+      - name: 'Store MSVC archives'
+        uses: actions/upload-artifact@v4
+        with:
+          name: msvc
+          path: '${{ github.workspace }}/dist'
+
+  msvc-verify:
+    needs: [msvc, src]
+    runs-on: windows-latest
+    steps:
+      - name: 'Fetch .github/actions/setup-ninja/action.yml'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: |
+            .github/actions/setup-ninja/action.yml
+            build-scripts/build-release.py
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Unzip ${{ needs.src.outputs.src-zip }}'
+        id: src
+        run: |
+          mkdir '${{ github.workspace }}/sources'
+          cd '${{ github.workspace }}/sources'
+          unzip "${{ github.workspace }}/${{ needs.src.outputs.src-zip }}"
+          echo "path=${{ github.workspace }}/sources/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$env:GITHUB_OUTPUT
+      - name: 'Download dependencies'
+        id: deps
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py `
+            --actions download `
+            --commit ${{ inputs.commit }} `
+            --root "${{ steps.src.outputs.path }}" `
+            --github `
+            --debug
+      - name: 'Extract dependencies'
+        id: deps-extract
+        run: |
+          mkdir '${{ github.workspace }}/deps-vc'
+          cd '${{ github.workspace }}/deps-vc'
+          unzip "${{ steps.deps.outputs.dep-path }}/SDL2-devel-${{ steps.deps.outputs.dep-sdl-version }}-VC.zip"
+          echo "path=${{ github.workspace }}/deps-vc" >>$env:GITHUB_OUTPUT
+      - name: 'Download MSVC binaries'
+        uses: actions/download-artifact@v4
+        with:
+          name: msvc
+          path: '${{ github.workspace }}'
+      - name: 'Unzip ${{ needs.msvc.outputs.VC-devel }}'
+        id: bin
+        run: |
+          mkdir '${{ github.workspace }}/vc'
+          cd '${{ github.workspace }}/vc'
+          unzip "${{ github.workspace }}/${{ needs.msvc.outputs.VC-devel }}"
+          echo "path=${{ github.workspace }}/vc/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$env:GITHUB_OUTPUT
+      - name: Set up ninja
+        uses: ./.github/actions/setup-ninja
+      - name: 'Configure vcvars x86'
+        uses: ilammy/msvc-dev-cmd@v1
+        with:
+          arch: x64_x86
+      - name: 'CMake (configure + build + tests) x86'
+        run: |
+          cmake -S "${{ steps.src.outputs.path }}/cmake/test"     `
+              -B build_x86                                        `
+              -GNinja                                             `
+              -DCMAKE_BUILD_TYPE=Debug                            `
+              -Werror                                             `
+              -DTEST_STATIC=FALSE                                 `
+              -DTEST_SHARED=TRUE                                  `
+              -DCMAKE_SUPPRESS_REGENERATION=TRUE                  `
+              -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}"
+          Start-Sleep -Seconds 2
+          cmake --build build_x86 --config Release --verbose
+      - name: 'Configure vcvars x64'
+        uses: ilammy/msvc-dev-cmd@v1
+        with:
+          arch: x64
+      - name: 'CMake (configure + build + tests) x64'
+        run: |
+          cmake -S "${{ steps.src.outputs.path }}/cmake/test"     `
+              -B build_x64                                        `
+              -GNinja                                             `
+              -DCMAKE_BUILD_TYPE=Debug                            `
+              -Werror                                             `
+              -DTEST_STATIC=FALSE                                 `
+              -DTEST_SHARED=TRUE                                  `
+              -DCMAKE_SUPPRESS_REGENERATION=TRUE                  `
+              -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}"
+          Start-Sleep -Seconds 2
+          cmake --build build_x64 --config Release --verbose
+
+  mingw:
+    needs: [src]
+    runs-on: ubuntu-24.04  # FIXME: current ubuntu-latest ships an outdated mingw, replace with ubuntu-latest once 24.04 becomes the new default
+    outputs:
+      mingw-devel-tar-gz: ${{ steps.releaser.outputs.mingw-devel-tar-gz }}
+      mingw-devel-tar-xz: ${{ steps.releaser.outputs.mingw-devel-tar-xz }}
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Install Mingw toolchain'
+        run: |
+          sudo apt-get update -y
+          sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
+        id: tar
+        run: |
+          mkdir -p /tmp/tardir
+          tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
+          echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Build MinGW binary archives'
+        id: releaser
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions download mingw \
+            --commit ${{ inputs.commit }} \
+            --root "${{ steps.tar.outputs.path }}" \
+            --github \
+            --debug
+      - name: 'Store MinGW archives'
+        uses: actions/upload-artifact@v4
+        with:
+          name: mingw
+          path: '${{ github.workspace }}/dist'
+
+  mingw-verify:
+    needs: [mingw, src]
+    runs-on: ubuntu-latest
+    steps:
+      - name: 'Set up Python'
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.11'
+      - name: 'Fetch build-release.py'
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ inputs.commit }}
+          sparse-checkout: 'build-scripts/build-release.py'
+      - name: 'Install Mingw toolchain'
+        run: |
+          sudo apt-get update -y
+          sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build
+      - name: 'Download source archives'
+        uses: actions/download-artifact@v4
+        with:
+          name: sources
+          path: '${{ github.workspace }}'
+      - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
+        id: src
+        run: |
+          mkdir -p /tmp/tardir
+          tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
+          echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
+      - name: 'Download dependencies'
+        id: deps
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          python build-scripts/build-release.py \
+            --actions download \
+            --commit ${{ inputs.commit }} \
+            --root "${{ steps.src.outputs.path }}" \
+            --github \
+            --debug
+      - name: 'Untar and install dependencies'
+        id: deps-extract
+        run: |
+          mkdir -p /tmp/deps-mingw/cmake
+          mkdir -p /tmp/deps-mingw/i686-w64-mingw32
+          mkdir -p /tmp/deps-mingw/x86_64-w64-mingw32
+          
+          mkdir -p /tmp/deps-mingw-extract/sdl2/
+          tar -C /tmp/deps-mingw-extract/sdl2 -v -x -f "${{ steps.deps.outputs.dep-path }}/SDL2-devel-${{ steps.deps.outputs.dep-sdl-version }}-mingw.tar.gz"
+          make -C /tmp/deps-mingw-extract/sdl2/SDL2-${{ steps.deps.outputs.dep-sdl-version }} install-package arch=i686-w64-mingw32   prefix=/tmp/deps-mingw/i686-w64-mingw32
+          make -C /tmp/deps-mingw-extract/sdl2/SDL2-${{ steps.deps.outputs.dep-sdl-version }} install-package arch=x86_64-w64-mingw32 prefix=/tmp/deps-mingw/x86_64-w64-mingw32
+          cp -r /tmp/deps-mingw-extract/sdl2/SDL2-${{ steps.deps.outputs.dep-sdl-version }}/cmake/* /tmp/deps-mingw/cmake
+      - name: 'Download MinGW binaries'
+        uses: actions/download-artifact@v4
+        with:
+          name: mingw
+          path: '${{ github.workspace }}'
+      - name: 'Untar and install ${{ needs.mingw.outputs.mingw-devel-tar-gz }}'
+        id: bin
+        run: |
+          mkdir -p /tmp/mingw-tardir
+          tar -C /tmp/mingw-tardir -v -x -f "${{ github.workspace }}/${{ needs.mingw.outputs.mingw-devel-tar-gz }}"
+          make -C /tmp/mingw-tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }} install-package arch=i686-w64-mingw32   prefix=/tmp/deps-mingw/i686-w64-mingw32
+          make -C /tmp/mingw-tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }} install-package arch=x86_64-w64-mingw32 prefix=/tmp/deps-mingw/x86_64-w64-mingw32
+          cp -r /tmp/mingw-tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}/cmake/* /tmp/deps-mingw/cmake
+      - name: 'CMake (configure + build) i686'
+        run: |
+          set -e
+          cmake -S "${{ steps.src.outputs.path }}/cmake/test"                                                           \
+              -DCMAKE_BUILD_TYPE="Release"                                                                              \
+              -DTEST_SHARED=TRUE                                                                                        \
+              -DTEST_STATIC=TRUE                                                                                        \
+              -DCMAKE_PREFIX_PATH="/tmp/deps-mingw"                                                                     \
+              -DCMAKE_TOOLCHAIN_FILE="${{ steps.src.outputs.path }}/build-scripts/cmake-toolchain-mingw64-i686.cmake"   \
+              -Werror=dev                                                                                               \
+              -B build_x86
+          cmake --build build_x86 --config Release --verbose
+      - name: 'CMake (configure + build) x86_64'
+        run: |
+          set -e
+          cmake -S "${{ steps.src.outputs.path }}/cmake/test"                                                           \
+              -DCMAKE_BUILD_TYPE="Release"                                                                              \
+              -DTEST_SHARED=TRUE                                                                                        \
+              -DTEST_STATIC=TRUE                                                                                        \
+              -DCMAKE_PREFIX_PATH="/tmp/deps-mingw"                                                                     \
+              -DCMAKE_TOOLCHAIN_FILE="${{ steps.src.outputs.path }}/build-scripts/cmake-toolchain-mingw64-x86_64.cmake" \
+              -Werror=dev                                                                                               \
+              -B build_x64
+          cmake --build build_x64 --config Release --verbose
diff --git a/VisualC/SDL_mixer.vcxproj b/VisualC/SDL_mixer.vcxproj
index 524dd09a8..f63bec41a 100644
--- a/VisualC/SDL_mixer.vcxproj
+++ b/VisualC/SDL_mixer.vcxproj
@@ -101,7 +101,7 @@
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\src\codecs;$(ProjectDir)..\src\codecs\timidity;$(ProjectDir)..\src\codecs\native_midi;$(ProjectDir)external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll";OGG_DYNAMIC="libvorbisfile-3.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
@@ -129,7 +129,7 @@
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\src\codecs;$(ProjectDir)..\src\codecs\timidity;$(ProjectDir)..\src\codecs\native_midi;$(ProjectDir)external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll";OGG_DYNAMIC="libvorbisfile-3.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
     </ClCompile>
@@ -155,7 +155,7 @@
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\src\codecs;$(ProjectDir)..\src\codecs\timidity;$(ProjectDir)..\src\codecs\native_midi;$(ProjectDir)external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;MUSIC_WAVPACK;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll";OGG_DYNAMIC="libvorbisfile-3.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
     </ClCompile>
@@ -163,8 +163,10 @@
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>winmm.lib;SDL2.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Windows</SubSystem>
+      <AdditionalDependencies>winmm.lib;SDL2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -180,15 +182,17 @@
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\src\codecs;$(ProjectDir)..\src\codecs\timidity;$(ProjectDir)..\src\codecs\native_midi;$(ProjectDir)external\include;%(Additional

(Patch may be truncated, please check the link at the top of this post.)