From 4b2280e51ccc4ebc7066d6a264dea5dff8f27585 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Wed, 18 Mar 2026 19:35:28 -0400 Subject: [PATCH] feat: add support for win-mingw ucrt64 builds --- .github/workflows/libvni.yml | 325 ++++++++++++++++++++++------------- CMakeLists.txt | 26 ++- README.md | 84 +++++++++ 3 files changed, 308 insertions(+), 127 deletions(-) diff --git a/.github/workflows/libvni.yml b/.github/workflows/libvni.yml index 44375d5..132c0fe 100644 --- a/.github/workflows/libvni.yml +++ b/.github/workflows/libvni.yml @@ -3,6 +3,9 @@ on: push: pull_request: +permissions: + contents: write + defaults: run: shell: bash @@ -10,12 +13,12 @@ defaults: jobs: version: name: Detect version - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: tag: ${{ steps.version.outputs.tag }} vniversion: ${{ steps.version.outputs.vniversion }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - id: version @@ -46,142 +49,224 @@ jobs: fail-fast: false matrix: include: - - os: windows-latest - platform: win - arch: x64 - - os: windows-latest - platform: win - arch: x86 - - os: macos-latest - platform: macos - arch: arm64 - - os: macos-latest - platform: macos - arch: x64 - - os: ubuntu-24.04 - platform: linux - arch: x64 - - os: ubuntu-24.04-arm - platform: linux - arch: aarch64 - - os: ubuntu-24.04 - platform: android - arch: arm64-v8a - - os: macos-latest - platform: ios - arch: arm64 - - os: macos-latest - platform: ios-simulator - arch: arm64 - - os: macos-latest - platform: tvos - arch: arm64 + - { os: windows-2025, platform: win, arch: x64 } + - { os: windows-2025, platform: win, arch: x86 } + - { os: windows-2025, platform: win-mingw, arch: x64 } + - { os: macos-15, platform: macos, arch: arm64 } + - { os: macos-15, platform: macos, arch: x64 } + - { os: ubuntu-24.04, platform: linux, arch: x64 } + - { os: ubuntu-24.04-arm, platform: linux, arch: aarch64 } + - { os: ubuntu-24.04, platform: android, arch: arm64-v8a } + - { os: macos-15, platform: ios, arch: arm64 } + - { os: macos-15, platform: ios-simulator, arch: arm64 } + - { os: macos-15, platform: tvos, arch: arm64 } steps: - - uses: actions/checkout@v4 - - name: Build libvni-${{ matrix.platform }}-${{ matrix.arch }} - run: | - if [[ "${{ matrix.platform }}" == "win" ]]; then - if [[ "${{ matrix.arch }}" == "x86" ]]; then - cmake -G "Visual Studio 17 2022" -A Win32 -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build - else - cmake -G "Visual Studio 17 2022" -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build - fi - cmake --build build --config Release + - uses: actions/checkout@v6 + # + # install dependencies + # + - if: (matrix.platform == 'win') + uses: microsoft/setup-msbuild@v2 + - if: (matrix.platform == 'win-mingw') + run: | + /c/msys64/usr/bin/bash.exe -l -c "pacman -S --noconfirm \ + mingw-w64-ucrt-x86_64-gcc \ + mingw-w64-ucrt-x86_64-cmake" + # + # build (win) + # + - if: (matrix.platform == 'win') + name: Build (win) + run: | + if [[ "${{ matrix.arch }}" == "x64" ]]; then + cmake \ + -G "Visual Studio 17 2022" \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build else - if [[ "$(uname)" == "Darwin" ]]; then - NUM_PROCS=$(sysctl -n hw.ncpu) - else - NUM_PROCS=$(nproc) - fi - cmake -DCMAKE_BUILD_TYPE=Release -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build - cmake --build build -- -j${NUM_PROCS} + cmake \ + -G "Visual Studio 17 2022" \ + -A Win32 \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build fi - - name: Prepare artifacts - id: artifacts + cmake --build build --config Release + # + # build (win-mingw) + # + - if: (matrix.platform == 'win-mingw') + name: Build (win-mingw) + run: | + CURRENT_DIR="$(pwd)" + MSYSTEM=UCRT64 /c/msys64/usr/bin/bash.exe -l -c " + cd \"${CURRENT_DIR}\" && + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build && + cmake --build build -- -j\$(nproc) + " + # + # build (macos) + # + - if: (matrix.platform == 'macos') + name: Build (macos) + run: | + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build + cmake --build build -- -j$(sysctl -n hw.ncpu) + # + # build (linux) + # + - if: (matrix.platform == 'linux') + name: Build (linux) + run: | + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build + cmake --build build -- -j$(nproc) + # + # build (ios/tvos) + # + - if: (matrix.platform == 'ios' || matrix.platform == 'ios-simulator' || matrix.platform == 'tvos') + name: Build (ios/tvos) + run: | + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build + cmake --build build -- -j$(sysctl -n hw.ncpu) + # + # build (android) + # + - if: (matrix.platform == 'android') + name: Build (android) + run: | + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=${{ matrix.platform }} \ + -DARCH=${{ matrix.arch }} \ + -B build + cmake --build build -- -j$(nproc) + # + # prepare artifacts + # + - if: (matrix.platform == 'win') + name: Prepare artifacts (win) run: | mkdir tmp - if [[ "${{ matrix.platform }}" == "win" ]]; then - ARTIFACT_PATH="tmp" - if [[ "${{ matrix.arch }}" == "x86" ]]; then - cp build/Release/vni.lib tmp - cp build/Release/vni.dll tmp - else - cp build/Release/vni64.lib tmp - cp build/Release/vni64.dll tmp - fi - cp build/Release/vni_static.lib tmp - else - ARTIFACT_PATH="libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz" - if [[ "${{ matrix.platform }}" == "macos" ]]; then - cp build/libvni.a tmp - cp build/libvni.*.dylib tmp - elif [[ "${{ matrix.platform }}" == "linux" ]]; then - cp build/libvni.a tmp - cp build/libvni.so.* tmp - elif [[ "${{ matrix.platform }}" == "ios" || "${{ matrix.platform }}" == "ios-simulator" || "${{ matrix.platform }}" == "tvos" ]]; then - cp build/libvni.a tmp - cp build/libvni.*.dylib tmp - elif [[ "${{ matrix.platform }}" == "android" ]]; then - cp build/libvni.a tmp - cp build/libvni.so tmp - fi - cd tmp - tar -czvf ../${ARTIFACT_PATH} * - fi - echo "artifact_path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT - - name: Upload artifacts - uses: actions/upload-artifact@v4 + cp build/Release/*.lib tmp/ + cp build/Release/*.dll tmp/ + cd tmp && 7z a -r ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.zip * + - if: (matrix.platform == 'win-mingw') + name: Prepare artifacts (win-mingw) + run: | + mkdir tmp + cp build/*.dll tmp/ + cp build/*.dll.a tmp/ + cp build/vni_static.a tmp/ + UCRT64_BIN="/c/msys64/ucrt64/bin" + cp "${UCRT64_BIN}/libgcc_s_seh-1.dll" tmp/ + cp "${UCRT64_BIN}/libstdc++-6.dll" tmp/ + cd tmp && 7z a -r ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.zip * + - if: (matrix.platform == 'macos') + name: Prepare artifacts (macos) + run: | + mkdir tmp + cp build/libvni.a tmp/ + cp -a build/*.dylib tmp/ + cd tmp && tar -czvf ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz * + - if: (matrix.platform == 'linux') + name: Prepare artifacts (linux) + run: | + mkdir tmp + cp build/libvni.a tmp/ + cp -a build/*.so tmp/ + cp -a build/*.so.* tmp/ + cd tmp && tar -czvf ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz * + - if: (matrix.platform == 'ios' || matrix.platform == 'ios-simulator' || matrix.platform == 'tvos') + name: Prepare artifacts (ios/tvos) + run: | + mkdir tmp + cp build/libvni.a tmp/ + cp -a build/*.dylib tmp/ + cd tmp && tar -czvf ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz * + - if: (matrix.platform == 'android') + name: Prepare artifacts (android) + run: | + mkdir tmp + cp build/libvni.a tmp/ + cp build/libvni.so tmp/ + cd tmp && tar -czvf ../libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz * + # + # upload artifacts + # + - if: (matrix.platform == 'win' || matrix.platform == 'win-mingw') + uses: actions/upload-artifact@v7 + with: + name: libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.zip + path: libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.zip + archive: false + - if: (matrix.platform != 'win' && matrix.platform != 'win-mingw') + uses: actions/upload-artifact@v7 with: - name: libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }} - path: ${{ steps.artifacts.outputs.artifact_path }} + name: libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz + path: libvni-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz + archive: false post-build: - runs-on: macos-latest + runs-on: macos-15 needs: [ version, build ] name: Build libvni-macos steps: - - uses: actions/download-artifact@v4 - - name: Unpack artifacts - run: | - cd libvni-${{ needs.version.outputs.tag }}-macos-x64 - tar -xzvf libvni-${{ needs.version.outputs.tag }}-macos-x64.tar.gz - cd .. - cd libvni-${{ needs.version.outputs.tag }}-macos-arm64 - tar -xzvf libvni-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz + - uses: actions/download-artifact@v8 + with: + name: libvni-${{ needs.version.outputs.tag }}-macos-x64.tar.gz + skip-decompress: true + - uses: actions/download-artifact@v8 + with: + name: libvni-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz + skip-decompress: true - name: Combine macos architectures run: | + mkdir macos-x64 macos-arm64 + tar -xzvf libvni-${{ needs.version.outputs.tag }}-macos-x64.tar.gz -C macos-x64 + tar -xzvf libvni-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz -C macos-arm64 mkdir tmp - lipo -create -output tmp/libvni-${{ needs.version.outputs.tag }}.dylib \ - libvni-${{ needs.version.outputs.tag }}-macos-arm64/libvni.${{ needs.version.outputs.vniversion }}.dylib \ - libvni-${{ needs.version.outputs.tag }}-macos-x64/libvni.${{ needs.version.outputs.vniversion }}.dylib - - name: Prepare artifacts - run: | - cd tmp - tar -czvf ../libvni-${{ needs.version.outputs.tag }}-macos.tar.gz * + find macos-arm64 -name "*.dylib" | while read -r file; do + if [ -L "$file" ]; then + cp -a "$file" "tmp/" + elif [ -f "$file" ]; then + filename=$(basename "$file") + lipo -create -output "tmp/$filename" \ + "macos-arm64/$filename" \ + "macos-x64/$filename" + fi + done + cd tmp && tar -czvf ../libvni-${{ needs.version.outputs.tag }}-macos.tar.gz * && cd .. - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: - name: libvni-${{ needs.version.outputs.tag }}-macos + name: libvni-${{ needs.version.outputs.tag }}-macos.tar.gz path: libvni-${{ needs.version.outputs.tag }}-macos.tar.gz - - name: Package - if: startsWith(github.ref, 'refs/tags/') - run: | - zip -r libvni-${{ needs.version.outputs.tag }}-win-x64.zip libvni-${{ needs.version.outputs.tag }}-win-x64 - zip -r libvni-${{ needs.version.outputs.tag }}-win-x86.zip libvni-${{ needs.version.outputs.tag }}-win-x86 + archive: false + - if: startsWith(github.ref, 'refs/tags/') + uses: actions/download-artifact@v8 + with: + path: release + skip-decompress: true - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') with: draft: true - files: | - libvni-${{ needs.version.outputs.tag }}-win-x64.zip - libvni-${{ needs.version.outputs.tag }}-win-x86.zip - libvni-${{ needs.version.outputs.tag }}-macos-arm64/libvni-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz - libvni-${{ needs.version.outputs.tag }}-macos-x64/libvni-${{ needs.version.outputs.tag }}-macos-x64.tar.gz - libvni-${{ needs.version.outputs.tag }}-macos.tar.gz - libvni-${{ needs.version.outputs.tag }}-linux-x64/libvni-${{ needs.version.outputs.tag }}-linux-x64.tar.gz - libvni-${{ needs.version.outputs.tag }}-linux-aarch64/libvni-${{ needs.version.outputs.tag }}-linux-aarch64.tar.gz - libvni-${{ needs.version.outputs.tag }}-ios-arm64/libvni-${{ needs.version.outputs.tag }}-ios-arm64.tar.gz - libvni-${{ needs.version.outputs.tag }}-ios-simulator-arm64/libvni-${{ needs.version.outputs.tag }}-ios-simulator-arm64.tar.gz - libvni-${{ needs.version.outputs.tag }}-tvos-arm64/libvni-${{ needs.version.outputs.tag }}-tvos-arm64.tar.gz - libvni-${{ needs.version.outputs.tag }}-android-arm64-v8a/libvni-${{ needs.version.outputs.tag }}-android-arm64-v8a.tar.gz + files: release/**/* diff --git a/CMakeLists.txt b/CMakeLists.txt index f8eb9e4..f92d33f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,16 +111,25 @@ if(BUILD_SHARED) target_include_directories(vni_shared PUBLIC ${VNI_INCLUDE_DIRS}) target_compile_definitions(vni_shared PRIVATE VNI_EXPORTS) - if(PLATFORM STREQUAL "win" AND ARCH STREQUAL "x64") + if((PLATFORM STREQUAL "win" OR PLATFORM STREQUAL "win-mingw") AND ARCH STREQUAL "x64") set(VNI_OUTPUT_NAME "vni64") else() set(VNI_OUTPUT_NAME "vni") endif() - set_target_properties(vni_shared PROPERTIES - OUTPUT_NAME ${VNI_OUTPUT_NAME} - VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} - ) + if(PLATFORM STREQUAL "win-mingw") + set_target_properties(vni_shared PROPERTIES + PREFIX "" + IMPORT_PREFIX "" + OUTPUT_NAME ${VNI_OUTPUT_NAME} + VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + ) + else() + set_target_properties(vni_shared PROPERTIES + OUTPUT_NAME ${VNI_OUTPUT_NAME} + VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + ) + endif() install(TARGETS vni_shared LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib @@ -135,8 +144,11 @@ if(BUILD_STATIC) target_include_directories(vni_static PUBLIC ${VNI_INCLUDE_DIRS}) target_compile_definitions(vni_static PUBLIC VNI_STATIC) - if(PLATFORM STREQUAL "win") - set_target_properties(vni_static PROPERTIES OUTPUT_NAME "vni_static") + if(PLATFORM STREQUAL "win" OR PLATFORM STREQUAL "win-mingw") + set_target_properties(vni_static PROPERTIES + PREFIX "" + OUTPUT_NAME "vni_static" + ) else() set_target_properties(vni_static PROPERTIES OUTPUT_NAME "vni") endif() diff --git a/README.md b/README.md index 2b16fec..66477ac 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,87 @@ A simple platform-independent conversion to C++ of the VNI converter of LibDmd w LibDmd is part of [DMD Extensions](https://github.com/freezy/dmd-extensions). The purpose of this lib is to support unprotected VNI colorizations in libdmdutil, mainly to create RGB565 dumps of colorized frames as a jump-start for the author of the VNI to convert the project into a Serum colorization. + +## Building: + +#### Windows (x64) + +```shell +cmake -G "Visual Studio 17 2022" -DPLATFORM=win -DARCH=x64 -B build +cmake --build build --config Release +``` + +#### Windows (x86) + +```shell +cmake -G "Visual Studio 17 2022" -A Win32 -DPLATFORM=win -DARCH=x86 -B build +cmake --build build --config Release +``` + +#### Windows MinGW / MSYS2 UCRT64 (x64) + +Requires MSYS2 with UCRT64 environment. Install dependencies: + +```shell +pacman -S --noconfirm \ + mingw-w64-ucrt-x86_64-gcc \ + mingw-w64-ucrt-x86_64-cmake +``` + +Build (entire build runs inside the MSYS2 UCRT64 shell): + +```shell +MSYSTEM=UCRT64 /c/msys64/usr/bin/bash.exe -l -c " + cd \"$(pwd)\" && + cmake -DCMAKE_BUILD_TYPE=Release -DPLATFORM=win-mingw -DARCH=x64 -B build && + cmake --build build -- -j\$(nproc) +" +``` + +#### Linux (x64) +```shell +cmake -DPLATFORM=linux -DARCH=x64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### Linux (aarch64) +```shell +cmake -DPLATFORM=linux -DARCH=aarch64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### MacOS (arm64) +```shell +cmake -DPLATFORM=macos -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### MacOS (x64) +```shell +cmake -DPLATFORM=macos -DARCH=x64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### iOS (arm64) +```shell +cmake -DPLATFORM=ios -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### iOS Simulator (arm64) +```shell +cmake -DPLATFORM=ios-simulator -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### tvOS (arm64) +```shell +cmake -DPLATFORM=tvos -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + +#### Android (arm64-v8a) +```shell +cmake -DPLATFORM=android -DARCH=arm64-v8a -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +```