From b39e77b3d725d7fa88abfb0a50780677d7ef7050 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 5 Oct 2022 11:35:05 -0700 Subject: [PATCH] Encapsulate the prefab configuration for Android consumers Summary: This moves the prefab/pickFirst configuration from the user's build.gradle to the React Native Gradle Plugin. As this configuration is entirely under our control, is safe to assume users won't need to tweak it (e.g. we control which libraries are built, etc.). Changelog: [Android] [Changed] - Encapsulate the prefab configuration for consumers Reviewed By: cipolleschi Differential Revision: D40094691 fbshipit-source-id: d1510a0a382d26e94e3d01f30661af39f7bedf52 --- .../kotlin/com/facebook/react/ReactPlugin.kt | 2 + .../react/utils/NdkConfiguratorUtils.kt | 60 +++++++++++++++++++ .../com/facebook/react/utils/ProjectUtils.kt | 17 ++++++ .../facebook/react/utils/ProjectUtilsTest.kt | 43 +++++++++++++ packages/rn-tester/android/app/build.gradle | 8 --- .../rn-tester/android/app/gradle.properties | 3 + 6 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt create mode 100644 packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index 23dcb9357195cf..aee077a66942d0 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -16,6 +16,7 @@ import com.facebook.react.tasks.BuildCodegenCLITask import com.facebook.react.tasks.GenerateCodegenArtifactsTask import com.facebook.react.tasks.GenerateCodegenSchemaTask import com.facebook.react.utils.JsonUtils +import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativePrefab import com.facebook.react.utils.findPackageJsonFile import java.io.File import kotlin.system.exitProcess @@ -53,6 +54,7 @@ class ReactPlugin : Plugin { } private fun applyAppPlugin(project: Project, config: ReactExtension) { + configureReactNativePrefab(project) project.afterEvaluate { if (config.applyAppPlugin.getOrElse(false)) { val androidConfiguration = project.extensions.getByType(BaseExtension::class.java) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt new file mode 100644 index 00000000000000..22ebe92b538283 --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.utils + +import com.android.build.api.variant.AndroidComponentsExtension +import com.facebook.react.utils.ProjectUtils.isNewArchEnabled +import org.gradle.api.Project + +internal object NdkConfiguratorUtils { + @Suppress("UnstableApiUsage") + fun configureReactNativePrefab(project: Project) { + if (!project.isNewArchEnabled) { + return + } + project.pluginManager.withPlugin("com.android.application") { + project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext -> + // We enable prefab so users can consume .so/headers from ReactAndroid and hermes-engine + // .aar + ext.buildFeatures.prefab = true + + // We set some packagingOptions { pickFirst ... } for our users for libraries we own. + ext.packagingOptions.jniLibs.pickFirsts.addAll( + listOf( + // Hermes & JSC are provided by AAR dependencies we pre-bundle. + "**/libhermes.so", + "**/libjsc.so", + // This is the .so provided by FBJNI via prefab + "**/libfbjni.so", + // Those are prefab libraries we distribute via ReactAndroid + // Due to a bug in AGP, they fire a warning on console as both the JNI + // and the prefab .so files gets considered. See more on: + "**/libfabricjni.so", + "**/libfolly_runtime.so", + "**/libglog.so", + "**/libjsi.so", + "**/libreact_codegen_rncore.so", + "**/libreact_debug.so", + "**/libreact_nativemodule_core.so", + "**/libreact_newarchdefaults.so", + "**/libreact_render_componentregistry.so", + "**/libreact_render_core.so", + "**/libreact_render_debug.so", + "**/libreact_render_graphics.so", + "**/libreact_render_mapbuffer.so", + "**/librrc_view.so", + "**/libruntimeexecutor.so", + "**/libturbomodulejsijni.so", + "**/libyoga.so", + // AGP will give priority of libc++_shared coming from App modules. + "**/libc++_shared.so", + )) + } + } + } +} diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt new file mode 100644 index 00000000000000..2a4a51467bfc1f --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.utils + +import org.gradle.api.Project + +internal object ProjectUtils { + internal val Project.isNewArchEnabled: Boolean + get() = + project.hasProperty("newArchEnabled") && + project.property("newArchEnabled").toString().toBoolean() +} diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt new file mode 100644 index 00000000000000..8b86ba56bb1cc6 --- /dev/null +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.utils + +import com.facebook.react.tests.createProject +import com.facebook.react.utils.ProjectUtils.isNewArchEnabled +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class ProjectUtilsTest { + + @Test + fun isNewArchEnabled_returnsFalseByDefault() { + assertFalse(createProject().isNewArchEnabled) + } + + @Test + fun isNewArchEnabled_withDisabled_returnsFalse() { + val project = createProject() + project.extensions.extraProperties.set("newArchEnabled", "false") + assertFalse(project.isNewArchEnabled) + } + + @Test + fun isNewArchEnabled_withEnabled_returnsTrue() { + val project = createProject() + project.extensions.extraProperties.set("newArchEnabled", "true") + assertTrue(project.isNewArchEnabled) + } + + @Test + fun isNewArchEnabled_withInvalid_returnsFalse() { + val project = createProject() + project.extensions.extraProperties.set("newArchEnabled", "¯\\_(ツ)_/¯") + assertFalse(project.isNewArchEnabled) + } +} diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index 865e9898ac9521..bc1eead8261128 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -191,14 +191,6 @@ android { ] } } - buildFeatures { - prefab true - } - packagingOptions { - pickFirst '**/libhermes.so' - pickFirst '**/libjsc.so' - pickFirst '**/libc++_shared.so' - } } dependencies { diff --git a/packages/rn-tester/android/app/gradle.properties b/packages/rn-tester/android/app/gradle.properties index c780b9d10b81e5..159049803a664d 100644 --- a/packages/rn-tester/android/app/gradle.properties +++ b/packages/rn-tester/android/app/gradle.properties @@ -11,3 +11,6 @@ android.enableJetifier=true # Version of flipper SDK to use with React Native FLIPPER_VERSION=0.125.0 + +# RN-Tester is building with NewArch always enabled +newArchEnabled=true