Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
79e03c1
Update Android build to NDK 28 and system V8
matthargett Sep 28, 2025
43d677a
Improve Android V8 header discovery
matthargett Sep 28, 2025
22d1f96
Improve Android V8 header hint coverage
matthargett Sep 28, 2025
435c798
Improve Android V8 discovery for SDK 35
matthargett Sep 28, 2025
e1d0f2f
Log Android V8 search hints and broaden header discovery
matthargett Sep 28, 2025
dbef5ba
Force Android builds to use NDK r28c and API 35
matthargett Sep 30, 2025
1159300
Relax Android NDK version guard
matthargett Sep 30, 2025
39f1536
Pin Gradle NDK wiring to r28c
matthargett Oct 1, 2025
82b17e8
Improve Android NDK detection for Android tests
matthargett Oct 1, 2025
2dd6185
Simplify Android NDK environment configuration
matthargett Oct 1, 2025
98c40b5
Fix(CI): Update Android CI to use NDK 28 and API 35
google-labs-jules[bot] Oct 1, 2025
02a7dc5
Merge pull request #2 from rebeckerspecialties/feat/android-ci-update
matthargett Oct 1, 2025
99c49b1
Fix(CI): Update Android CI to use NDK 28 and API 35
google-labs-jules[bot] Oct 1, 2025
a40c852
Revise tool requirements and Android version support
matthargett Oct 2, 2025
f98247a
New Java doesn't implicitly include bind support, we have to specify …
matthargett Oct 2, 2025
7faff92
work around latent unsafe file descriptor issue that causes intermitt…
matthargett Oct 2, 2025
b3480ca
fix the C++20 libc++ deprecation issue more elegantly
matthargett Oct 2, 2025
118450b
pull in the already-existing upstream fix for compatiblity with newer…
matthargett Oct 2, 2025
4d9eb96
revert to using third aprty prebuilt v8 so we can test things more in…
matthargett Oct 2, 2025
e5e5648
fix another fdsan-found issue that causes intermittent crashes on exit
matthargett Oct 3, 2025
d205c4a
Add tests for updated JS capabilities from newer JSC. This has an apk…
matthargett Oct 3, 2025
4633fa3
JSC's results deviate from the standard. for now, let's capture both …
matthargett Oct 3, 2025
465685e
Use latest Java LTS so that modern commandline options are available,…
matthargett Oct 3, 2025
fcc3ce1
skip tests Chakra doesn't support only on win32. Chakra support is ho…
matthargett Oct 3, 2025
c1fdff4
See if reducing resource usage of the simulator helps solve the timin…
matthargett Oct 3, 2025
a54a121
Give more specific failure information when tests fail in the device …
matthargett Oct 3, 2025
be1baf6
some of these tests won't work on jsc-android
matthargett Oct 3, 2025
a6a258d
it was worth a try to test this functionality, so that Babylon Native…
matthargett Oct 8, 2025
b9aa23c
properly polyfill globalThis. add inline sourcemaps to tests so that …
matthargett Oct 9, 2025
27eed75
try a more resilient way of getting globalThis on v8 that doesn't cau…
matthargett Oct 10, 2025
9a268bb
retry websocket tests in case public echo server (or routes) are down…
matthargett Oct 10, 2025
56be206
The reason we called the log directly is because fdsan (file descript…
matthargett Oct 10, 2025
f378d3f
A race can occur in CI where the boot is completed, but package insta…
matthargett Oct 10, 2025
ed53fd9
I keep hitting totally unrelated CI flakiness. This time, it's that t…
matthargett Oct 10, 2025
863f962
Update README.md
matthargett Oct 16, 2025
2e467dd
Update README.md
matthargett Oct 16, 2025
84005c0
PR feedback
matthargett Oct 16, 2025
9e3cfc9
now that Azure pipeline uses JDK 18, we don't need this original work…
matthargett Oct 16, 2025
98e80ef
fix wrong abi being forced. pull in AndroidExtensiosn bug fix branch.
matthargett Oct 19, 2025
499ae36
I simply cannot get address sanitizer to run well under Android simul…
matthargett Oct 20, 2025
51f1f45
fix macOS build of unit tests, enable sanitizers. they are finding bu…
matthargett Oct 20, 2025
496c67f
don't put build/bundle artifacts in the source dir, put them in build…
matthargett Oct 20, 2025
403b452
make globalThis test using ifdefs in consistent way with other skippe…
matthargett Oct 20, 2025
5253492
the existing tests crash under address sanitizer when skipping a test…
matthargett Oct 20, 2025
ebf6950
fix test failure that was an issue in the test rather than the implem…
matthargett Oct 20, 2025
cfb1af6
this is a change that should be contributed to upstream node-api -- b…
matthargett Oct 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ schedules:

variables:
- name: ndkVersion
value: 25.2.9519653
value: 28.2.13676358

jobs:
# WIN32
Expand Down
73 changes: 59 additions & 14 deletions .github/jobs/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,61 @@ jobs:
timeoutInMinutes: 30

pool:
vmImage: macos-13
vmImage: macos-latest

steps:
- task: JavaToolInstaller@0
displayName: 'Set up JDK 17'
inputs:
versionSpec: '17'
jdkArchitectureOption: 'x64'
jdkSourceOption: 'PreInstalled'

- script: |
echo Install Android image
export JAVA_HOME=$JAVA_HOME_8_X64
echo 'y' | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;default;x86_64'
echo 'y' | $ANDROID_HOME/tools/bin/sdkmanager --licenses
echo Create AVD
$ANDROID_HOME/tools/bin/avdmanager create avd -n Pixel_API_27 -d pixel -k 'system-images;android-27;default;x86_64'
echo "Install NDK and Android SDK"
# Use Java 17 which is compatible with modern Android tooling
export JAVA_HOME=$JAVA_HOME_17_X64
export PATH=$JAVA_HOME/bin:$PATH

echo "Java version:"
java -version

# Use cmdline-tools instead of deprecated tools/bin path
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "ndk;$(ndkVersion)"
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "platforms;android-35"
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "build-tools;35.0.0"
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "system-images;android-35;google_apis;x86_64"
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
echo "Create AVD with Pixel 2 profile and optimized memory"
echo "no" | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n Pixel_2_API_35 -d pixel_2 -k "system-images;android-35;google_apis;x86_64"
# Optimize AVD for CI - reduce memory and disk size
echo "hw.ramSize=1024" >> ~/.android/avd/Pixel_2_API_35.avd/config.ini
echo "disk.dataPartition.size=2G" >> ~/.android/avd/Pixel_2_API_35.avd/config.ini
echo "hw.gpu.enabled=yes" >> ~/.android/avd/Pixel_2_API_35.avd/config.ini
echo "hw.gpu.mode=swiftshader_indirect" >> ~/.android/avd/Pixel_2_API_35.avd/config.ini
displayName: 'Install Android Emulator'

- script: |
echo Start emulator
nohup $ANDROID_HOME/emulator/emulator -avd Pixel_API_27 -gpu host -no-window -no-audio -no-boot-anim 2>&1 &
export JAVA_HOME=$JAVA_HOME_17_X64
export PATH=$JAVA_HOME/bin:$PATH

echo Start emulator with optimized settings
nohup $ANDROID_HOME/emulator/emulator -avd Pixel_2_API_35 -gpu swiftshader_indirect -no-window -no-audio -no-boot-anim -no-snapshot-save -memory 1024 -partition-size 2048 2>&1 &
echo Wait for emulator
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do echo '.'; sleep 1; done'
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do echo "Waiting for boot..."; sleep 2; done'

# Additional wait for package manager to be ready
echo "Waiting for package manager..."
$ANDROID_HOME/platform-tools/adb shell 'while [[ -z $(pm list packages 2>/dev/null) ]]; do sleep 2; done'

# Disable animations for test stability
$ANDROID_HOME/platform-tools/adb shell settings put global window_animation_scale 0
$ANDROID_HOME/platform-tools/adb shell settings put global transition_animation_scale 0
$ANDROID_HOME/platform-tools/adb shell settings put global animator_duration_scale 0

# Increase ADB timeout
export ADB_INSTALL_TIMEOUT=120

$ANDROID_HOME/platform-tools/adb devices
displayName: 'Start Android Emulator'

Expand All @@ -35,17 +73,24 @@ jobs:
workingDirectory: 'Tests/UnitTests/Android'
options: '-PabiFilters=x86_64 -PjsEngine=${{parameters.jsEngine}} -PndkVersion=$(ndkVersion)'
tasks: 'connectedAndroidTest'
jdkVersionOption: 1.17
jdkVersionOption: '1.17'
displayName: 'Run Connected Android Test'
retryCountOnTaskFailure: 2

- script: |
# Dump test failure details when tests fail
if [ -f ./app/build/outputs/androidTest-results/connected/TEST-*.xml ]; then
echo "=== Test Results Summary ==="
grep -h "testcase\|failure" ./app/build/outputs/androidTest-results/connected/TEST-*.xml || true
fi
# Dump logcat output which contains our detailed error messages
find ./app/build/outputs/androidTest-results -name "*.txt" -print0 | while IFS= read -r -d '' file; do
echo "cat \"$file\""
cat "$file"
echo "=== Logcat Output from: $file ==="
cat "$file" | grep -E "(FAILED|TEST FAILURES|Error:|Stack:|JsRuntimeHost)" || cat "$file"
done
workingDirectory: 'Tests/UnitTests/Android'
condition: succeededOrFailed()
displayName: 'Dump logcat from Test Results'
displayName: 'Dump test failure details and logcat'

- task: PublishBuildArtifacts@1
inputs:
Expand Down
32 changes: 30 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ FetchContent_Declare(arcana.cpp
GIT_REPOSITORY https://github.com/microsoft/arcana.cpp.git
GIT_TAG 1a8a5d6e95413ed14b38a6ac9419048f9a9c8009)
FetchContent_Declare(AndroidExtensions
GIT_REPOSITORY https://github.com/bghgary/AndroidExtensions.git
GIT_TAG 7d88a601fda9892791e7b4e994e375e049615688)
GIT_REPOSITORY https://github.com/matthargett/AndroidExtensions.git
GIT_TAG fix-stale-JNI-ref)
Comment on lines +16 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this needs to be updated once AndroidExtensions PR is merged

FetchContent_Declare(asio
GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
GIT_TAG f693a3eb7fe72a5f19b975289afc4f437d373d9c)
Expand Down Expand Up @@ -49,6 +49,19 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc")
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "Debug")
if(NOT DEFINED JSRUNTIMEHOST_NATIVE_SANITIZERS)
set(JSRUNTIMEHOST_NATIVE_SANITIZERS "address,undefined")
endif()
if(JSRUNTIMEHOST_NATIVE_SANITIZERS)
message(STATUS "macOS sanitizers enabled: ${JSRUNTIMEHOST_NATIVE_SANITIZERS}")
add_compile_options("-fsanitize=${JSRUNTIMEHOST_NATIVE_SANITIZERS}" "-fno-omit-frame-pointer")
add_link_options("-fsanitize=${JSRUNTIMEHOST_NATIVE_SANITIZERS}")
endif()
endif()
endif()
Comment on lines +52 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are sanitizers supposed to be part of this PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To some degree, yes, because NDK 28 turns some of them on by default and the crash that occurred is what got me started on that sidequest. We could override the NDK 28 default to turn off default sanitizers, and put the fixes into a separate PR. Up to you :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was curious about what could be found with sanitizers so I opened this PR : BabylonJS/BabylonNative#1559


# --------------------------------------------------
# Options
Expand Down Expand Up @@ -81,6 +94,21 @@ set_property(TARGET arcana PROPERTY FOLDER Dependencies)
if(JSRUNTIMEHOST_POLYFILL_XMLHTTPREQUEST)
FetchContent_MakeAvailable_With_Message(UrlLib)
set_property(TARGET UrlLib PROPERTY FOLDER Dependencies)
if(APPLE)
FetchContent_GetProperties(UrlLib)
if(UrlLib_POPULATED)
target_compile_options(UrlLib PRIVATE -fobjc-arc)
set(_urllib_objc_sources
"${UrlLib_SOURCE_DIR}/Source/UrlRequest_Apple.mm"
"${UrlLib_SOURCE_DIR}/Source/WebSocket_Apple.mm"
"${UrlLib_SOURCE_DIR}/Source/WebSocket_Apple_ObjC.m")
foreach(_file IN LISTS _urllib_objc_sources)
if(EXISTS "${_file}")
set_source_files_properties("${_file}" PROPERTIES COMPILE_FLAGS "-fobjc-arc")
endif()
endforeach()
endif()
endif()
Comment on lines +97 to +111
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in UrlLib itself?

endif()

if(BABYLON_DEBUG_TRACE)
Expand Down
4 changes: 2 additions & 2 deletions Core/AppRuntime/V8Inspector/Source/V8InspectorAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ namespace Babylon
}
v8::Local<v8::String> string_value = v8::Local<v8::String>::Cast(value);
int len = string_value->Length();
std::basic_string<uint16_t> buffer(len, '\0');
string_value->Write(v8::Isolate::GetCurrent(), &buffer[0], 0, len);
std::vector<uint16_t> buffer(len, 0);
string_value->Write(v8::Isolate::GetCurrent(), buffer.data(), 0, len);
return v8_inspector::StringBuffer::create(
v8_inspector::StringView(buffer.data(), len));
}
Expand Down
6 changes: 5 additions & 1 deletion Core/Node-API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ if(NAPI_BUILD_ABI)
npm(install --no-package-lock --silent WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

file(GLOB_RECURSE ANDROID_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/node_modules/${V8_PACKAGE_NAME}/${aar_path}/*.aar")
if(NOT ANDROID_ARCHIVE)
message(FATAL_ERROR "Could not find archive at ${CMAKE_CURRENT_BINARY_DIR}/node_modules/${V8_PACKAGE_NAME}/${aar_path}/*.aar")
endif()
file(ARCHIVE_EXTRACT INPUT ${ANDROID_ARCHIVE} DESTINATION ${output_directory} PATTERNS jni)
message(STATUS "Extracting ${V8_PACKAGE_NAME} archive - done")

Expand All @@ -56,7 +59,8 @@ if(NAPI_BUILD_ABI)
if(ANDROID)
set(V8_PACKAGE_NAME "jsc-android")
set(JSC_ANDROID_DIR "${CMAKE_CURRENT_BINARY_DIR}/${V8_PACKAGE_NAME}")
napi_install_android_package(jsc "dist/org/webkit/android-jsc" ${JSC_ANDROID_DIR})
# Use android-jsc-intl for full intl support
napi_install_android_package(jsc "dist/org/webkit/android-jsc-intl" ${JSC_ANDROID_DIR})

# Add `JavaScriptCore` prefix to the include path
file(RENAME "${JSC_ANDROID_DIR}/include" "${JSC_ANDROID_DIR}/JavaScriptCore")
Expand Down
14 changes: 11 additions & 3 deletions Core/Node-API/Include/Shared/napi/napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
#include <type_traits>
#include <utility>

#if defined(__clang__) || defined(__GNUC__)
#define NAPI_NO_SANITIZE_VPTR __attribute__((no_sanitize("vptr")))
#else
#define NAPI_NO_SANITIZE_VPTR
#endif

Comment on lines +22 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did these changes come from? We try to ensure these headers match the original unless it is documented as a change. Search for // [BABYLON-NATIVE-ADDITION]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the commit message, I noted that this should be upstreamed. When they cast the T down to a void* l, it loses RTTI and that trips a sanitizer. I'll add the local comment and submit a PR upstream as well.

namespace Napi {

#ifdef NAPI_CPP_CUSTOM_NAMESPACE
Expand Down Expand Up @@ -4496,7 +4502,7 @@ inline napi_value InstanceWrap<T>::WrappedMethod(
////////////////////////////////////////////////////////////////////////////////

template <typename T>
inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
inline NAPI_NO_SANITIZE_VPTR ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
napi_env env = callbackInfo.Env();
napi_value wrapper = callbackInfo.This();
napi_status status;
Expand All @@ -4510,7 +4516,7 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
}

template <typename T>
inline ObjectWrap<T>::~ObjectWrap() {
inline NAPI_NO_SANITIZE_VPTR ObjectWrap<T>::~ObjectWrap() {
// If the JS object still exists at this point, remove the finalizer added
// through `napi_wrap()`.
if (!IsEmpty() && !_finalized) {
Expand All @@ -4524,7 +4530,7 @@ inline ObjectWrap<T>::~ObjectWrap() {
}

template <typename T>
inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
inline NAPI_NO_SANITIZE_VPTR T* ObjectWrap<T>::Unwrap(Object wrapper) {
void* unwrapped;
napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped);
NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
Expand Down Expand Up @@ -6681,4 +6687,6 @@ bool Env::CleanupHook<Hook, Arg>::IsEmpty() const {

} // namespace Napi

#undef NAPI_NO_SANITIZE_VPTR

#endif // SRC_NAPI_INL_H_
18 changes: 17 additions & 1 deletion Core/Node-API/Source/js_native_api_javascriptcore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ struct napi_callback_info__ {
};

namespace {
// Minimal char_traits-like helper for JSChar (unsigned short) to compute string length at compile time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be a simple function. There is no reason for the struct or template.

template<typename CharT>
struct jschar_traits;

template<>
struct jschar_traits<JSChar> {
using char_type = JSChar;

static constexpr size_t length(const char_type* str) noexcept {
if (!str) return 0;
const char_type* s = str;
while (*s) ++s;
return s - str;
}
};

class JSString {
public:
JSString(const JSString&) = delete;
Expand All @@ -33,7 +49,7 @@ namespace {
}

JSString(const JSChar* string, size_t length = NAPI_AUTO_LENGTH)
: _string{JSStringCreateWithCharacters(string, length == NAPI_AUTO_LENGTH ? std::char_traits<JSChar>::length(string) : length)} {
: _string{JSStringCreateWithCharacters(string, length == NAPI_AUTO_LENGTH ? jschar_traits<JSChar>::length(string) : length)} {
}

~JSString() {
Expand Down
2 changes: 1 addition & 1 deletion Core/Node-API/package-jsc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"dependencies": {
"jsc-android": "250231.0.0"
"jsc-android": "294992.0.0"
}
}
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ polyfills that consumers can include if required.

## **Building - All Development Platforms**

**Required Tools:** [git](https://git-scm.com/), [CMake](https://cmake.org/), [node.js](https://nodejs.org/en/)
**Required Tools:** [git](https://git-scm.com/), [CMake 3.29 or newer](https://cmake.org/), [node.js 20.x or newer](https://nodejs.org/en/)

The first step for all development environments and targets is to clone this repository.

Expand All @@ -32,9 +32,9 @@ npm install
_Follow the steps from [All Development Platforms](#all-development-platforms) before proceeding._

**Required Tools:**
[Android Studio](https://developer.android.com/studio), [Node.js](https://nodejs.org/en/download/), [Ninja](https://ninja-build.org/)
[Android Studio](https://developer.android.com/studio) with Android NDK 28.2.13676358 and API level 35 SDK platforms installed, [Node.js 20.x or newer](https://nodejs.org/en/download/), [Ninja](https://ninja-build.org/)

The minimal requirement target is Android 5.0.
The minimal requirement target is Android 10.0, which has [~95%](https://gs.statcounter.com/android-version-market-share/mobile-tablet/worldwide) active device coverage globally. Android 10 support covers Meta Quest 1 (and newer), HTC Vive Focus 2 (and newer), and Pico 3 (and newer).

Only building with Android Studio is supported. CMake is not used directly. Instead, Gradle
is used for building and CMake is automatically invocated for building the native part.
Expand Down Expand Up @@ -68,4 +68,4 @@ Security Response Center (MSRC) at [secure@microsoft.com](mailto:secure@microsof
You should receive a response within 24 hours. If for some reason you do not, please
follow up via email to ensure we received your original message. Further information,
including the [MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) key, can
be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/default).
be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/default).
10 changes: 9 additions & 1 deletion Tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
add_subdirectory(UnitTests)
set(JSRUNTIMEHOST_OUTPUT_DIR "${CMAKE_BINARY_DIR}/Tests/UnitTests/dist")
set(JSRUNTIMEHOST_OUTPUT_DIR "${JSRUNTIMEHOST_OUTPUT_DIR}" CACHE INTERNAL "Output directory for bundled unit test scripts")
Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to set both the cache and local variable?

file(MAKE_DIRECTORY "${JSRUNTIMEHOST_OUTPUT_DIR}")
file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/UnitTests/dist")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a good idea? Seems dangerous to remove a folder in the source folder when running CMake.


set(ENV{JSRUNTIMEHOST_BUNDLE_OUTPUT} "${JSRUNTIMEHOST_OUTPUT_DIR}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, looking at this more. I didn't realize what was happening here. Looks like dist\tests.js is committed to source control, so my original comment about generated files being in the CMake binary folder does not make sense. Can you please revert the changes for this? Also, don't add the dist folder to .gitignore like you had originally. It actually needs to be included in the PR if the ts file changes.

npm(install --silent)
unset(ENV{JSRUNTIMEHOST_BUNDLE_OUTPUT})

add_subdirectory(UnitTests)
43 changes: 33 additions & 10 deletions Tests/UnitTests/Android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,56 @@ if (project.hasProperty("jsEngine")) {
jsEngine = project.property("jsEngine")
}

def targetApiLevel = 35
def requiredNdkVersion = project.findProperty("ndkVersion") ?: "28.2.13676358"

android {
namespace 'com.jsruntimehost.unittests'
compileSdk 33
ndkVersion = "23.1.7779620"
if (project.hasProperty("ndkVersion")) {
ndkVersion = project.property("ndkVersion")
}
compileSdk targetApiLevel
ndkVersion = requiredNdkVersion

defaultConfig {
applicationId "com.jsruntimehost.unittests"
minSdk 21
targetSdk 33
targetSdk targetApiLevel
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

externalNativeBuild {
cmake {
arguments (
arguments(
"-DANDROID_STL=c++_shared",
"-DNAPI_JAVASCRIPT_ENGINE=${jsEngine}",
"-DJSRUNTIMEHOST_CORE_APPRUNTIME_V8_INSPECTOR=ON"
)
}
}

if (project.hasProperty("abiFilters")) {
ndk {
abiFilters project.getProperty("abiFilters")
ndk {
def abiFiltersProp = project.findProperty("abiFilters")?.toString()
if (abiFiltersProp) {
def propFilters = abiFiltersProp.split(',').collect { it.trim() }.findAll { !it.isEmpty() }
if (!propFilters.isEmpty()) {
abiFilters(*propFilters)
}
} else {
// Prefer injected ABI hints and fall back to a host-aware default
def requestedAbi = project.findProperty("android.injected.build.abi") ?: System.getenv("ANDROID_ABI")
def defaultAbis = []
if (requestedAbi) {
defaultAbis = requestedAbi.split(',').collect { it.trim() }.findAll { !it.isEmpty() }
}
if (defaultAbis.isEmpty()) {
def hostArch = (System.getProperty("os.arch") ?: "").toLowerCase()
if (hostArch.contains("aarch64") || hostArch.contains("arm64")) {
defaultAbis = ['arm64-v8a']
} else {
defaultAbis = ['arm64-v8a', 'x86_64']
}
}
abiFilters(*defaultAbis)
Comment on lines +37 to +59
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this change?

}
}
}
Expand Down Expand Up @@ -101,3 +121,6 @@ tasks.configureEach { task ->
task.dependsOn(copyScripts)
}
}

// Note: The Android Gradle Plugin should handle NDK location automatically
// If you encounter NDK issues, ensure you have NDK 28.2.13676358 installed via SDK Manager
Loading
Loading