BabylonJS / BabylonNative

Build cross-platform native applications with the power of the Babylon.js JavaScript framework
MIT License
779 stars 133 forks source link

Binary packages : AAR, pod, nuget #1446

Open CedricGuillemet opened 1 week ago

CedricGuillemet commented 1 week ago

Following this PR that adds .aar android package build: https://github.com/BabylonJS/BabylonNative/pull/1440

Next steps to improve integration ease into user land projects:

Unkowns

Technical questions/small tasks:

iOS

Windows/Nuget

BRN

Next steps:

okwasniewski commented 4 days ago

Hey @CedricGuillemet,

I'm experimenting with the AAR and wanted to create a prebuilt for React Native.

As I understand the flow would be to:

  1. Prebuild .AAR file with NAPI_JAVASCRIPT_ENGINE set as JSI
  2. Integrate .aar file with React Native
  3. Use the Wrapper and Engine View making the integration significantly easier.

I'm hitting issues on the first step, when I set the variable I'm getting this error:

CMake Error at /Users/okwasniewski/workspace/Babylon/BabylonNative/Build/Android/Debug/1s1i656w/x86/_deps/jsruntimehost-src/Core/Node-API-JSI/CMakeLists.txt:55 (message):
  jsi target is required : com.android.ide.common.process.ProcessException: -- Android: Targeting API '24' with architecture 'x86', ABI 'x86', and processor 'i686'

I guess I need to have JSI linked, which means that prebuilding won't be possible for React Native? Or do you have some idea how to make this work?

I've tried to reference JSI in the CMake file of Babylon Native (just for testing) but it didn't work:

add_subdirectory(/Users/okwasniewski/workspace/react-native/packages/react-native/ReactCommon/jsi/jsi
 ${CMAKE_CURRENT_BINARY_DIR}/jsi)
target_include_directories(jsi INTERFACE /Users/okwasniewski/workspace/react-native/packages/react-native/ReactCommon/jsi)

Can you point me in the right direction on how to get the AAR prebuild working?

okwasniewski commented 4 days ago

As an additional context I was able to take the build the AAR file, reference it in a React Native project:

implementation files('libs/BabylonNative-release.aar')

Render the Engine View that Babylon Native provides and load scripts using the view.loadScript method:

engineView.loadScript("app:///Scripts/experience.js")

And it worked! Making the integration way simpler (Great work on that btw!)

image

Now its the matter of having JSI in the middle 😅

CedricGuillemet commented 4 days ago

And it worked! Making the integration way simpler (Great work on that btw!)

That's excellent news! Yes, integration should be a lot easier and it should be possible to do the same for other platforms as well. Correct me if I'm wrong @bghgary but JSI with napi is waiting for some tasks to be done in the RN team. I don't think it's possible to precompile for JSI at the moment. This said, is it possible to test android + jsi with BabylonNative CI ?

okwasniewski commented 3 days ago

@CedricGuillemet @bghgary any chance you can share what are the prerequisites for getting this prebuilt JSI to work? I think this is crucial for the new architecture to work properly, moving most of the integration layer back to Babylon Native would make it a lot easier.

For now I'm struggling with getting new architecture to work properly due to some internal stack corruption errors..

I wanted to explore whether using your work on AAR this might make the new architecture migration easier.

I've been trying out different ways of getting the prebuild of JSI to work, I think I'm getting there, this is a hacky way of getting this working there but we can polish the build system once it works.

I've been modifying this file:

https://github.com/BabylonJS/BabylonNative/blob/master/Apps/Playground/Android/BabylonNative/CMakeLists.txt

set(REACT_NATIVE_PATH "~/workspace/react-native/packages/react-native" CACHE PATH "Path to React Native source")

# Add all JSI dependencies

add_subdirectory("${REACT_NATIVE_PATH}/ReactAndroid/src/main/jni/third-party/folly" 
                 "${CMAKE_CURRENT_BINARY_DIR}/folly")

add_subdirectory("${REACT_NATIVE_PATH}/ReactAndroid/src/main/jni/third-party/boost" 
                 "${CMAKE_CURRENT_BINARY_DIR}/boost")

add_subdirectory("${REACT_NATIVE_PATH}/ReactAndroid/src/main/jni/third-party/fmt" 
                 "${CMAKE_CURRENT_BINARY_DIR}/fmt")

add_subdirectory("${REACT_NATIVE_PATH}/ReactAndroid/src/main/jni/third-party/double-conversion" 
                 "${CMAKE_CURRENT_BINARY_DIR}/double-conversion")

add_subdirectory("${REACT_NATIVE_PATH}/ReactAndroid/src/main/jni/third-party/glog" 
                 "${CMAKE_CURRENT_BINARY_DIR}/glog")

add_subdirectory("${REACT_NATIVE_PATH}/ReactCommon/jsi" 
                 "${CMAKE_CURRENT_BINARY_DIR}/jsi")

target_include_directories(BabylonNativeJNI
    PRIVATE "${REACT_NATIVE_PATH}/ReactCommon"
    PRIVATE "${REACT_NATIVE_PATH}/ReactCommon/jsi")

target_link_libraries(BabylonNativeJNI
    GLESv3
    android
    EGL
    log
    jsi # Add jsi here
    -lz
    AndroidExtensions
    AppRuntime
    Canvas
    Console
    GraphicsDevice
    NativeCamera
    NativeEngine
    NativeInput
    NativeOptimizations
    NativeXr
    ScriptLoader
    XMLHttpRequest
    Window)

It looks like this is almost working, Im still struggling with the error that V8JsiRuntime.h is missing. Do you have an idea why that might be missing? It looks like it comes from the configuration of Babylon Native.

/Users/okwasniewski/workspace/Babylon/BabylonNative/Build/Android/RelWithDebInfo/3q27672l/arm64-v8a/_deps/jsruntimehost-src/Core/AppRuntime/Source/AppRuntime_JSI.cpp:5:10: fatal error: 'V8JsiRuntime.h' file not found
#include <V8JsiRuntime.h>
         ^~~~~~~~~~~~~~~~

Also I noticed that the new Babylon Native wrapper doesn't have methods to interface with JSI, should we create new ones? Where we will probably pass some JSI instance etc.? Just how the old Babylon React Native integration worked?