11apply plugin : " com.android.application"
22
33import com.android.build.OutputFile
4+ import org.apache.tools.ant.taskdefs.condition.Os
45
56/**
67 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
@@ -77,14 +78,19 @@ import com.android.build.OutputFile
7778 * ]
7879 */
7980
81+ def projectRoot = rootDir. getAbsoluteFile(). getParentFile(). getAbsolutePath()
82+
83+ def reactNativeRoot = new File ([" node" , " --print" , " require.resolve('react-native/package.json')" ]. execute(null , rootDir). text. trim()). getParentFile(). getAbsolutePath()
84+
8085project. ext. react = [
86+ entryFile : [" node" , " -e" , " require('expo/scripts/resolveAppEntry')" , projectRoot, " android" ]. execute(null , rootDir). text. trim(),
8187 enableHermes : (findProperty(' expo.jsEngine' ) ?: " jsc" ) == " hermes" ,
82- cliPath : new File ([" node" , " --print" , " require.resolve('react-native/package.json')" ]. execute(null , rootDir). text. trim()). getParentFile(). getAbsolutePath() + " /cli.js " ,
83- hermesCommand : new File ([ " node " , " --print " , " require.resolve('hermes-engine/package.json') " ] . execute( null , rootDir) . text . trim()) . getParentFile() . getAbsolutePath() + " /%OS-BIN%/hermesc " ,
84- composeSourceMapsPath : new File ([ " node " , " --print " , " require.resolve('react-native/package.json') " ] . execute( null , rootDir) . text . trim()) . getParentFile() . getAbsolutePath() + " /scripts/compose-source-maps.js" ,
88+ hermesCommand : new File ([" node" , " --print" , " require.resolve('react-native/package.json')" ]. execute(null , rootDir). text. trim()). getParentFile(). getAbsolutePath() + " /sdks/hermesc/%OS-BIN%/hermesc " ,
89+ cliPath : " ${ reactNativeRoot } /cli.js " ,
90+ composeSourceMapsPath : " ${ reactNativeRoot } /scripts/compose-source-maps.js" ,
8591]
8692
87- apply from : new File ([ " node " , " --print " , " require.resolve('react-native/package.json') " ] . execute( null , rootDir) . text . trim(), " ../ react.gradle" )
93+ apply from : new File (reactNativeRoot , " react.gradle" )
8894
8995/**
9096 * Set this to true to create two separate APKs instead of one:
@@ -99,7 +105,7 @@ def enableSeparateBuildPerCPUArchitecture = false
99105/**
100106 * Run Proguard to shrink the Java bytecode in release builds.
101107 */
102- def enableProguardInReleaseBuilds = false
108+ def enableProguardInReleaseBuilds = (findProperty( ' android.enableProguardInReleaseBuilds ' ) ?: false ) . toBoolean()
103109
104110/**
105111 * The preferred build flavor of JavaScriptCore.
@@ -117,33 +123,112 @@ def jscFlavor = 'org.webkit:android-jsc:+'
117123/**
118124 * Whether to enable the Hermes VM.
119125 *
120- * This should be set on project.ext.react and mirrored here. If it is not set
126+ * This should be set on project.ext.react and that value will be read here. If it is not set
121127 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
122128 * and the benefits of using Hermes will therefore be sharply reduced.
123129 */
124130def enableHermes = project. ext. react. get(" enableHermes" , false );
125131
132+ /**
133+ * Architectures to build native code for.
134+ */
135+ def reactNativeArchitectures () {
136+ def value = project. getProperties(). get(" reactNativeArchitectures" )
137+ return value ? value. split(" ," ) : [" armeabi-v7a" , " x86" , " x86_64" , " arm64-v8a" ]
138+ }
139+
126140android {
127- compileSdkVersion rootProject. ext. compileSdkVersion
141+ ndkVersion rootProject. ext. ndkVersion
128142
129- compileOptions {
130- sourceCompatibility JavaVersion . VERSION_1_8
131- targetCompatibility JavaVersion . VERSION_1_8
132- }
143+ compileSdkVersion rootProject. ext. compileSdkVersion
133144
134145 defaultConfig {
135146 applicationId ' io.stream.expomessaging'
136147 minSdkVersion rootProject. ext. minSdkVersion
137148 targetSdkVersion rootProject. ext. targetSdkVersion
138149 versionCode 1
139150 versionName " 1.0.0"
151+ buildConfigField " boolean" , " IS_NEW_ARCHITECTURE_ENABLED" , isNewArchitectureEnabled(). toString()
152+
153+ if (isNewArchitectureEnabled()) {
154+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
155+ externalNativeBuild {
156+ ndkBuild {
157+ arguments " APP_PLATFORM=android-21" ,
158+ " APP_STL=c++_shared" ,
159+ " NDK_TOOLCHAIN_VERSION=clang" ,
160+ " GENERATED_SRC_DIR=$buildDir /generated/source" ,
161+ " PROJECT_BUILD_DIR=$buildDir " ,
162+ " REACT_ANDROID_DIR=${ reactNativeRoot} /ReactAndroid" ,
163+ " REACT_ANDROID_BUILD_DIR=${ reactNativeRoot} /ReactAndroid/build" ,
164+ " NODE_MODULES_DIR=$rootDir /../node_modules"
165+ cFlags " -Wall" , " -Werror" , " -fexceptions" , " -frtti" , " -DWITH_INSPECTOR=1"
166+ cppFlags " -std=c++17"
167+ // Make sure this target name is the same you specify inside the
168+ // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
169+ targets " expomessaging_appmodules"
170+
171+ // Fix for windows limit on number of character in file paths and in command lines
172+ if (Os . isFamily(Os . FAMILY_WINDOWS )) {
173+ arguments " NDK_APP_SHORT_COMMANDS=true"
174+ }
175+ }
176+ }
177+ if (! enableSeparateBuildPerCPUArchitecture) {
178+ ndk {
179+ abiFilters (* reactNativeArchitectures())
180+ }
181+ }
182+ }
183+ }
184+
185+ if (isNewArchitectureEnabled()) {
186+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
187+ externalNativeBuild {
188+ ndkBuild {
189+ path " $projectDir /src/main/jni/Android.mk"
190+ }
191+ }
192+ def reactAndroidProjectDir = project(' :ReactAndroid' ). projectDir
193+ def packageReactNdkDebugLibs = tasks. register(" packageReactNdkDebugLibs" , Copy ) {
194+ dependsOn(" :ReactAndroid:packageReactNdkDebugLibsForBuck" )
195+ from(" $reactAndroidProjectDir /src/main/jni/prebuilt/lib" )
196+ into(" $buildDir /react-ndk/exported" )
197+ }
198+ def packageReactNdkReleaseLibs = tasks. register(" packageReactNdkReleaseLibs" , Copy ) {
199+ dependsOn(" :ReactAndroid:packageReactNdkReleaseLibsForBuck" )
200+ from(" $reactAndroidProjectDir /src/main/jni/prebuilt/lib" )
201+ into(" $buildDir /react-ndk/exported" )
202+ }
203+ afterEvaluate {
204+ // If you wish to add a custom TurboModule or component locally,
205+ // you should uncomment this line.
206+ // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
207+ preDebugBuild. dependsOn(packageReactNdkDebugLibs)
208+ preReleaseBuild. dependsOn(packageReactNdkReleaseLibs)
209+
210+ // Due to a bug inside AGP, we have to explicitly set a dependency
211+ // between configureNdkBuild* tasks and the preBuild tasks.
212+ // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
213+ configureNdkBuildRelease. dependsOn(preReleaseBuild)
214+ configureNdkBuildDebug. dependsOn(preDebugBuild)
215+ reactNativeArchitectures(). each { architecture ->
216+ tasks. findByName(" configureNdkBuildDebug[${ architecture} ]" )?. configure {
217+ dependsOn(" preDebugBuild" )
218+ }
219+ tasks. findByName(" configureNdkBuildRelease[${ architecture} ]" )?. configure {
220+ dependsOn(" preReleaseBuild" )
221+ }
222+ }
223+ }
140224 }
225+
141226 splits {
142227 abi {
143228 reset()
144229 enable enableSeparateBuildPerCPUArchitecture
145230 universalApk false // If true, also generate a universal APK
146- include " armeabi-v7a " , " x86 " , " arm64-v8a " , " x86_64 "
231+ include ( * reactNativeArchitectures())
147232 }
148233 }
149234 signingConfigs {
@@ -183,39 +268,60 @@ android {
183268 }
184269}
185270
271+ // Apply static values from `gradle.properties` to the `android.packagingOptions`
272+ // Accepts values in comma delimited lists, example:
273+ // android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini
274+ [" pickFirsts" , " excludes" , " merges" , " doNotStrip" ]. each { prop ->
275+ // Split option: 'foo,bar' -> ['foo', 'bar']
276+ def options = (findProperty(" android.packagingOptions.$prop " ) ?: " " ). split(" ," );
277+ // Trim all elements in place.
278+ for (i in 0 .. < options. size()) options[i] = options[i]. trim();
279+ // `[] - ""` is essentially `[""].filter(Boolean)` removing all empty strings.
280+ options - = " "
281+
282+ if (options. length > 0 ) {
283+ println " android.packagingOptions.$prop += $options ($options . length )"
284+ // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
285+ options. each {
286+ android. packagingOptions[prop] + = it
287+ }
288+ }
289+ }
290+
186291dependencies {
187292 implementation fileTree(dir : " libs" , include : [" *.jar" ])
293+
188294 // noinspection GradleDynamicVersion
189295 implementation " com.facebook.react:react-native:+" // From node_modules
190296
191297 def isGifEnabled = (findProperty(' expo.gif.enabled' ) ?: " " ) == " true" ;
192298 def isWebpEnabled = (findProperty(' expo.webp.enabled' ) ?: " " ) == " true" ;
193299 def isWebpAnimatedEnabled = (findProperty(' expo.webp.animated' ) ?: " " ) == " true" ;
300+ def frescoVersion = rootProject. ext. frescoVersion
194301
195302 // If your app supports Android versions before Ice Cream Sandwich (API level 14)
196- // All fresco packages should use the same version
197303 if (isGifEnabled || isWebpEnabled) {
198- implementation ' com.facebook.fresco:fresco:2.0.0 '
199- implementation ' com.facebook.fresco:imagepipeline-okhttp3:2.0.0 '
304+ implementation " com.facebook.fresco:fresco:${ frescoVersion } "
305+ implementation " com.facebook.fresco:imagepipeline-okhttp3:${ frescoVersion } "
200306 }
201307
202308 if (isGifEnabled) {
203309 // For animated gif support
204- implementation ' com.facebook.fresco:animated-gif:2.0.0 '
310+ implementation " com.facebook.fresco:animated-gif:${ frescoVersion } "
205311 }
206312
207313 if (isWebpEnabled) {
208314 // For webp support
209- implementation ' com.facebook.fresco:webpsupport:2.0.0 '
315+ implementation " com.facebook.fresco:webpsupport:${ frescoVersion } "
210316 if (isWebpAnimatedEnabled) {
211317 // Animated webp support
212- implementation ' com.facebook.fresco:animated-webp:2.0.0 '
318+ implementation " com.facebook.fresco:animated-webp:${ frescoVersion } "
213319 }
214320 }
215-
321+
216322 implementation " androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
217323 debugImplementation(" com.facebook.flipper:flipper:${ FLIPPER_VERSION} " ) {
218- exclude group :' com.facebook.fbjni'
324+ exclude group :' com.facebook.fbjni'
219325 }
220326 debugImplementation(" com.facebook.flipper:flipper-network-plugin:${ FLIPPER_VERSION} " ) {
221327 exclude group :' com.facebook.flipper'
@@ -226,19 +332,45 @@ dependencies {
226332 }
227333
228334 if (enableHermes) {
229- debugImplementation files(new File ([" node" , " --print" , " require.resolve('hermes-engine/package.json')" ]. execute(null , rootDir). text. trim(), " ../android/hermes-debug.aar" ))
230- releaseImplementation files(new File ([" node" , " --print" , " require.resolve('hermes-engine/package.json')" ]. execute(null , rootDir). text. trim(), " ../android/hermes-release.aar" ))
335+ // noinspection GradleDynamicVersion
336+ implementation(" com.facebook.react:hermes-engine:+" ) { // From node_modules
337+ exclude group :' com.facebook.fbjni'
338+ }
231339 } else {
232340 implementation jscFlavor
233341 }
234342}
235343
344+ if (isNewArchitectureEnabled()) {
345+ // If new architecture is enabled, we let you build RN from source
346+ // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
347+ // This will be applied to all the imported transtitive dependency.
348+ configurations. all {
349+ resolutionStrategy. dependencySubstitution {
350+ substitute(module(" com.facebook.react:react-native" ))
351+ .using(project(" :ReactAndroid" ))
352+ .because(" On New Architecture we're building React Native from source" )
353+ substitute(module(" com.facebook.react:hermes-engine" ))
354+ .using(project(" :ReactAndroid:hermes-engine" ))
355+ .because(" On New Architecture we're building Hermes from source" )
356+ }
357+ }
358+ }
359+
236360// Run this once to be able to run the application with BUCK
237361// puts all compile dependencies into folder libs for BUCK to use
238362task copyDownloadableDepsToLibs (type : Copy ) {
239- from configurations. compile
363+ from configurations. implementation
240364 into ' libs'
241365}
242366
243367apply from : new File ([" node" , " --print" , " require.resolve('@react-native-community/cli-platform-android/package.json')" ]. execute(null , rootDir). text. trim(), " ../native_modules.gradle" );
244368applyNativeModulesAppBuildGradle(project)
369+
370+ def isNewArchitectureEnabled () {
371+ // To opt-in for the New Architecture, you can either:
372+ // - Set `newArchEnabled` to true inside the `gradle.properties` file
373+ // - Invoke gradle with `-newArchEnabled=true`
374+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
375+ return project. hasProperty(" newArchEnabled" ) && project. newArchEnabled == " true"
376+ }
0 commit comments