Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Apps/Playground/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
require_relative '../node_modules/react-native-test-app/test_app'
require_relative '../node_modules/react-native-permissions/scripts/setup'

# Match the @babylonjs/react-native pod's iOS 16 minimum (required for Xcode 26
# builds, where the CMake-generated framework targets iOS 16 by default).
platform :ios, '16.0'

workspace 'Playground.xcworkspace'

# react-native-permissions
Expand Down
8 changes: 7 additions & 1 deletion Modules/@babylonjs/react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The minimum Android SDK version is 21. This must be set as `minSdkVersion` in th

### iOS Configuration

The minimum deployment target version is 12. This must be set as `iOS Deployment Target` in the consuming project's `project.pbxproj`, and must also be set as `platform` in the consuming project's `Podfile`.
The minimum deployment target version is 16. This must be set as `iOS Deployment Target` in the consuming project's `project.pbxproj`, and must also be set as `platform` in the consuming project's `Podfile`.
Make sure `pod install` is called from the ios folder after npm install.

#### Workspace
Expand All @@ -39,6 +39,12 @@ To use the system cmake (e.g. a Homebrew or system install) instead of the cmake
export BABYLON_USE_SYSTEM_CMAKE=1
```

To override the iOS deployment target used by the generated `ReactNativeBabylon.xcodeproj` (defaults to `16.0`), set this variable before running `npm install` so it matches your app's Podfile `platform :ios` value:
```
export BABYLON_IOS_DEPLOYMENT_TARGET=16.0
```
The previous default of iOS 12 caused Xcode 26's Clang to crash while compiling `DeviceImpl_iOS.mm`; the default is now `16.0` and this variable lets you raise it further (or, at your own risk, lower it) without patching the deployment target from a Podfile `post_install` hook.

### Plugins selection

Plugins can be disabled at build time. They are all enabled by default and disabling is done with environment variables:
Expand Down
35 changes: 32 additions & 3 deletions Modules/@babylonjs/react-native/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ def graphics_api = safeExtGet('GRAPHICS_API', "OpenGL")
def rootBuildDir = "${rootProject.rootDir}/../Build/Android"
def extractedLibDir = "${rootBuildDir}/lib"

// ARCore version. Consumers can override by setting ext.arcoreVersion in their
// root build.gradle (e.g. `ext.arcoreVersion = '1.26.0'` to resolve the
// duplicate-class conflict between com.google.ar:core:1.22 and
// com.android.installreferrer:installreferrer:2.2). A consumer's
// resolutionStrategy.force on com.google.ar:core also wins over this value,
// in which case the dynamic ARCORE_LIBPATH resolution below still picks up
// the actually-extracted AAR.
def arcoreVersion = safeExtGet('arcoreVersion', '1.22.0')

def BABYLON_NATIVE_PLUGIN_NATIVECAMERA = System.getenv("BABYLON_NATIVE_PLUGIN_NATIVECAMERA") != "0"
def BABYLON_NATIVE_PLUGIN_NATIVEXR = System.getenv("BABYLON_NATIVE_PLUGIN_NATIVEXR") != "0"

Expand Down Expand Up @@ -168,10 +177,17 @@ android {
cmake {
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
abiFilters (*reactNativeArchitectures())
// NOTE: -DARCORE_LIBPATH below points at the AAR matching the
// declared `arcoreVersion` (see top of this file). The actual
// resolved ARCore version may differ (consumer
// resolutionStrategy.force, dependency conflict resolution),
// so the argument is rewritten further down in this script
// (search for "arcoreAarFileName") to point at the AAR that
Comment thread
CedricGuillemet marked this conversation as resolved.
// Gradle actually extracted.
arguments "-DANDROID_STL=c++_shared",
"-DGRAPHICS_API=${graphics_api}",
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
"-DARCORE_LIBPATH=${extractedLibDir}/core-1.22.0.aar/jni",
"-DARCORE_LIBPATH=${extractedLibDir}/core-${arcoreVersion}.aar/jni",
"-DREACTNATIVE_DIR=${rootDir}/../node_modules/react-native/",
"-DBABYLON_NATIVE_PLUGIN_NATIVECAMERA=${BABYLON_NATIVE_PLUGIN_NATIVECAMERA ? '1' : '0'}",
"-DBABYLON_NATIVE_PLUGIN_NATIVEXR=${BABYLON_NATIVE_PLUGIN_NATIVEXR ? '1' : '0'}",
Expand Down Expand Up @@ -286,9 +302,9 @@ repositories {
dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'com.google.ar:core:1.22.0'
implementation "com.google.ar:core:${arcoreVersion}"

extractLibs 'com.google.ar:core:1.22.0'
extractLibs "com.google.ar:core:${arcoreVersion}"

if (REACT_NATIVE_VERSION < 71) {
logger.warn("BabylonReactNative: Extracting files from AAR (pre RN 0.71)")
Expand Down Expand Up @@ -388,6 +404,19 @@ def nativeBuildDependsOn(dependsOnTask, variant) {
buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
}

// Resolve the actual ARCore AAR name. A consumer project may override
// `ext.arcoreVersion` or apply a resolutionStrategy.force to com.google.ar:core
// (e.g. to resolve a conflict with installreferrer 2.2 that requires
// com.google.ar:core 1.26+). Gradle extracts the AAR into a folder named after
// the *resolved* artifact (core-<version>.aar), so the native build's
// -DARCORE_LIBPATH argument must match that resolved name rather than the
// version literal declared in the dependencies block.
def arcoreAar = configurations.extractLibs.resolvedConfiguration.resolvedArtifacts.find { it.name == 'core' }
def arcoreAarName = arcoreAar ? "${arcoreAar.name}-${arcoreAar.moduleVersion.id.version}.aar" : "core-${arcoreVersion}.aar"
android.defaultConfig.externalNativeBuild.cmake.arguments.replaceAll {
it.toString().startsWith('-DARCORE_LIBPATH=') ? "-DARCORE_LIBPATH=${extractedLibDir}/${arcoreAarName}/jni".toString() : it
}
Comment thread
CedricGuillemet marked this conversation as resolved.

configurations.extractLibs.files.each { file ->
copy {
from zipTree(file)
Expand Down
20 changes: 18 additions & 2 deletions Modules/@babylonjs/react-native/ios/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ FetchContent_Declare(ios-cmake
FetchContent_MakeAvailable(ios-cmake)
set(CMAKE_TOOLCHAIN_FILE "${ios-cmake_SOURCE_DIR}/ios.toolchain.cmake" CACHE PATH "")
set(PLATFORM "OS64COMBINED" CACHE STRING "")
set(DEPLOYMENT_TARGET "12" CACHE STRING "")

# Allow the consuming project to override the iOS deployment target used when
# generating the Xcode project. Resolution order:
# 1. -DDEPLOYMENT_TARGET=<x> on the cmake command line (highest priority)
# 2. BABYLON_IOS_DEPLOYMENT_TARGET environment variable (forwarded by
# postinstall.js so consumers can set it before `npm install`)
# 3. 16.0 (default). iOS 12 used to be the default, but it is known to crash
# Xcode 26's Clang while compiling DeviceImpl_iOS.mm; iOS 16 is now the
# supported minimum.
if(NOT DEFINED DEPLOYMENT_TARGET OR "${DEPLOYMENT_TARGET}" STREQUAL "")
if(DEFINED ENV{BABYLON_IOS_DEPLOYMENT_TARGET} AND NOT "$ENV{BABYLON_IOS_DEPLOYMENT_TARGET}" STREQUAL "")
set(DEPLOYMENT_TARGET "$ENV{BABYLON_IOS_DEPLOYMENT_TARGET}" CACHE STRING "iOS deployment target")
else()
set(DEPLOYMENT_TARGET "16" CACHE STRING "iOS deployment target")
Comment thread
CedricGuillemet marked this conversation as resolved.
endif()
endif()
message(STATUS "BabylonReactNative iOS DEPLOYMENT_TARGET: ${DEPLOYMENT_TARGET}")
set(ENABLE_ARC OFF CACHE STRING "Enables or disables ARC support.")
set(ENABLE_PCH OFF CACHE STRING "Enables or disables precompiled headers.")
set(CMAKE_XCODE_GENERATE_SCHEME ON)
Expand Down Expand Up @@ -91,7 +107,7 @@ target_link_libraries(BabylonNative
# TODO: For some reason these don't work, so we specify these in the CMake command line args.
set_target_properties(BabylonNative PROPERTIES
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 12.0
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET}
XCODE_ATTRIBUTE_ENABLE_BITCODE YES
XCODE_GENERATE_SCHEME ON
)
16 changes: 14 additions & 2 deletions Modules/@babylonjs/react-native/postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@ function getCmakeExecutable() {
function iosCMake() {
const { spawn } = require('child_process');

const cmake = spawn(getCmakeExecutable(), [
const cmakeArgs = [
'-S', path.join(__dirname, 'ios'),
'-B', path.join(__dirname, 'Build/iOS'),
'-G', 'Xcode',
], { stdio: 'inherit', cwd: __dirname });
];

// Allow the consuming project to override the iOS deployment target used
// when generating the Xcode project. The CMakeLists.txt default is 16.0
// (iOS 12 used to be the default but is known to crash Xcode 26's Clang
// when compiling DeviceImpl_iOS.mm); set this if you need a different
// minimum to match your Podfile `platform :ios` value.
const deploymentTarget = process.env.BABYLON_IOS_DEPLOYMENT_TARGET;
if (deploymentTarget && deploymentTarget.trim() !== '') {
cmakeArgs.push(`-DDEPLOYMENT_TARGET=${deploymentTarget.trim()}`);
}

const cmake = spawn(getCmakeExecutable(), cmakeArgs, { stdio: 'inherit', cwd: __dirname });

cmake.on('exit', code => {
if (code !== 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Pod::Spec.new do |s|
s.license = package["license"]
s.authors = package["author"]

s.platforms = { :ios => "12.0" }
s.platforms = { :ios => "16.0" }
s.source = { :git => package["repository"]["url"], :tag => s.version }

s.source_files = "ios/*.{h,m,mm}"
Expand Down
Loading