Skip to content

Commit

Permalink
Allow configuring ndk build architectures (#31232)
Browse files Browse the repository at this point in the history
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 react-native-community/cli#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: #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
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Jul 12, 2021
1 parent 8dfc3bc commit d6ed1ff
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
9 changes: 9 additions & 0 deletions ReactAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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",
Expand Down
11 changes: 10 additions & 1 deletion packages/rn-tester/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -179,6 +184,11 @@ android {
debug {
debuggable true
signingConfig signingConfigs.release
if (nativeArchitectures) {
ndk {
abiFilters nativeArchitectures.split(',')
}
}
}
release {
debuggable false
Expand Down Expand Up @@ -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",
Expand Down
10 changes: 10 additions & 0 deletions template/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit d6ed1ff

Please sign in to comment.