Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
61 changes: 60 additions & 1 deletion .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@ env:
jobs:
build:
runs-on: ${{ inputs.runs-on }}
timeout-minutes: 45
timeout-minutes: ${{ inputs.runs-on == 'ubuntu-latest' && 90 || 45 }}
steps:
- uses: actions/checkout@v5

# The Hermes host-compiler bootstrap, four ABIs of NDK output and an
# emulator image together fill the default hosted runner disk; reclaim the
# unused toolchains before anything is downloaded.
- name: Free disk space
if: inputs.js-engine == 'Hermes' && runner.os == 'Linux'
uses: jlumbroso/free-disk-space@v1.3.1
with:
tool-cache: false
large-packages: false
# Must stay false: this would delete /usr/local/lib/android, i.e. the
# SDK the Gradle build and the emulator both need.
android: false

- uses: actions/setup-java@v5
with:
Expand All @@ -48,3 +60,50 @@ jobs:
-PARM64Only \
-PNDK_VERSION=${{ env.NDK_VERSION }} \
-PSANITIZERS=OFF
# reactivecircus/android-emulator-runner needs /dev/kvm to be writable by
# the runner user; the hosted Ubuntu image ships it root-only. macOS
# runners have no KVM, so the emulator run is Linux only.
- name: Enable KVM group permissions
if: runner.os == 'Linux'
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
# Apps/UnitTests on the emulator. This covers the JsRuntimeHost suites
# only: the Babylon Native graphics suites need a desktop window and
# graphics device, so BABYLON_NATIVE_UNIT_TESTS_GRAPHICS is off here.
- name: Run UnitTests on the emulator
if: runner.os == 'Linux'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 33
target: google_apis
arch: x86_64
force-avd-creation: false
emulator-options: -no-snapshot -no-window -gpu swiftshader_indirect -no-boot-anim -no-audio
disable-animations: true
working-directory: Apps/UnitTests/Android
# NOTE: android-emulator-runner runs this script one line at a time
# through `sh -c`, so backslash line continuations do not work here.
script: |
chmod +x gradlew
./gradlew connectedAndroidTest -PabiFilters=x86_64 -PjsEngine=${{ inputs.js-engine }} -PNDK_VERSION=${{ env.NDK_VERSION }}
- name: Dump UnitTests results
if: always() && runner.os == 'Linux'
working-directory: Apps/UnitTests/Android
run: |
find app/build/outputs/androidTest-results/connected -name '*.xml' -print -exec cat {} \; || true
- name: Upload UnitTests report
if: always() && runner.os == 'Linux'
uses: actions/upload-artifact@v6
with:
name: android-unittests-${{ inputs.js-engine }}-${{ inputs.runs-on }}
path: |
Apps/UnitTests/Android/app/build/reports/androidTests/**
Apps/UnitTests/Android/app/build/outputs/androidTest-results/**
if-no-files-found: ignore
32 changes: 32 additions & 0 deletions .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ on:
required: false
type: string
default: macos-latest
simulator:
required: false
type: string
default: 'iPhone 17'

# Absorb transient npm registry / CDN flakes during `npm install` in Apps/CMakeLists.txt.
# npm's default fetch-retries is 2; bump to 5 (npm's own exponential backoff handles spacing).
Expand Down Expand Up @@ -47,3 +51,31 @@ jobs:
-sdk iphoneos \
-configuration Release \
CODE_SIGNING_ALLOWED=NO
# The UnitTests app contains the JsRuntimeHost suites only; the Babylon
# Native graphics suites need a desktop window/graphics host, so
# BABYLON_NATIVE_UNIT_TESTS_GRAPHICS defaults to OFF here.
#
# ARCHS is forced to arm64: ios-cmake's OS64COMBINED hardcodes
# ARCHS[sdk=iphonesimulator*]=x86_64, which is wrong on Apple silicon
# runners and makes the link fail against the arm64-only SDK stubs.
- name: Build UnitTests iOS
run: |
xcodebuild \
-project build/iOS/BabylonNative.xcodeproj \
-scheme UnitTests \
-sdk iphonesimulator \
-configuration Release \
ARCHS=arm64 \
VALID_ARCHS=arm64 \
ONLY_ACTIVE_ARCH=NO \
CODE_SIGNING_ALLOWED=NO
- name: Boot Simulator
run: xcrun simctl boot "${{ inputs.simulator }}"

- name: Run UnitTests iOS
run: |
xcrun simctl install booted "build/iOS/Apps/UnitTests/Release-iphonesimulator/UnitTests.app"
xcrun simctl launch --console booted "com.babylonnative.unittests" 2> /tmp/exitCode
(exit $(cat /tmp/exitCode))
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
deployment-target: "26.0"
xcode-version: "26.4"
runs-on: macos-26
simulator: "iPhone 17"

MacOS_QuickJS:
uses: ./.github/workflows/build-macos.yml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/build
/Build
.DS_Store
.vscode
9 changes: 8 additions & 1 deletion Apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ if(NOT ANDROID)
endif()

if((WIN32 AND NOT WINDOWS_STORE) OR (APPLE AND NOT IOS AND NOT VISIONOS) OR (UNIX AND NOT ANDROID AND NOT APPLE))
add_subdirectory(UnitTests)
add_subdirectory(ModuleLoadTest)
endif()

# The unit tests build on every platform. Whether they include the Babylon
# Native graphics suites on top of the JsRuntimeHost suites is decided by
# BABYLON_NATIVE_UNIT_TESTS_GRAPHICS. Android drives them through the Gradle
# harness in UnitTests/Android instead of an executable target.
if(NOT ANDROID AND NOT VISIONOS)
add_subdirectory(UnitTests)
endif()

if((WIN32 AND NOT WINDOWS_STORE AND GRAPHICS_API STREQUAL D3D11) OR (APPLE AND NOT IOS AND NOT VISIONOS))
if(BABYLON_NATIVE_PLUGIN_SHADERCACHE AND BABYLON_NATIVE_PLUGIN_SHADERTOOL AND NOT BABYLON_NATIVE_PLUGIN_NATIVEENGINE_COMPILESHADERS)
add_subdirectory(PrecompiledShaderTest)
Expand Down
51 changes: 49 additions & 2 deletions Apps/HeadlessScreenshotApp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
FetchContent_Declare(DirectXTK
GIT_REPOSITORY https://github.com/microsoft/DirectXTK.git
GIT_TAG e7d9b64ca6bb8977d4e3006727deaf57a7c1de84)
GIT_TAG e7d9b64ca6bb8977d4e3006727deaf57a7c1de84
# Populate the source tree without configuring it: the shaders have to be
# compiled before DirectXTK's own CMakeLists.txt is processed (see below).
SOURCE_SUBDIR DoNotConfigure)

FetchContent_MakeAvailable(CMakeExtensions)
include(${CMAKE_CURRENT_LIST_DIR}/../../Scripts/extensions.cmake)

set(BUILD_TESTING OFF)
set(BUILD_TOOLS OFF)
Expand All @@ -11,6 +14,50 @@ set(DIRECTX_ARCH ${CMAKE_VS_PLATFORM_NAME})

FetchContent_MakeAvailable_With_Message(DirectXTK)

# DirectXTK compiles its HLSL shaders from a custom build step that runs
# `cmake -E env ... CompileShaders.cmd` with a *relative* command name and
# relies on the Windows SDK bin directory being on PATH. Neither holds here:
# CMake no longer resolves a relative command against WORKING_DIRECTORY, and
# the custom build step doesn't inherit a developer command prompt, so fxc.exe
# isn't found. Compile the shaders ourselves at configure time (absolute paths,
# explicitly located fxc.exe) and hand the result to DirectXTK through its
# USE_PREBUILT_SHADERS / COMPILED_SHADERS contract.
set(DIRECTXTK_COMPILED_SHADERS "${directxtk_BINARY_DIR}/Shaders/Compiled")
if(NOT EXISTS "${DIRECTXTK_COMPILED_SHADERS}/SpriteEffect_SpriteVertexShader.inc")
find_program(FXC_EXECUTABLE fxc
HINTS
"$ENV{WindowsSdkVerBinPath}/${CMAKE_VS_PLATFORM_NAME}"
"$ENV{WindowsSdkDir}bin/${CMAKE_VS_PLATFORM_NAME}"
PATHS
"$ENV{ProgramFiles\(x86\)}/Windows Kits/10/bin/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/${CMAKE_VS_PLATFORM_NAME}"
"$ENV{ProgramFiles}/Windows Kits/10/bin/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/${CMAKE_VS_PLATFORM_NAME}")
if(NOT FXC_EXECUTABLE)
message(FATAL_ERROR "fxc.exe (Windows SDK HLSL compiler) is required to build DirectXTK shaders but was not found.")
endif()

cmake_path(GET FXC_EXECUTABLE PARENT_PATH FXC_DIR)
file(MAKE_DIRECTORY "${DIRECTXTK_COMPILED_SHADERS}")

message(STATUS "Compiling DirectXTK shaders")
execute_process(
COMMAND "${CMAKE_COMMAND}" -E env
"CompileShadersOutput=${DIRECTXTK_COMPILED_SHADERS}"
"PATH=${FXC_DIR};$ENV{PATH}"
"${directxtk_SOURCE_DIR}/Src/Shaders/CompileShaders.cmd"
WORKING_DIRECTORY "${directxtk_SOURCE_DIR}/Src/Shaders"
OUTPUT_FILE "${DIRECTXTK_COMPILED_SHADERS}/compileshaders.log"
ERROR_FILE "${DIRECTXTK_COMPILED_SHADERS}/compileshaders.log"
RESULT_VARIABLE DIRECTXTK_SHADERS_RESULT)
if(NOT DIRECTXTK_SHADERS_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to compile DirectXTK shaders (${DIRECTXTK_SHADERS_RESULT}). See ${DIRECTXTK_COMPILED_SHADERS}/compileshaders.log")
endif()
message(STATUS "Compiling DirectXTK shaders - done")
endif()

set(USE_PREBUILT_SHADERS ON)
set(COMPILED_SHADERS "${DIRECTXTK_COMPILED_SHADERS}")
add_subdirectory("${directxtk_SOURCE_DIR}" "${directxtk_BINARY_DIR}")

set_property(TARGET DirectXTK PROPERTY FOLDER Apps/Dependencies)

set(BABYLON_SCRIPTS
Expand Down
10 changes: 10 additions & 0 deletions Apps/UnitTests/Android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.iml
.gradle/
.idea/
local.properties

app/.cxx/
app/build/
app/src/main/assets

build/
125 changes: 125 additions & 0 deletions Apps/UnitTests/Android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
plugins {
id 'com.android.application'
}

def jsEngine = "V8"
if (project.hasProperty("jsEngine")) {
jsEngine = project.property("jsEngine")
}

def cmakeArguments = [
"-DANDROID_STL=c++_shared",
"-DENABLE_PCH=OFF",
"-DNAPI_JAVASCRIPT_ENGINE=${jsEngine}",
"-DJSRUNTIMEHOST_CORE_APPRUNTIME_V8_INSPECTOR=ON"
]
// Hermes for Android needs HOST hermesc/shermes (they emit bytecode at build
// time and can't run as NDK-cross-compiled binaries). The CMake scripts
// bootstrap these host compilers automatically when cross-compiling, so no
// hand-off is normally required. This property is an optional manual override:
// pass -PimportHostCompilers=<ImportHostCompilers.cmake> to reuse a prebuilt
// host-compiler set and skip the in-CMake bootstrap.
if (project.hasProperty("importHostCompilers")) {
cmakeArguments.add("-DIMPORT_HOST_COMPILERS=${project.property('importHostCompilers')}")
}

android {
namespace = 'com.babylonnative.unittests'
compileSdk = 34

defaultConfig {
applicationId = "com.babylonnative.unittests"
minSdk = 25
targetSdk = 33
versionCode = 1
versionName = "1.0"

ndkVersion = "29.0.14206865"
if (project.hasProperty("NDK_VERSION")) {
ndkVersion = project.property("NDK_VERSION")
}

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

externalNativeBuild {
cmake {
arguments(*cmakeArguments)
cppFlags += ["-Wno-deprecated-literal-operator"]
}
}

if (project.hasProperty("abiFilters")) {
ndk {
abiFilters project.getProperty("abiFilters")
}
}
}

externalNativeBuild {
cmake {
path = file('src/main/cpp/CMakeLists.txt')
buildStagingDirectory = "../../../../Build/Android"
version = '3.22.1+'
}
}

packaging {
jniLibs {
pickFirsts += ['lib/*/libv8android.so', 'lib/*/libjsc.so', 'lib/*/libc++_shared.so']
}
}

buildTypes {
release {
minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.5.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

// The JS bundle and the data files the suite loads over app:/// have to end up
// in the APK's assets under the same layout the desktop build stages next to
// the executable (Assets/ and Scripts/).
tasks.register('copyScripts') {
doLast {
copy {
from '../../JavaScript/dist'
include "tests.jsRuntime.js"
into 'src/main/assets/Assets'
}
copy {
from '../../Assets'
include "*.*"
into 'src/main/assets/Assets'
}
copy {
from '../../Scripts'
include "*.js"
into 'src/main/assets/Scripts'
}
}
}

// Run copyScripts after the CMake external build, and make sure asset merging
// happens after the copy.
tasks.configureEach { task ->
if (task.name == 'mergeDebugNativeLibs') {
task.finalizedBy(copyScripts)
}
if (task.name == 'mergeDebugAssets') {
task.dependsOn(copyScripts)
}
}
21 changes: 21 additions & 0 deletions Apps/UnitTests/Android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading