diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b080df6e9..fda5d5dab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,375 +20,6 @@ env: VULKAN_VERSION: 1.4.363.1 jobs: - linux-clang: - runs-on: ubuntu-26.04 - name: Linux Clang - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - double_precision: [No, Yes] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} clang++-${{env.UBUNTU_CLANG_VERSION}} -DDOUBLE_PRECISION=${{matrix.double_precision}} - - name: Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - linux-clang-check-global-new: - runs-on: ubuntu-26.04 - name: Linux Clang Check Global New - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh Debug clang++-${{env.UBUNTU_CLANG_VERSION}} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON - - name: Check Global New - working-directory: ${{github.workspace}}/Build - run: ./check_global_new.sh Linux_Debug clang-query-${{env.UBUNTU_CLANG_VERSION}} - - linux_clang_tsan: - runs-on: ubuntu-26.04 - name: Linux Clang Sanitizers - strategy: - fail-fast: false - matrix: - build_type: [ReleaseASAN, ReleaseUBSAN, ReleaseTSAN] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} clang++-${{env.UBUNTU_CLANG_VERSION}} -DTARGET_VIEWER=OFF -DTARGET_SAMPLES=OFF -DTARGET_HELLO_WORLD=OFF -DTARGET_UNIT_TESTS=ON -DTARGET_PERFORMANCE_TEST=ON - - name: Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Unit Tests - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - name: Test ConvexVsMesh - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ./PerformanceTest -q=LinearCast -t=max -s=ConvexVsMesh - - name: Test Ragdoll - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ./PerformanceTest -q=LinearCast -t=max -s=Ragdoll - - linux-clang-so: - runs-on: ubuntu-26.04 - name: Linux Clang Shared Library - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} clang++-${{env.UBUNTU_CLANG_VERSION}} -DBUILD_SHARED_LIBS=YES - - name: Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - linux-clang-32-bit: - runs-on: ubuntu-26.04 - name: Linux Clang 32-bit - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Update APT - run: sudo apt update - - name: Install G++-Multilib - run: sudo apt -y install g++-multilib - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} clang++-${{env.UBUNTU_CLANG_VERSION}} -DCMAKE_CXX_FLAGS=-m32 -DUSE_SSE4_1=OFF -DUSE_SSE4_2=OFF -DUSE_AVX=OFF -DUSE_AVX2=OFF -DUSE_AVX512=OFF -DUSE_LZCNT=OFF -DUSE_TZCNT=OFF -DUSE_F16C=OFF -DUSE_FMADD=OFF - - name: Build - run: cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - linux-gcc: - runs-on: ubuntu-26.04 - name: Linux GCC - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} g++-${{env.UBUNTU_GCC_VERSION}} - - name: Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - linux-gcc-so: - runs-on: ubuntu-26.04 - name: Linux GCC Shared Library - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./cmake_linux_clang_gcc.sh ${{matrix.build_type}} g++-${{env.UBUNTU_GCC_VERSION}} -DBUILD_SHARED_LIBS=Yes - - name: Build - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - msys2_mingw_gcc: - runs-on: windows-2025-vs2026 - defaults: - run: - shell: msys2 {0} - name: MSYS2 MinGW GCC - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release] - shared_lib: [No, Yes] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 - with: - msystem: ucrt64 - install: mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake - update: true - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_linux_mingw.sh ${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_lib}} - - name: Build - run: cmake --build Build/MinGW_${{matrix.build_type}} -j $(nproc) - - name: Test - working-directory: Build/MinGW_${{matrix.build_type}} - run: ctest --output-on-failure --verbose - - msvc_cl: - runs-on: windows-2025-vs2026 - name: Visual Studio CL - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - double_precision: [No, Yes] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_cl.bat -DDOUBLE_PRECISION=${{matrix.double_precision}} - - name: Build - run: msbuild Build\VS2026_CL\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - name: Test - working-directory: ${{github.workspace}}/Build/VS2026_CL/${{matrix.build_type}} - run: ./UnitTests.exe - - msvc_cl_no_object_stream: - runs-on: windows-2025-vs2026 - name: Visual Studio CL - No Object Stream - strategy: - fail-fast: false - matrix: - build_type: [Debug, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_cl.bat -DENABLE_OBJECT_STREAM=NO - - name: Build - run: msbuild Build\VS2026_CL\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - name: Test - working-directory: ${{github.workspace}}/Build/VS2026_CL/${{matrix.build_type}} - run: ./UnitTests.exe - - msvc_cl_dll: - runs-on: windows-2025-vs2026 - name: Visual Studio CL Shared Library - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_cl.bat -DBUILD_SHARED_LIBS=Yes - - name: Build - run: msbuild Build\VS2026_CL\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - name: Test - working-directory: ${{github.workspace}}/Build/VS2026_CL/${{matrix.build_type}} - run: ./UnitTests.exe - - msvc_cl_32_bit: - runs-on: windows-2025-vs2026 - name: Visual Studio CL 32-bit - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_cl_32bit.bat - - name: Build - run: msbuild Build\VS2026_CL_32BIT\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - name: Test - working-directory: ${{github.workspace}}/Build/VS2026_CL_32BIT/${{matrix.build_type}} - run: ./UnitTests.exe - - msvc_cl_arm: - runs-on: windows-2025-vs2026 - name: Visual Studio CL ARM - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_cl_arm.bat - - name: Build - run: msbuild Build\VS2026_CL_ARM\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - msvc_clang: - runs-on: windows-2025-vs2026 - name: Visual Studio Clang - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - double_precision: [No, Yes] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v3 - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_vs2026_clang.bat -DDOUBLE_PRECISION=${{matrix.double_precision}} - - name: Build - run: msbuild Build\VS2026_Clang\JoltPhysics.slnx /property:Configuration=${{matrix.build_type}} -m - - name: Test - working-directory: ${{github.workspace}}/Build/VS2026_Clang/${{matrix.build_type}} - run: ./UnitTests.exe - - macos: - runs-on: macos-latest - name: macOS - env: - VULKAN_SDK_INSTALL: ${{github.workspace}}/vulkan_sdk - strategy: - fail-fast: false - matrix: - build_type: [Debug, Release, Distribution] - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Install Metal Toolchain - run: xcodebuild -downloadComponent MetalToolchain - - name: Install Vulkan - run: ${{github.workspace}}/Build/macos_install_vulkan_sdk.sh ${VULKAN_SDK_INSTALL} - - name: Configure CMake - run: | - source ${VULKAN_SDK_INSTALL}/setup-env.sh - cmake -B ${{github.workspace}}/Build/MacOS_${{matrix.build_type}} -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_CXX_COMPILER=clang++ Build - - name: Build - run: cmake --build ${{github.workspace}}/Build/MacOS_${{matrix.build_type}} -j $(sysctl -n hw.ncpu) - - name: Test - working-directory: ${{github.workspace}}/Build/MacOS_${{matrix.build_type}} - run: | - source ${VULKAN_SDK_INSTALL}/setup-env.sh - ctest --output-on-failure --verbose - android: runs-on: ubuntu-26.04 name: Android @@ -403,50 +34,21 @@ jobs: with: distribution: 'temurin' java-version: '17' - - name: Install Vulkan - run: ${{github.workspace}}/Build/ubuntu26_install_vulkan_sdk.sh ${{env.VULKAN_VERSION}} - name: Gradle Build working-directory: ${{github.workspace}}/Build/Android - run: | - source $HOME/vulkan/${{env.VULKAN_VERSION}}/setup-env.sh - ./gradlew build --no-daemon - - ios: - runs-on: macos-latest - name: iOS - strategy: - fail-fast: false - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Configure CMake - run: cmake -B ${{github.workspace}}/Build/XCode_iOS -DTARGET_HELLO_WORLD=OFF -DTARGET_PERFORMANCE_TEST=OFF -DCMAKE_SYSTEM_NAME=iOS -GXcode Build - - name: Build - run: cmake --build ${{github.workspace}}/Build/XCode_iOS -- -sdk iphonesimulator -arch arm64 -j $(sysctl -n hw.ncpu) - - emscripten: - runs-on: ubuntu-26.04 - name: Emscripten - - steps: - - name: Checkout Code - uses: actions/checkout@v7 - - name: Setup emsdk - uses: mymindstorm/setup-emsdk@v16 + run: ./gradlew :UnitTests:assembleDebug -Pandroid.injected.build.abi=x86_64 --no-daemon + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Run Unit Tests + timeout-minutes: 30 + uses: reactivecircus/android-emulator-runner@v2 with: - version: ${{env.EMSCRIPTEN_VERSION}} - - name: Verify emsdk - run: emcc -v - - name: Setup Node.js ${{env.NODE_VERSION}} - uses: actions/setup-node@v7 - with: - node-version: ${{env.NODE_VERSION}} - - name: Configure CMake - working-directory: ${{github.workspace}}/Build - run: ./cmake_linux_emscripten.sh Distribution -DTARGET_HELLO_WORLD=OFF -DTARGET_PERFORMANCE_TEST=OFF - - name: Build - run: cmake --build ${{github.workspace}}/Build/WASM_Distribution -j $(nproc) - - name: Test - working-directory: ${{github.workspace}}/Build/WASM_Distribution - run: node UnitTests.js + api-level: 34 + arch: x86_64 + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim + disable-animations: true + script: ${{github.workspace}}/Build/Android/run_unit_tests.sh ${{github.workspace}}/Build/Android/UnitTests/build/intermediates/apk/debug/UnitTests-debug.apk 600 + diff --git a/.github/workflows/determinism_check.yml b/.github/workflows/determinism_check.yml.bak similarity index 100% rename from .github/workflows/determinism_check.yml rename to .github/workflows/determinism_check.yml.bak diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml.bak similarity index 100% rename from .github/workflows/doxygen.yml rename to .github/workflows/doxygen.yml.bak diff --git a/.github/workflows/sonar-cloud.yml b/.github/workflows/sonar-cloud.yml.bak similarity index 100% rename from .github/workflows/sonar-cloud.yml rename to .github/workflows/sonar-cloud.yml.bak diff --git a/Build/Android/run_unit_tests.sh b/Build/Android/run_unit_tests.sh new file mode 100755 index 000000000..7d7b7cdde --- /dev/null +++ b/Build/Android/run_unit_tests.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Installs the unit test APK on the connected device / emulator, runs it and fails (exit code 1) if the unit tests failed. +# Usage: run_unit_tests.sh [timeout in seconds] + +APK="$1" +TIMEOUT="${2:-900}" + +if [ -z "$APK" ] || [ ! -f "$APK" ]; then + echo "Usage: $0 [timeout in seconds]" + exit 2 +fi + +adb install -t -r "$APK" || exit 2 +adb logcat -c +adb shell am start -n com.joltphysics.unittests/android.app.NativeActivity || exit 2 + +# Wait for the app to report its result +RESULT="" +for ((i = 0; i < TIMEOUT; i++)); do + RESULT=$(adb logcat -d -s Jolt:I | grep -F "UNIT_TESTS_RESULT:" | tail -n 1) + [ -n "$RESULT" ] && break + sleep 1 +done + +# Show the full log of the test run +adb logcat -d -s Jolt:I + +if [ -z "$RESULT" ]; then + echo "Unit tests did not finish within $TIMEOUT seconds (or crashed)" + adb logcat -d -s AndroidRuntime:E DEBUG:I libc:F + exit 1 +fi + +if [[ "$RESULT" == *"PASSED"* ]]; then + echo "Unit tests passed" + exit 0 +fi + +echo "::error::Android unit tests failed" +exit 1 diff --git a/Build/README.md b/Build/README.md index e4bc557aa..25641dec4 100644 --- a/Build/README.md +++ b/Build/README.md @@ -168,7 +168,7 @@ To implement your custom memory allocator override Allocate, Free, Reallocate, A
  • If you want to build the Samples, install the Vulkan SDK (required to compile the shaders)
  • Open the 'Build/Android' folder in Android Studio and wait until gradle finishes
  • Select 'Run' and 'UnitTests', 'PerformanceTest' or 'Samples'
  • -
  • For the UnitTests: If the screen turns green after a while the unit tests succeeded, when red they failed (see the android log for details)
  • +
  • For the UnitTests: The application exits when the unit tests complete. Look at the Android logs to see if they succeeded or failed. You can also run Build/Android/run_unit_tests.sh
  • The Samples use Vulkan for rendering. Touch input is mapped to mouse and keyboard input:
    • One finger drag: Rotate the camera / interact with the menu (drag vertically to scroll long menus)
    • diff --git a/UnitTests/UnitTestFramework.cpp b/UnitTests/UnitTestFramework.cpp index 5246dbb3d..1081c545a 100644 --- a/UnitTests/UnitTestFramework.cpp +++ b/UnitTests/UnitTestFramework.cpp @@ -12,7 +12,6 @@ #include #endif // JPH_PLATFORM_WINDOWS #ifdef JPH_PLATFORM_ANDROID -#include #include #include #endif // JPH_PLATFORM_ANDROID @@ -286,52 +285,18 @@ void AndroidInitialize(android_app *inApp) context.addFilter("reporters", "android_log"); int return_value = context.run(); - // Color the screen according to the test result - JPH::Color color = return_value == 0? JPH::Color::sGreen : JPH::Color::sRed; - ANativeWindow_acquire(inApp->window); - ANativeWindow_Buffer buffer; - ARect bounds; - ANativeWindow_lock(inApp->window, &buffer, &bounds); - switch (buffer.format) - { - case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: - case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: - { - uint32 color_u32 = color.GetUInt32(); - for (int y = 0; y < buffer.height; ++y) - { - uint32 *dest = (uint32 *)((uint8 *)buffer.bits + y * buffer.stride * sizeof(uint32)); - for (int x = 0; x < buffer.width; ++x) - *dest++ = color_u32; - } - break; - } - - case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: - { - uint16 color_u16 = (color.b >> 3) + ((color.g >> 2) << 5) + ((color.r >> 3) << 11); - for (int y = 0; y < buffer.height; ++y) - { - uint16 *dest = (uint16 *) ((uint8 *) buffer.bits + y * buffer.stride * sizeof(uint16)); - for (int x = 0; x < buffer.width; ++x) - *dest++ = color_u16; - } - break; - } - - default: - // TODO implement - break; - } - ANativeWindow_unlockAndPost(inApp->window); - ANativeWindow_release(inApp->window); - // Unregisters all types with the factory and cleans up the default material UnregisterTypes(); // Destroy the factory delete Factory::sInstance; Factory::sInstance = nullptr; + + // Report the result in the log (this is what the CI looks for, the exit code of a NativeActivity is not visible through adb) + __android_log_print(return_value == 0? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "Jolt", "UNIT_TESTS_RESULT: %s (return value %d)", return_value == 0? "PASSED" : "FAILED", return_value); + + // Exit the process with the doctest return value + exit(return_value); } // Handle callback from Android