From 1c20f46887b1a8f40a859514d6372bc6b7ad038a Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Fri, 25 Apr 2025 14:56:06 +0200 Subject: [PATCH] ci : enable bindings java job (#3070) * ci : re-enable bindings-java (java) job This commit re-enables the job previously name `java` which was disabled in the build.yml file. The motivation for this is that we recently fixed a few issue in the java bindings and it should be possible to build them on windows. Refs: https://github.com/ggerganov/whisper.cpp/pull/2949 Resolves: https://github.com/ggerganov/whisper.cpp/issues/2781 --- .github/workflows/build.yml | 166 +++++++++++++----- CMakeLists.txt | 16 ++ bindings/java/build.gradle | 30 +++- .../whispercpp/WhisperCppJnaLibrary.java | 1 + 4 files changed, 162 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8e3a955..553fc0c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -561,6 +561,7 @@ jobs: run: > cmake -S . -B ./build -A ${{ matrix.arch }} -DCMAKE_BUILD_TYPE=${{ matrix.build }} + -DBUILD_SHARED_LIBS=ON -DWHISPER_SDL2=${{ matrix.sdl2 }} - name: Build @@ -572,12 +573,37 @@ jobs: if: matrix.sdl2 == 'ON' run: copy "$env:SDL2_DIR/../lib/${{ matrix.s2arc }}/SDL2.dll" build/bin/${{ matrix.build }} - - name: Upload dll + - name: Upload SDL2.dll + if: matrix.sdl2 == 'ON' uses: actions/upload-artifact@v4 with: - name: ${{ matrix.jnaPath }}_whisper.dll + name: ${{ matrix.s2arc }}_SDL2.dll + path: build/bin/${{ matrix.build }}/SDL2.dll + + - name: Upload whisper dll + uses: actions/upload-artifact@v4 + with: + name: whisper_${{ matrix.arch }}.dll path: build/bin/${{ matrix.build }}/whisper.dll + - name: Upload ggml dll + uses: actions/upload-artifact@v4 + with: + name: ggml_${{ matrix.arch }}.dll + path: build/bin/${{ matrix.build }}/ggml.dll + + - name: Upload ggml base dll + uses: actions/upload-artifact@v4 + with: + name: ggml_base_${{ matrix.arch }}.dll + path: build/bin/${{ matrix.build }}/ggml-base.dll + + - name: Upload ggml cpu dll + uses: actions/upload-artifact@v4 + with: + name: ggml_cpu_${{ matrix.arch }}.dll + path: build/bin/${{ matrix.build }}/ggml-cpu.dll + - name: Upload binaries if: matrix.sdl2 == 'ON' uses: actions/upload-artifact@v4 @@ -996,49 +1022,99 @@ jobs: chmod +x ./gradlew ./gradlew assembleRelease -# TODO: disabled because of following fail: https://github.com/ggerganov/whisper.cpp/actions/runs/9686220096/job/26735899598 -# java: -# needs: [ 'windows' ] -# runs-on: windows-latest -# steps: -# - uses: actions/checkout@v4 -# -# - name: Install Java -# uses: actions/setup-java@v4 -# with: -# distribution: zulu -# java-version: 20 -# -# - name: Download Windows lib -# uses: actions/download-artifact@v4 -# with: -# name: win32-x86-64_whisper.dll -# path: bindings/java/build/generated/resources/main/win32-x86-64 -# -# - name: Build -# run: | -# models\download-ggml-model.cmd tiny.en -# cd bindings/java -# chmod +x ./gradlew -# ./gradlew build -# -# - name: Upload jar -# uses: actions/upload-artifact@v4 -# with: -# name: whispercpp.jar -# path: bindings/java/build/libs/whispercpp-*.jar -# -# - name: Publish package -# if: ${{ github.ref == 'refs/heads/master' }} -# uses: gradle/gradle-build-action@v2.4.2 -# with: -# arguments: publish -# build-root-directory: bindings/java -# env: -# MAVEN_USERNAME: ${{ secrets.JIRA_USER }} -# MAVEN_PASSWORD: ${{ secrets.JIRA_PASS }} -# PGP_SECRET: ${{ secrets.GPG_PRIVATE_KEY }} -# PGP_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + bindings-java: + if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' || + github.event.inputs.run_type == 'full-ci' }} + needs: ['windows'] + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Java + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: 20 + + - name: Download Whisper Windows lib + uses: actions/download-artifact@v4 + with: + name: whisper_x64.dll + + - name: Download GGML Windows lib + uses: actions/download-artifact@v4 + with: + name: ggml_x64.dll + + - name: Download GGML Base Windows lib + uses: actions/download-artifact@v4 + with: + name: ggml_base_x64.dll + + - name: Download GGML CPU Windows lib + uses: actions/download-artifact@v4 + with: + name: ggml_cpu_x64.dll + + - name: Download SDL2.dll + uses: actions/download-artifact@v4 + with: + name: x64_SDL2.dll + + - name: List downloaded files + shell: pwsh + run: | + Get-ChildItem -Path "." -Recurse -Filter "*.dll" + + - name: Move DLL to correct location + shell: pwsh + run: | + New-Item -Path "build\bin\Release" -ItemType Directory -Force + + Copy-Item -Path "whisper.dll" -Destination "build\bin\Release\whisper.dll" -Force + Write-Host "Copied whisper.dll to build\bin\Release\whisper.dll directory" + + Copy-Item -Path "ggml.dll" -Destination "build\bin\Release\ggml.dll" -Force + Write-Host "Copied ggml.dll to build\bin\Release\ggml.dll directory" + + Copy-Item -Path "ggml-base.dll" -Destination "build\bin\Release\ggml-base.dll" -Force + Write-Host "Copied ggml-base.dll to build\bin\Release\ggml-base.dll directory" + + Copy-Item -Path "ggml-cpu.dll" -Destination "build\bin\Release\ggml-cpu.dll" -Force + Write-Host "Copied ggml-cpu.dll to build\bin\Release\ggml-cpu.dll directory" + + Copy-Item -Path "SDL2.dll" -Destination "build\bin\Release\SDL2.dll" -Force + Write-Host "Copied SDL2.dll to build\bin\Release\SDL2.dll directory" + + - name: List build release files + shell: pwsh + run: | + Get-ChildItem -Path "build\Release" -Recurse -Filter "*.dll" + + - name: Build + run: | + models\download-ggml-model.cmd tiny.en models/ + cd bindings/java + chmod +x ./gradlew + ./gradlew build --info + + - name: Upload jar + uses: actions/upload-artifact@v4 + with: + name: whispercpp.jar + path: bindings/java/build/libs/whispercpp-*.jar + + - name: Publish package + if: ${{ github.ref == 'refs/heads/master' }} + uses: gradle/gradle-build-action@v2.4.2 + with: + arguments: publish + build-root-directory: bindings/java + env: + MAVEN_USERNAME: ${{ secrets.JIRA_USER }} + MAVEN_PASSWORD: ${{ secrets.JIRA_PASS }} + PGP_SECRET: ${{ secrets.GPG_PRIVATE_KEY }} + PGP_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} quantize: if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' || diff --git a/CMakeLists.txt b/CMakeLists.txt index be6db903..34ef7958 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,22 @@ if (NOT TARGET ggml) add_library(ggml ALIAS ggml::ggml) else() add_subdirectory(ggml) + if(WIN32) + # The following adds a _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR macro and is a workaround for + # the Windows C++ standard library which does not support constexpr mutexes. + # From the release notes://github.com/microsoft/STL/wiki/Changelog + # Disable constexpr mutex constructor on Windows + # Fixed mutex's constructor to be constexpr. #3824 #4000 #4339 + # Note: Programs that aren't following the documented restrictions on binary compatibility may encounter + # null dereferences in mutex machinery. You must follow this rule: + # When you mix binaries built by different supported versions of the toolset, the Redistributable version + # must be at least as new as the latest toolset used by any app component. + # You can define _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR as an escape hatch. + # + # Specifically to whisper.cpp this would cause a crash when using the Java bindings. + # resulting in a Invalid memory access error. + target_compile_definitions(ggml-base PRIVATE _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) + endif() endif() # ... otherwise assume ggml is added by a parent CMakeLists.txt endif() diff --git a/bindings/java/build.gradle b/bindings/java/build.gradle index eb1a5c07..30184eed 100644 --- a/bindings/java/build.gradle +++ b/bindings/java/build.gradle @@ -27,23 +27,41 @@ sourceSets { tasks.register('copyLibwhisperDynlib', Copy) { from '../../build/src' include 'libwhisper.dylib' - into 'build/generated/resources/main/darwin' + into 'build/generated/resources/main' } tasks.register('copyLibwhisperSo', Copy) { from '../../build/src' include 'libwhisper.so' - into 'build/generated/resources/main/linux-x86-64' + into 'build/generated/resources/main' } -tasks.register('copyWhisperDll', Copy) { - from '../../build/Release' +tasks.register('copyWhisperDLL', Copy) { + from '../../build/bin/Release' include 'whisper.dll' - into 'build/generated/resources/main/windows-x86-64' + into 'build/generated/resources/main' +} + +tasks.register('copyGGML_BASE_DLL', Copy) { + from '../../build/bin/Release' + include 'ggml-base.dll' + into 'build/generated/resources/main' +} + +tasks.register('copyGGML_DLL', Copy) { + from '../../build/bin/Release' + include 'ggml.dll' + into 'build/generated/resources/main' +} + +tasks.register('copyGGML_CPU_DLL', Copy) { + from '../../build/bin/Release' + include 'ggml-cpu.dll' + into 'build/generated/resources/main' } tasks.register('copyLibs') { - dependsOn copyLibwhisperDynlib, copyLibwhisperSo, copyWhisperDll + dependsOn copyLibwhisperDynlib, copyLibwhisperSo, copyWhisperDLL, copyGGML_BASE_DLL, copyGGML_DLL, copyGGML_CPU_DLL } test { diff --git a/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java b/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java index 1cd2449f..690f1bd5 100644 --- a/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java +++ b/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java @@ -9,6 +9,7 @@ import io.github.ggerganov.whispercpp.params.WhisperContextParams; import io.github.ggerganov.whispercpp.params.WhisperFullParams; public interface WhisperCppJnaLibrary extends Library { + WhisperCppJnaLibrary instance = Native.load("whisper", WhisperCppJnaLibrary.class); String whisper_print_system_info();