From d6ed1ff58b2ca4d1c8b45416e56fa1da75633c07 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Mon, 12 Jul 2021 09:51:14 -0700 Subject: [PATCH] Allow configuring ndk build architectures (#31232) Summary: Building from source in debug takes a very long time because native builds need to run for all supported architectures. It is possible to check which architecture the devices for which we are about to launch the app on are and build only for those. For most cases we can reduce the number of architectures we build for to 1 instead of 4, resulting in a large speedup of the build. This is inspired by iOS which has a "Build for active architecture only" option. Since android doesn't really support this natively we can implement it here and also in react-native by reading the build properties that we pass and alter the abi we build for. With fabric / codegen coming up I suspect that we might want to default to building c++ soon. This should ease the transition as builds won't be orders of magnitude slower. See https://github.com/react-native-community/cli/pull/1388 for more context and how we use this new config to automatically detect running emulator architectures. ## Changelog [Android] [Added] - Allow configuring ndk build architectures Pull Request resolved: https://github.com/facebook/react-native/pull/31232 Test Plan: Tested by setting reactNativeDebugArchitectures with different values in gradle.properties. Checked the build logs to see which architectures are being built. Also made sure release builds are not affected by this value. Clean build reactNativeDebugArchitectures not set 824.41s reactNativeDebugArchitectures=x86 299.77s Reviewed By: mdvacca Differential Revision: D29613939 Pulled By: ShikaSD fbshipit-source-id: d20a23d1d9bbf33f5afaaf3475f208a2e48c0e1a --- ReactAndroid/build.gradle | 9 +++++++++ packages/rn-tester/android/app/build.gradle | 11 ++++++++++- template/android/app/build.gradle | 10 ++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 3e1cee5c7b693f..c8c7a460b77f05 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -326,6 +326,14 @@ def reactNativeInspectorProxyPort() { return value != null ? value : reactNativeDevServerPort() } +def reactNativeArchitectures() { + def isDebug = gradle.startParameter.taskRequests.any { + it.args.any { it.endsWith("Debug") } + } + def value = project.getProperties().get("reactNativeDebugArchitectures") + return value != null && isDebug ? value : "all" +} + def getNdkBuildFullPath() { def ndkBuildFullPath = findNdkBuildFullPath() if (ndkBuildFullPath == null) { @@ -355,6 +363,7 @@ def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) { inputs.dir("src/main/java/com/facebook/react/modules/blob") outputs.dir("$buildDir/react-ndk/all") commandLine(getNdkBuildFullPath(), + "APP_ABI=${reactNativeArchitectures()}", "NDK_DEBUG=" + (nativeBuildType.equalsIgnoreCase("debug") ? "1" : "0"), "NDK_PROJECT_PATH=null", "NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk", diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index 37793448e573e0..7f04213604bfff 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -128,6 +128,11 @@ def enableFabric = project.ext.react.enableFabric */ def useIntlJsc = false +/** + * Architectures to build native code for in debug. + */ +def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures") + android { compileSdkVersion 29 ndkVersion ANDROID_NDK_VERSION @@ -179,6 +184,11 @@ android { debug { debuggable true signingConfig signingConfigs.release + if (nativeArchitectures) { + ndk { + abiFilters nativeArchitectures.split(',') + } + } } release { debuggable false @@ -254,7 +264,6 @@ if (enableCodegen) { defaultConfig { externalNativeBuild { ndkBuild { - abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a" arguments "APP_PLATFORM=android-21", "APP_STL=c++_shared", "NDK_TOOLCHAIN_VERSION=clang", diff --git a/template/android/app/build.gradle b/template/android/app/build.gradle index 3e76ea0e075e8b..3fd5f4275c0f64 100644 --- a/template/android/app/build.gradle +++ b/template/android/app/build.gradle @@ -120,6 +120,11 @@ def jscFlavor = 'org.webkit:android-jsc:+' */ def enableHermes = project.ext.react.get("enableHermes", false); +/** + * Architectures to build native code for in debug. + */ +def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures") + android { ndkVersion rootProject.ext.ndkVersion @@ -151,6 +156,11 @@ android { buildTypes { debug { signingConfig signingConfigs.debug + if (nativeArchitectures) { + ndk { + abiFilters nativeArchitectures.split(',') + } + } } release { // Caution! In production, you need to generate your own keystore file.