Skip to content

Commit e79a4e3

Browse files
authored
Monorepo step 3: vendor JsRuntimeHost and UrlLib with full file history (#1947)
*[Updated by Copilot on behalf of @bghgary]* Brings JsRuntimeHost and UrlLib into BabylonNative so changes to these components and their consumers can be reviewed together. **Merge without squashing.** The original repository-import ancestry is retained; subsequent feedback fixes are consolidated, with the bgfx integration in a separate commit. The repository currently permits only squash merges, so landing requires enabling a history-preserving merge method. ### Worth a look - The bgfx wrapper includes the unmerged [upstream proposal](bkaradzic/bgfx.cmake#108). See `Dependencies/CMakeLists.txt` for BabylonNative's revision choices and wrapper adaptations. - Source-package consumers must adapt to the dependency layout: the tracked wrapper and fetched bx, bimg, and bgfx sources are packaged separately. - Component tests follow `BABYLON_NATIVE_BUILD_APPS` on supported platforms. Android and iOS execution covers JsRuntimeHost, not BabylonNative's renderer or UrlLib's standalone suite. - Win32 x86 and Windows Store x64 JSI/V8 configurations are restored in pull-request checks. Sanitizer coverage is in the Azure Pipelines nightly, not the pull-request workflow.
2 parents db5c5e9 + da9131c commit e79a4e3

317 files changed

Lines changed: 57170 additions & 1264 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitattributes‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@
22
*.h diff
33
*.java diff
44
*.txt diff
5-
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Build mobile unit-test artifacts
2+
description: Build a component's platform test project and publish its artifacts.
3+
4+
inputs:
5+
component:
6+
required: true
7+
description: Component whose test project is built (JsRuntimeHost)
8+
platform:
9+
required: true
10+
description: Android or iOS
11+
js-engine:
12+
default: JavaScriptCore
13+
description: JavaScript engine used by this platform configuration
14+
deployment-target:
15+
default: '26.0'
16+
description: Minimum iOS simulator version
17+
18+
runs:
19+
using: composite
20+
steps:
21+
# Each component/platform pair names its existing Gradle or CMake test project
22+
# and outputs; the shared steps below configure, build, package and upload them.
23+
- name: Select ${{ inputs.component }} ${{ inputs.platform }} test project
24+
id: project
25+
shell: bash
26+
env:
27+
COMPONENT: ${{ inputs.component }}
28+
PLATFORM: ${{ inputs.platform }}
29+
JS_ENGINE: ${{ inputs.js-engine }}
30+
run: |
31+
case "$COMPONENT/$PLATFORM" in
32+
JsRuntimeHost/Android)
33+
project=Dependencies/JsRuntimeHost/Tests/UnitTests/Source/Android
34+
echo "gradle-project=$project" >> "$GITHUB_OUTPUT"
35+
;;
36+
JsRuntimeHost/iOS)
37+
build=build/mobile-tests-JsRuntimeHost
38+
echo "cmake-source=Dependencies/JsRuntimeHost" >> "$GITHUB_OUTPUT"
39+
echo "cmake-build=$build" >> "$GITHUB_OUTPUT"
40+
echo "cmake-args=-DNAPI_JAVASCRIPT_ENGINE=$JS_ENGINE -DJSRUNTIMEHOST_TESTS=ON" >> "$GITHUB_OUTPUT"
41+
echo "cmake-target=UnitTests" >> "$GITHUB_OUTPUT"
42+
echo "app=$build/Tests/UnitTests/RelWithDebInfo-iphonesimulator/UnitTests.app" >> "$GITHUB_OUTPUT"
43+
;;
44+
*)
45+
echo "::error::No $PLATFORM test project is defined for $COMPONENT"
46+
exit 1
47+
;;
48+
esac
49+
- name: Build and package Android ${{ inputs.component }} unit tests
50+
if: inputs.platform == 'Android'
51+
shell: bash
52+
env:
53+
PROJECT: ${{ steps.project.outputs.gradle-project }}
54+
JS_ENGINE: ${{ inputs.js-engine }}
55+
DESTINATION: test-artifacts/${{ inputs.component }}
56+
run: |
57+
bash .github/scripts/build-android-tests.sh "$PROJECT" "$JS_ENGINE" "$DESTINATION"
58+
- name: Configure iOS simulator ${{ inputs.component }} unit tests
59+
if: inputs.platform == 'iOS'
60+
shell: bash
61+
env:
62+
SOURCE: ${{ steps.project.outputs.cmake-source }}
63+
BUILD: ${{ steps.project.outputs.cmake-build }}
64+
PROJECT_ARGS: ${{ steps.project.outputs.cmake-args }}
65+
DEPLOYMENT_TARGET: ${{ inputs.deployment-target }}
66+
run: |
67+
cmake -S "$SOURCE" -B "$BUILD" -G Xcode \
68+
-DIOS=ON -DPLATFORM=SIMULATORARM64 \
69+
"-DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET" $PROJECT_ARGS
70+
- name: Build iOS simulator ${{ inputs.component }} unit tests
71+
if: inputs.platform == 'iOS'
72+
shell: bash
73+
env:
74+
BUILD: ${{ steps.project.outputs.cmake-build }}
75+
TARGET: ${{ steps.project.outputs.cmake-target }}
76+
run: |
77+
cmake --build "$BUILD" --config RelWithDebInfo --target "$TARGET" -- \
78+
-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' \
79+
CODE_SIGNING_ALLOWED=NO
80+
- name: Package iOS unit-test artifacts
81+
if: inputs.platform == 'iOS'
82+
shell: bash
83+
env:
84+
DESTINATION: test-artifacts/${{ inputs.component }}
85+
APP: ${{ steps.project.outputs.app }}
86+
run: |
87+
mkdir -p "$DESTINATION"
88+
tar -czf "$DESTINATION/app.tar.gz" -C "$(dirname "$APP")" "$(basename "$APP")"
89+
- uses: actions/upload-artifact@v6
90+
with:
91+
name: UnitTests-${{ inputs.platform }}-${{ inputs.component }}-${{ inputs.js-engine }}
92+
path: test-artifacts/${{ inputs.component }}
93+
if-no-files-found: error
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
project="${1:?Expected Gradle project directory}"
5+
engine="${2:?Expected JavaScript engine}"
6+
destination="${3:?Expected artifact directory}"
7+
8+
echo "y" | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "ndk;27.2.12479018" "cmake;3.30.3"
9+
bash "$project/gradlew" -p "$project" -PabiFilters=x86_64 -PndkVersion=27.2.12479018 \
10+
"-PjsEngine=$engine" assembleDebug assembleDebugAndroidTest
11+
12+
mkdir -p "$destination"
13+
cp "$project/app/build/outputs/apk/debug/app-debug.apk" "$destination/app.apk"
14+
cp "$project/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk" "$destination/tests.apk"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
artifact_root="${1:?Expected artifact directory}"
5+
shift
6+
if [[ $# -eq 0 ]]; then
7+
echo "Expected at least one JavaScript engine" >&2
8+
exit 1
9+
fi
10+
11+
mkdir -p test-results
12+
trap 'adb logcat -d > test-results/logcat.txt' EXIT
13+
ready=false
14+
for ((attempt = 0; attempt < 60; attempt++)); do
15+
connectivity=$(timeout 10s adb shell dumpsys connectivity)
16+
active=$(sed -n 's/^Active default network: \([0-9][0-9]*\).*$/\1/p' <<< "$connectivity")
17+
if [[ -n "$active" ]] && grep -F 'NetworkAgentInfo{' <<< "$connectivity" |
18+
grep -F "network{$active}" | grep -w VALIDATED > /dev/null; then
19+
ready=true
20+
break
21+
fi
22+
sleep 2
23+
done
24+
if [[ "$ready" != true ]]; then
25+
echo "::error::Emulator network did not become ready"
26+
printf '%s\n' "$connectivity"
27+
exit 1
28+
fi
29+
30+
shopt -s nullglob
31+
artifacts=("$artifact_root"/*)
32+
if [[ ${#artifacts[@]} -ne $# ]]; then
33+
echo "::error::Expected exactly $# Android artifacts"
34+
exit 1
35+
fi
36+
for engine in "$@"; do
37+
directory="$artifact_root/UnitTests-Android-JsRuntimeHost-$engine"
38+
test -f "$directory/app.apk"
39+
test -f "$directory/tests.apk"
40+
done
41+
42+
failed=()
43+
application=com.jsruntimehost.unittests
44+
for engine in "$@"; do
45+
name="UnitTests-Android-JsRuntimeHost-$engine"
46+
directory="$artifact_root/$name"
47+
echo "::group::Running $name"
48+
set +e
49+
(
50+
set -euo pipefail
51+
installed=()
52+
trap 'code=$?; for package in "${installed[@]}"; do timeout 120s adb uninstall "$package" || code=1; done; exit "$code"' EXIT
53+
timeout 120s adb install -r "$directory/app.apk"
54+
installed+=("$application")
55+
timeout 120s adb install -r "$directory/tests.apk"
56+
installed=("$application.test" "$application")
57+
timeout 120s adb shell pm clear "$application"
58+
timeout 20m adb shell am instrument -w -r \
59+
"$application.test/androidx.test.runner.AndroidJUnitRunner" 2>&1 | tee "test-results/$name.log"
60+
grep -Eq '^OK \([1-9][0-9]* tests?\)[[:space:]]*$' "test-results/$name.log"
61+
grep -Eq '^INSTRUMENTATION_CODE: -1[[:space:]]*$' "test-results/$name.log"
62+
)
63+
result=$?
64+
set -e
65+
if [[ $result -ne 0 ]]; then
66+
echo "::error::$name failed (exit $result)"
67+
failed+=("$name")
68+
fi
69+
echo "::endgroup::"
70+
done
71+
if [[ ${#failed[@]} -ne 0 ]]; then
72+
printf 'Failed: %s\n' "${failed[@]}"
73+
exit 1
74+
fi

‎.github/tsan_suppressions.txt‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# JavaScriptCore GTK race reports can be attributed to libc interceptors instead
2+
# of the library, so function-name suppressions are needed alongside library matching.
3+
called_from_lib:libjavascriptcoregtk
4+
race:free
5+
race:close
6+
race:memcpy
7+
8+
# Suppress JavaScriptCore GTK signal handlers that do not preserve errno.
9+
signal:libjavascriptcoregtk

‎.github/workflows/build-android.yml‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ env:
1919
jobs:
2020
build:
2121
runs-on: ${{ inputs.runs-on }}
22-
timeout-minutes: 45
22+
timeout-minutes: 120
2323
steps:
2424
- uses: actions/checkout@v5
2525

26-
2726
- uses: actions/setup-java@v5
2827
with:
2928
distribution: temurin
@@ -80,6 +79,13 @@ jobs:
8079
-PSANITIZERS=OFF
8180
ccache --show-stats
8281
82+
- name: Build unit-test artifacts
83+
uses: ./.github/actions/build-mobile-tests
84+
with:
85+
component: JsRuntimeHost
86+
platform: Android
87+
js-engine: ${{ inputs.js-engine }}
88+
8389
- name: Save ccache
8490
if: ${{ github.event_name == 'push' && success() }}
8591
uses: actions/cache/save@v5

‎.github/workflows/build-ios.yml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ env:
2323
jobs:
2424
build:
2525
runs-on: ${{ inputs.runs-on }}
26-
timeout-minutes: 30
26+
timeout-minutes: 120
2727
steps:
2828
- uses: actions/checkout@v5
2929

@@ -49,3 +49,10 @@ jobs:
4949
-sdk iphoneos \
5050
-configuration Release \
5151
CODE_SIGNING_ALLOWED=NO
52+
53+
- name: Build unit-test artifacts
54+
uses: ./.github/actions/build-mobile-tests
55+
with:
56+
component: JsRuntimeHost
57+
platform: iOS
58+
deployment-target: ${{ inputs.deployment-target }}

‎.github/workflows/build-linux.yml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ jobs:
175175
ulimit -c unlimited
176176
xvfb-run --auto-servernum ./ModuleLoadTest
177177
178+
- name: JsRuntimeHost Unit Tests
179+
working-directory: build/Linux/Dependencies/JsRuntimeHost/Tests/UnitTests
180+
run: |
181+
ulimit -c unlimited
182+
xvfb-run --auto-servernum ./JsRuntimeHostUnitTests
183+
184+
- name: UrlLib Unit Tests
185+
working-directory: build/Linux/Dependencies/UrlLib/Tests
186+
run: ./UrlLibTests
187+
178188
- name: Upload Vulkan Test Results
179189
if: ${{ always() && inputs.graphics-api == 'Vulkan' }}
180190
uses: actions/upload-artifact@v6
@@ -210,3 +220,7 @@ jobs:
210220
build/Linux/Apps/UnitTests/core.*
211221
build/Linux/Apps/ModuleLoadTest/ModuleLoadTest
212222
build/Linux/Apps/ModuleLoadTest/core.*
223+
build/Linux/Dependencies/JsRuntimeHost/Tests/UnitTests/JsRuntimeHostUnitTests
224+
build/Linux/Dependencies/JsRuntimeHost/Tests/UnitTests/core.*
225+
build/Linux/Dependencies/UrlLib/Tests/UrlLibTests
226+
build/Linux/Dependencies/UrlLib/Tests/core.*

‎.github/workflows/build-macos.yml‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ jobs:
6161
- name: Build ModuleLoadTest macOS
6262
run: cmake --build build/macOS --target ModuleLoadTest --config RelWithDebInfo
6363

64+
- name: Build component unit tests
65+
run: cmake --build build/macOS --target JsRuntimeHostUnitTests UrlLibTests --config RelWithDebInfo
66+
6467
- name: Enable Core Dump
6568
run: sudo sysctl -w kern.corefile=%N.core.%P
6669

@@ -77,6 +80,16 @@ jobs:
7780
ulimit -c unlimited
7881
./ModuleLoadTest
7982
83+
- name: Run JsRuntimeHost Unit Tests
84+
working-directory: build/macOS/Dependencies/JsRuntimeHost/Tests/UnitTests/RelWithDebInfo
85+
run: |
86+
ulimit -c unlimited
87+
./JsRuntimeHostUnitTests
88+
89+
- name: Run UrlLib Unit Tests
90+
working-directory: build/macOS/Dependencies/UrlLib/Tests/RelWithDebInfo
91+
run: ./UrlLibTests
92+
8093
- name: Upload UnitTests Core Dumps
8194
if: failure()
8295
uses: actions/upload-artifact@v6
@@ -85,3 +98,7 @@ jobs:
8598
path: |
8699
build/macOS/Apps/UnitTests/RelWithDebInfo/UnitTests
87100
build/macOS/Apps/UnitTests/RelWithDebInfo/*.core.*
101+
build/macOS/Dependencies/JsRuntimeHost/Tests/UnitTests/RelWithDebInfo/JsRuntimeHostUnitTests
102+
build/macOS/Dependencies/JsRuntimeHost/Tests/UnitTests/RelWithDebInfo/*.core.*
103+
build/macOS/Dependencies/UrlLib/Tests/RelWithDebInfo/UrlLibTests
104+
build/macOS/Dependencies/UrlLib/Tests/RelWithDebInfo/*.core.*

‎.github/workflows/build-uwp.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ jobs:
3131
if [ "${{ inputs.napi-type }}" = "jsi" ]; then
3232
echo "suffix=_JSI" >> "$GITHUB_OUTPUT"
3333
echo "define=-DNAPI_JAVASCRIPT_ENGINE=JSI" >> "$GITHUB_OUTPUT"
34+
elif [ "${{ inputs.napi-type }}" = "V8" ]; then
35+
echo "suffix=_V8" >> "$GITHUB_OUTPUT"
36+
echo "define=-DNAPI_JAVASCRIPT_ENGINE=V8" >> "$GITHUB_OUTPUT"
3437
else
3538
echo "suffix=" >> "$GITHUB_OUTPUT"
3639
echo "define=" >> "$GITHUB_OUTPUT"

0 commit comments

Comments
 (0)