Installing BabylonNative on Linux

I’m trying to use BabylonNative on Linux from an App that has it’s own rather complex build system and set of dependencies. Is there an installer that installs BabylonNative shared libraries and includes in a standard way so that it can be used from other projects that may not use cmake?

Ideally I’d like to be able to use a package manager to install babylonnative. Something like:

apt install babylonnative

A related question, is that assume that an App uses CMake, but that the App lives outside the BabylonNative hierarchy. Is it easy to make that work? It’s pretty awkward when building a real App to arrange that it lives inside the BabylonNative hierarchy and build system.

Forgive me if these are naive questions.

adding @bghgary

No, there currently is not a prebuilt version of Babylon Native.

We’ve talked about publishing to a package. The main reason for not doing it is that there are so many different permutations. Currently, we are only considering publishing packages for integrations (like Babylon React Native) where the permutations are more manageable.

It shouldn’t be hard if you are using CMake. We need samples for this (cc @DarraghBurke). See Build System and Extensions for information about extending Babylon Native, which may help with building an App externally also.

@bghgary My external app is using CMake for the build.

What I’m currently doing is constructing a docker image that has all the BabylonNative dependencies and that has a pre-built version of BabylonNative, including source. i.e. as part of building the image I pulled the latest BabylonNative and built it, so source binaries exist on the image.

I’m using that as the base image for building my app.

I’m new to CMake, so I’m not sure how to go about creating the dependencies on BabylonNative so that my app can find headers and shared libraries on the image.

My first attempt was to try and use include_directories to specify the location of all the directories my app will depend on. Likewise for shared libraries.

For example:

include_directories( 
    "/thirdparty/BabylonNative/Core/AppRuntime/Include"
    "/thirdparty/BabylonNative/Core/JsRuntime/Include"
    "/thirdparty/BabylonNative/Dependencies/napi/napi-jsi/include"
)

But that seems pretty painful, and didn’t seem to be working. So now I’m wondering if I can do something like this.

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(BABYLON_NATIVE_PLATFORM "Unix")

add_subdirectory(/thirdparty/BabylonNative/Dependencies EXCLUDE_FROM_ALL)
add_subdirectory(/thirdparty/BabylonNative/Core EXCLUDE_FROM_ALL)
add_subdirectory(/thirdparty/BabylonNative/Plugins EXCLUDE_FROM_ALL)
add_subdirectory(/thirdparty/BabylonNative/Polyfills EXCLUDE_FROM_ALL)

But as yet I haven’t been able to get this to work either.

Can you give me some guidance as to the general approach and maybe the specific CMake commands that I should be looking at?

For now, I think it will be easier to put our App in the BabylonNative Apps folder, when building the Dokcer build image. But it would be nice to have an external example!

You should be able to add BabylonNative as a dependency by simply doing:

add_subdirectory(/thirdparty/BabylonNative EXCLUDE_FROM_ALL)

Then make sure to add BabylonNative as a dependency to your target. CMake should handle what folders to include and what libraries to add. Have you tried that?

@bghgary I did the following.

add_subdirectory(/BabylonNative ./build EXCLUDE_FROM_ALL)
add_executable(render3d src/main.cpp src/Process.cpp src/Renderer.cpp)
target_link_libraries (render3d ${Boost_LIBRARIES} ${CPPREST_LIB} ${ZLIB_LIBRARIES} OpenSSL::SSL glog ${OpenCV_LIBS} protobuf ${AWSSDK_LINK_LIBRARIES} sensei)
add_dependencies(render3d BabylonNative)

But I get the following error during the build.

#10 2.261 CMake Error at CMakeLists.txt:36 (add_dependencies):
#10 2.261   The dependency target "BabylonNative" of target "render3d" does not exist.

Is this how I should add the depencency on BabylonNative?

I think it is because BabylonNative is the name of a project, but not a target. add_dependencies takes targets. I think for this to work we would need to add a custom target in the root CMakeLists.txt file for BabylonNative.

@bghgary do you agree?

I forked the BabylonNative repo and added the following line to the root level CMakeLists.txt.

add_custom_target(BabylonNative ALL)

The following lines in my CMakeLists.txt are meant to pull in the BabylonNative dependencies.

add_subdirectory(/BabylonNative ./build EXCLUDE_FROM_ALL)
add_executable(render3d src/main.cpp src/Process.cpp src/Renderer.cpp)
target_link_libraries (render3d ${Boost_LIBRARIES} ${CPPREST_LIB} ${ZLIB_LIBRARIES} OpenSSL::SSL glog ${OpenCV_LIBS} protobuf ${AWSSDK_LINK_LIBRARIES} sensei)
add_dependencies(render3d BabylonNative)

This got me past the “target does not exist” error, but BabylonNative header files are still not found in building components in my app.

#11 0.412 /usr/bin/clang++ -DAWS_COMMON_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 -DAWS_SDK_VERSION_MINOR=8 -DAWS_SDK_VERSION_PATCH=139 -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_CHRONO_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_IOSTREAMS_DYN_LINK -DBOOST_LOG_DYN_LINK -DBOOST_LOG_SETUP_DYN_LINK -DBOOST_RANDOM_DYN_LINK -DBOOST_REGEX_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -DBOOST_TIMER_DYN_LINK -I/sensei -O3 -DNDEBUG -pthread -std=gnu++17 -MD -MT CMakeFiles/render3d.dir/src/Renderer.cpp.o -MF CMakeFiles/render3d.dir/src/Renderer.cpp.o.d -o CMakeFiles/render3d.dir/src/Renderer.cpp.o -c ../src/Renderer.cpp
#11 0.412 ../src/Renderer.cpp:20:10: fatal error: 'Babylon/AppRuntime.h' file not found
#11 0.412 #include <Babylon/AppRuntime.h>
#11 0.412          ^~~~~~~~~~~~~~~~~~~~~~

@bghgary you said, “Then make sure to add BabylonNative as a dependency to your target. CMake should handle what folders to include and what libraries to add.” I assumed that the add_dependencies command would do that, but it appears that all the add_dependencies command does is to arrange that the dependencies are built before the specified target. I don’t think it does anything in terms of taking care of includes and libraries.

How should I add BabylonNative as a dependency of my target?

@bghgary I got it building and linking by using the custom extension to CMake in BabylonNative. I added the following line and that set up the includes and library dependencies.

target_link_to_dependencies(render3d PRIVATE AppRuntime)

I know I’ll have to add additional targets. My app doesn’t do anything yet except for include some Babylon headers.

Progress!

Yes. You are on the right track. Sorry, I’ve been in meetings all day or I would have helped a bit. :slight_smile:

You should look at how the Playground pulls in the targets. We intentionally made all of the components as loosely coupled as possible so that you can pull in only the components you care about.

BabylonNative/CMakeLists.txt at master · BabylonJS/BabylonNative (github.com)

target_link_to_dependencies is a custom function that @syntheticmagus created that will also copy files along with the code dependency. You don’t have to use that if you don’t want to. Then it’s just a matter of bringing the components you need/want.

No problem. Thanks for any help you can offer, whenever.

I added a few lines of real code to my app, to take another baby step. (Linux App)

XInitThreads();
Display* display = XOpenDisplay(NULL);

Now I’m getting the following link error, which I assume has to do with either a settings mismatch or a versioning problem. I’m getting a bunch of these. This is just a sample. Although they are all related to bgfx.

I haven’t discovered which yet.

#11 41.42 /usr/bin/ld: build/Dependencies/bgfx.cmake/libbx.a(debug.cpp.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
#11 41.42 /usr/bin/ld: build/Dependencies/bgfx.cmake/libbx.a(dtoa.cpp.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC

There are a lot of compiler settings in Dependencies/CMakeLists.txt. But I assume those will get picked up.

Would you be able to share a repro?

My app is in an internal enterprise git repo. I could try to strip out internal dependencies and post it to github repo. But first let me update you on where I am. In comparing the build.ninja file for my app, to the build.ninja file for a standard BabylonNative build, I discovered that for some reason the ninja build triggered from my external app attempts to build bgfx as a shared library, while the standard BabylonNative build, builds it as a static library. So far, I haven’t found any other differences, which is a little strange.

#############################################
# Link the shared library build/Dependencies/bgfx.cmake/libbgfx.so

build build/Dependencies/bgfx.cmake/libbgfx.so: CXX_SHARED_LIBRARY_LINKER__bgfx_ build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/bgfx.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/debug_renderdoc.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/dxgi.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_egl.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_glx.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_html5.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_wgl.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/nvapi.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d11.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d12.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d9.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_gl.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_gnm.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_noop.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_nvn.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_vk.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_webgpu.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_dx9bc.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_dxbc.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_spirv.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/topology.cpp.o build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/vertexlayout.cpp.o | build/Dependencies/bgfx.cmake/libbx.a build/Dependencies/bgfx.cmake/libbimg.a /usr/lib/x86_64-linux-gnu/libX11.so /usr/lib/x86_64-linux-gnu/libGL.so build/Dependencies/bgfx.cmake/libastc-codec.a build/Dependencies/bgfx.cmake/libastc.a build/Dependencies/bgfx.cmake/libedtaa3.a build/Dependencies/bgfx.cmake/libetc1.a build/Dependencies/bgfx.cmake/libetc2.a build/Dependencies/bgfx.cmake/libiqa.a build/Dependencies/bgfx.cmake/libsquish.a build/Dependencies/bgfx.cmake/libnvtt.a build/Dependencies/bgfx.cmake/libbx.a build/Dependencies/bgfx.cmake/libpvrtc.a || build/Dependencies/bgfx.cmake/libastc-codec.a build/Dependencies/bgfx.cmake/libastc.a build/Dependencies/bgfx.cmake/libbimg.a build/Dependencies/bgfx.cmake/libbx.a build/Dependencies/bgfx.cmake/libedtaa3.a build/Dependencies/bgfx.cmake/libetc1.a build/Dependencies/bgfx.cmake/libetc2.a build/Dependencies/bgfx.cmake/libiqa.a build/Dependencies/bgfx.cmake/libnvtt.a build/Dependencies/bgfx.cmake/libpvrtc.a build/Dependencies/bgfx.cmake/libsquish.a
  LINK_LIBRARIES = -Wl,-rpath,/sensei:  build/Dependencies/bgfx.cmake/libbx.a  build/Dependencies/bgfx.cmake/libbimg.a  -lX11  -lGL  build/Dependencies/bgfx.cmake/libastc-codec.a  build/Dependencies/bgfx.cmake/libastc.a  build/Dependencies/bgfx.cmake/libedtaa3.a  build/Dependencies/bgfx.cmake/libetc1.a  build/Dependencies/bgfx.cmake/libetc2.a  build/Dependencies/bgfx.cmake/libiqa.a  build/Dependencies/bgfx.cmake/libsquish.a  build/Dependencies/bgfx.cmake/libnvtt.a  build/Dependencies/bgfx.cmake/libbx.a  -pthread  -ldl  -lrt  build/Dependencies/bgfx.cmake/libpvrtc.a
  LINK_PATH = -L/sensei
  OBJECT_DIR = build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir
  POST_BUILD = :
  PRE_LINK = :
  SONAME = libbgfx.so
  SONAME_FLAG = -Wl,-soname,
  TARGET_COMPILE_PDB = build/Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/
  TARGET_FILE = build/Dependencies/bgfx.cmake/libbgfx.so
  TARGET_PDB = build/Dependencies/bgfx.cmake/libbgfx.pdb

vs.

#############################################
# Link the static library Dependencies/bgfx.cmake/libbgfx.a

build Dependencies/bgfx.cmake/libbgfx.a: CXX_STATIC_LIBRARY_LINKER__bgfx_ Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/bgfx.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/debug_renderdoc.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/dxgi.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_egl.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_glx.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_html5.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/glcontext_wgl.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/nvapi.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d11.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d12.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_d3d9.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_gl.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_gnm.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_noop.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_nvn.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_vk.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/renderer_webgpu.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_dx9bc.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_dxbc.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/shader_spirv.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/topology.cpp.o Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx/src/vertexlayout.cpp.o || Dependencies/bgfx.cmake/libastc-codec.a Dependencies/bgfx.cmake/libastc.a Dependencies/bgfx.cmake/libbimg.a Dependencies/bgfx.cmake/libbx.a Dependencies/bgfx.cmake/libedtaa3.a Dependencies/bgfx.cmake/libetc1.a Dependencies/bgfx.cmake/libetc2.a Dependencies/bgfx.cmake/libiqa.a Dependencies/bgfx.cmake/libnvtt.a Dependencies/bgfx.cmake/libpvrtc.a Dependencies/bgfx.cmake/libsquish.a
  OBJECT_DIR = Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir
  POST_BUILD = :
  PRE_LINK = :
  TARGET_COMPILE_PDB = Dependencies/bgfx.cmake/CMakeFiles/bgfx.dir/bgfx.pdb
  TARGET_FILE = Dependencies/bgfx.cmake/libbgfx.a
  TARGET_PDB = Dependencies/bgfx.cmake/libbgfx.pdb

Upon further inspection, it looks like when BabylonNative is built as a dependency of my external app, several of the libraries are built as shared libraries. While the standard BabylonNative build, builds everything as static libraries.

I need to figure out what is triggering this.

It appears that some setting are being inherited from my external app’s CMakeLists.txt. I’ve tried to make all the settings the same, but obviously something is off.

Here’s my app’s CMakeLists.txt file. It’s pretty straight forward. I’m not sure what is triggering the shared libraries.

cmake_minimum_required(VERSION 3.5.1)
project(render3d)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# for local development, set the path to cpp sdk on your device
if(NOT SENSEI_SDK_DIR)
    set(SENSEI_SDK_DIR ~/code/adobe/sensei-cpp-sdk)
endif(NOT SENSEI_SDK_DIR)

include_directories(${SENSEI_SDK_DIR})
link_directories(${SENSEI_SDK_DIR})

find_path(CPPREST_INCLUDE cpprest/http_client.h)
find_library(CPPREST_LIB NAMES cpprest_2_9d cpprest_2_9 cpprestd cpprest cpprestsdk)
find_package(OpenSSL REQUIRED)
# find_package(OpenCV REQUIRED)
find_package(AWSSDK REQUIRED COMPONENTS sqs)

include_directories(${CPPREST_INCLUDE})

set(Boost_USE_MULTITHREADED ON)
find_package(Boost COMPONENTS log log_setup thread filesystem system random timer date_time atomic chrono regex iostreams)
find_package(OpenSSL REQUIRED)
find_path(CPPREST_INCLUDE cpprest/http_client.h)
find_library(CPPREST_LIB NAMES cpprest_2_9d cpprest_2_9 cpprestd cpprest)
find_package(ZLIB REQUIRED)

add_subdirectory(/BabylonNative ./build EXCLUDE_FROM_ALL)

add_executable(render3d src/main.cpp src/Process.cpp src/Renderer.cpp)

target_compile_definitions(render3d PRIVATE UNICODE)
target_compile_definitions(render3d PRIVATE _UNICODE)

target_link_libraries (render3d PUBLIC ${Boost_LIBRARIES} ${CPPREST_LIB} ${ZLIB_LIBRARIES} OpenSSL::SSL glog ${OpenCV_LIBS} protobuf ${AWSSDK_LINK_LIBRARIES} sensei)
add_dependencies(render3d BabylonNative)
target_link_to_dependencies(render3d
    PRIVATE AppRuntime
    PRIVATE NativeCapture
    PRIVATE ChromeDevTools
    PRIVATE NativeEngine
    PRIVATE Console
    PRIVATE Window
    PRIVATE ScriptLoader
    PRIVATE XMLHttpRequest
    ${ADDITIONAL_LIBRARIES}
    )

# Ubuntu mixes old experimental header and new runtime libraries
# Resulting in crash at runtime for std::filesystem
# https://stackoverflow.com/questions/56738708/c-stdbad-alloc-on-stdfilesystempath-append
target_link_libraries(render3d PRIVATE stdc++fs)

add_executable(health src/health.cpp)
target_link_libraries (health ${Boost_LIBRARIES} ${CPPREST_LIB} ${ZLIB_LIBRARIES} OpenSSL::SSL glog ${OpenCV_LIBS} protobuf ${AWSSDK_LINK_LIBRARIES} sensei)

add_subdirectory(tests)

Duh.

Our app builds with -DBUILD_SHARED_LIBS=ON

I’ll trying removing that.