@@ -114,16 +114,19 @@ def jscFlavor = 'org.webkit:android-jsc:+'
114114/**
115115 * Whether to enable the Hermes VM.
116116 *
117- * This should be set on project.ext.react and mirrored here. If it is not set
117+ * This should be set on project.ext.react and that value will be read here. If it is not set
118118 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
119119 * and the benefits of using Hermes will therefore be sharply reduced.
120120 */
121121def enableHermes = project. ext. react. get(" enableHermes" , false );
122122
123123/**
124- * Architectures to build native code for in debug .
124+ * Architectures to build native code for.
125125 */
126- def nativeArchitectures = project. getProperties(). get(" reactNativeDebugArchitectures" )
126+ def reactNativeArchitectures () {
127+ def value = project. getProperties(). get(" reactNativeArchitectures" )
128+ return value ? value. split(" ," ) : [" armeabi-v7a" , " x86" , " x86_64" , " arm64-v8a" ]
129+ }
127130
128131android {
129132 ndkVersion rootProject. ext. ndkVersion
@@ -136,13 +139,80 @@ android {
136139 targetSdkVersion rootProject. ext. targetSdkVersion
137140 versionCode 1
138141 versionName " 1.0"
142+ buildConfigField " boolean" , " IS_NEW_ARCHITECTURE_ENABLED" , isNewArchitectureEnabled(). toString()
143+ if (isNewArchitectureEnabled()) {
144+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
145+ externalNativeBuild {
146+ ndkBuild {
147+ arguments " APP_PLATFORM=android-21" ,
148+ " APP_STL=c++_shared" ,
149+ " NDK_TOOLCHAIN_VERSION=clang" ,
150+ " GENERATED_SRC_DIR=$buildDir /generated/source" ,
151+ " PROJECT_BUILD_DIR=$buildDir " ,
152+ " REACT_ANDROID_DIR=$rootDir /../node_modules/react-native/ReactAndroid" ,
153+ " REACT_ANDROID_BUILD_DIR=$rootDir /../node_modules/react-native/ReactAndroid/build" ,
154+ " NODE_MODULES_DIR=$rootDir /../node_modules"
155+ cFlags " -Wall" , " -Werror" , " -fexceptions" , " -frtti" , " -DWITH_INSPECTOR=1"
156+ cppFlags " -std=c++17"
157+ // Make sure this target name is the same you specify inside the
158+ // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
159+ targets " helloworldapp_appmodules"
160+ }
161+ }
162+ if (! enableSeparateBuildPerCPUArchitecture) {
163+ ndk {
164+ abiFilters (* reactNativeArchitectures())
165+ }
166+ }
167+ }
168+ }
169+ if (isNewArchitectureEnabled()) {
170+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
171+ externalNativeBuild {
172+ ndkBuild {
173+ path " $projectDir /src/main/jni/Android.mk"
174+ }
175+ }
176+ def reactAndroidProjectDir = project(' :ReactAndroid' ). projectDir
177+ def packageReactNdkDebugLibs = tasks. register(" packageReactNdkDebugLibs" , Copy ) {
178+ dependsOn(" :ReactAndroid:packageReactNdkDebugLibsForBuck" )
179+ from(" $reactAndroidProjectDir /src/main/jni/prebuilt/lib" )
180+ into(" $buildDir /react-ndk/exported" )
181+ }
182+ def packageReactNdkReleaseLibs = tasks. register(" packageReactNdkReleaseLibs" , Copy ) {
183+ dependsOn(" :ReactAndroid:packageReactNdkReleaseLibsForBuck" )
184+ from(" $reactAndroidProjectDir /src/main/jni/prebuilt/lib" )
185+ into(" $buildDir /react-ndk/exported" )
186+ }
187+ afterEvaluate {
188+ // If you wish to add a custom TurboModule or component locally,
189+ // you should uncomment this line.
190+ // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
191+ preDebugBuild. dependsOn(packageReactNdkDebugLibs)
192+ preReleaseBuild. dependsOn(packageReactNdkReleaseLibs)
193+
194+ // Due to a bug inside AGP, we have to explicitly set a dependency
195+ // between configureNdkBuild* tasks and the preBuild tasks.
196+ // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
197+ configureNdkBuildRelease. dependsOn(preReleaseBuild)
198+ configureNdkBuildDebug. dependsOn(preDebugBuild)
199+ reactNativeArchitectures(). each { architecture ->
200+ tasks. findByName(" configureNdkBuildDebug[${ architecture} ]" )?. configure {
201+ dependsOn(" preDebugBuild" )
202+ }
203+ tasks. findByName(" configureNdkBuildRelease[${ architecture} ]" )?. configure {
204+ dependsOn(" preReleaseBuild" )
205+ }
206+ }
207+ }
139208 }
209+
140210 splits {
141211 abi {
142212 reset()
143213 enable enableSeparateBuildPerCPUArchitecture
144214 universalApk false // If true, also generate a universal APK
145- include " armeabi-v7a " , " x86 " , " arm64-v8a " , " x86_64 "
215+ include ( * reactNativeArchitectures())
146216 }
147217 }
148218 signingConfigs {
@@ -156,11 +226,6 @@ android {
156226 buildTypes {
157227 debug {
158228 signingConfig signingConfigs. debug
159- if (nativeArchitectures) {
160- ndk {
161- abiFilters nativeArchitectures. split(' ,' )
162- }
163- }
164229 }
165230 release {
166231 // Caution! In production, you need to generate your own keystore file.
@@ -190,6 +255,7 @@ android {
190255
191256dependencies {
192257 implementation fileTree(dir : " libs" , include : [" *.jar" ])
258+
193259 // noinspection GradleDynamicVersion
194260 implementation " com.facebook.react:react-native:+" // From node_modules
195261
@@ -209,14 +275,31 @@ dependencies {
209275 }
210276
211277 if (enableHermes) {
212- def hermesPath = " ../../node_modules/hermes-engine/android/" ;
213- debugImplementation files(hermesPath + " hermes-debug.aar" )
214- releaseImplementation files(hermesPath + " hermes-release.aar" )
278+ // noinspection GradleDynamicVersion
279+ implementation(" com.facebook.react:hermes-engine:+" ) { // From node_modules
280+ exclude group :' com.facebook.fbjni'
281+ }
215282 } else {
216283 implementation jscFlavor
217284 }
218285}
219286
287+ if (isNewArchitectureEnabled()) {
288+ // If new architecture is enabled, we let you build RN from source
289+ // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
290+ // This will be applied to all the imported transtitive dependency.
291+ configurations. all {
292+ resolutionStrategy. dependencySubstitution {
293+ substitute(module(" com.facebook.react:react-native" ))
294+ .using(project(" :ReactAndroid" ))
295+ .because(" On New Architecture we're building React Native from source" )
296+ substitute(module(" com.facebook.react:hermes-engine" ))
297+ .using(project(" :ReactAndroid:hermes-engine" ))
298+ .because(" On New Architecture we're building Hermes from source" )
299+ }
300+ }
301+ }
302+
220303// Run this once to be able to run the application with BUCK
221304// puts all compile dependencies into folder libs for BUCK to use
222305task copyDownloadableDepsToLibs (type : Copy ) {
@@ -225,3 +308,11 @@ task copyDownloadableDepsToLibs(type: Copy) {
225308}
226309
227310apply from : file(" ../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle" ); applyNativeModulesAppBuildGradle(project)
311+
312+ def isNewArchitectureEnabled () {
313+ // To opt-in for the New Architecture, you can either:
314+ // - Set `newArchEnabled` to true inside the `gradle.properties` file
315+ // - Invoke gradle with `-newArchEnabled=true`
316+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
317+ return project. hasProperty(" newArchEnabled" ) && project. newArchEnabled == " true"
318+ }
0 commit comments