Update the template to use RNGP (#35075)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35075

This diff updates the New App template for Android to use the React Native Gradle Plugin.
With this we can:
1. Get rid of all the C++ code.
2. Remove a lot of New Architecture logic in the build.gradle
3. Reuse the prebuilts of React Native/Hermes via prefab

Changelog:
[Android] [Changed] - Update the template to use RNGP

Reviewed By: cipolleschi

Differential Revision: D40673732

fbshipit-source-id: 70935248993d1e24904c982e75f12ad580faa9d8
This commit is contained in:
Nicola Corti
2022-10-25 13:13:14 -07:00
committed by Facebook GitHub Bot
parent 1d6b732496
commit c96c76eb91
13 changed files with 107 additions and 226 deletions
+12 -1
View File
@@ -805,7 +805,9 @@ jobs:
- run:
name: Build the template application for << parameters.flavor >> with New Architecture set to << parameters.newarchitecture >>, and using the << parameters.jsengine>> JS engine.
command: cd /tmp/$PROJECT_NAME/android/ && ./gradlew assemble<< parameters.flavor >> -PnewArchEnabled=<< parameters.newarchitecture >>
command: |
cd /tmp/$PROJECT_NAME/android/
./gradlew assemble<< parameters.flavor >> -PnewArchEnabled=<< parameters.newarchitecture >> -PREACT_NATIVE_MAVEN_LOCAL_REPO=/root/react-native/maven-local
# -------------------------
# JOBS: Test iOS Template
@@ -1443,6 +1445,15 @@ jobs:
command: zip -r /tmp/hermes-native-symbols.zip ~/react-native/ReactAndroid/hermes-engine/build/intermediates/cmake/
- store_artifacts:
path: /tmp/hermes-native-symbols.zip
- run:
name: Zip Maven Artifacts from /tmp/maven-local
command: zip -r /tmp/maven-local.zip /tmp/maven-local
- store_artifacts:
path: /tmp/maven-local.zip
- persist_to_workspace:
root: /tmp
paths:
- maven-local
# START: Commitlies
# Provide a react-native package for this commit as a Circle CI release artifact.
+5
View File
@@ -14,6 +14,7 @@ def signingPwd = findProperty("SIGNING_PWD")
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
def androidOutputUrl = "file://${reactAndroidProjectDir}/../android"
def mavenTempLocalUrl = "file:///tmp/maven-local"
publishing {
publications {
@@ -68,6 +69,10 @@ publishing {
name = "npm"
url = androidOutputUrl
}
maven {
name = "mavenTempLocal"
url = mavenTempLocalUrl
}
}
if (signingKey && signingPwd) {
+5 -5
View File
@@ -115,11 +115,11 @@ tasks.register("publishAllInsideNpmPackage") {
dependsOn(":ReactAndroid:hermes-engine:installArchives")
}
tasks.register("publishAllToMavenLocal") {
description = "Publish all the artifacts to be available inside Maven Local."
dependsOn(":ReactAndroid:publishToMavenLocal")
dependsOn(":ReactAndroid:external-artifacts:publishToMavenLocal")
dependsOn(":ReactAndroid:hermes-engine:publishToMavenLocal")
tasks.register("publishAllToMavenTempLocal") {
description = "Publish all the artifacts to be available inside a Maven Local repository on /tmp."
dependsOn(":ReactAndroid:publishAllPublicationsToMavenTempLocalRepository")
// We don't publish the external-artifacts to Maven Local as CircleCI is using it via workspace.
dependsOn(":ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository")
}
tasks.register("publishAllToSonatype") {
+1 -1
View File
@@ -131,7 +131,7 @@
"pretty-format": "^26.5.2",
"promise": "^8.2.0",
"react-devtools-core": "^4.26.1",
"react-native-gradle-plugin": "0.71.4",
"react-native-gradle-plugin": "^0.71.6",
"react-refresh": "^0.4.0",
"react-shallow-renderer": "^16.15.0",
"regenerator-runtime": "^0.13.2",
@@ -1,6 +1,6 @@
{
"name": "react-native-gradle-plugin",
"version": "0.71.5",
"version": "0.71.6",
"description": "⚛️ Gradle Plugin for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
"repository": {
@@ -16,75 +16,84 @@ import org.gradle.api.Project
internal object NdkConfiguratorUtils {
@Suppress("UnstableApiUsage")
fun configureReactNativeNdk(project: Project, extension: ReactExtension) {
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
if (!project.isNewArchEnabled) {
// For Old Arch, we set a pickFirst only on libraries that we know are
// clashing with our direct dependencies (FBJNI, Flipper and Hermes).
ext.packagingOptions.jniLibs.pickFirsts.addAll(
listOf(
"**/libfbjni.so",
"**/libc++_shared.so",
))
} else {
// 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",
))
// 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_imagemanager.so",
"**/libreact_render_mapbuffer.so",
"**/librrc_image.so",
"**/librrc_view.so",
"**/libruntimeexecutor.so",
"**/libturbomodulejsijni.so",
"**/libyoga.so",
// AGP will give priority of libc++_shared coming from App modules.
"**/libc++_shared.so",
))
// If the user has not provided a CmakeLists.txt path, let's provide
// the default one from the framework
if (ext.externalNativeBuild.cmake.path == null) {
ext.externalNativeBuild.cmake.path =
File(
extension.reactNativeDir.get().asFile,
"cmake-utils/default-app-setup/CMakeLists.txt")
}
// If the user has not provided a CmakeLists.txt path, let's provide
// the default one from the framework
if (ext.externalNativeBuild.cmake.path == null) {
ext.externalNativeBuild.cmake.path =
File(
extension.reactNativeDir.get().asFile,
"ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt")
}
// Parameters should be provided in an additive manner (do not override what
// the user provided, but allow for sensible defaults).
val cmakeArgs = ext.defaultConfig.externalNativeBuild.cmake.arguments
if ("-DGENERATED_SRC_DIR" !in cmakeArgs) {
cmakeArgs.add("-DGENERATED_SRC_DIR=${File(project.buildDir, "generated/source")}")
}
if ("-DPROJECT_BUILD_DIR" !in cmakeArgs) {
cmakeArgs.add("-DPROJECT_BUILD_DIR=${project.buildDir}")
}
if ("-DREACT_ANDROID_DIR" !in cmakeArgs) {
cmakeArgs.add(
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
}
if ("-DREACT_ANDROID_BUILD_DIR" !in cmakeArgs) {
cmakeArgs.add(
"-DREACT_ANDROID_BUILD_DIR=${extension.reactNativeDir.file("ReactAndroid/build").get().asFile}")
}
if ("-DANDROID_STL" !in cmakeArgs) {
cmakeArgs.add("-DANDROID_STL=c++_shared")
// Parameters should be provided in an additive manner (do not override what
// the user provided, but allow for sensible defaults).
val cmakeArgs = ext.defaultConfig.externalNativeBuild.cmake.arguments
if ("-DGENERATED_SRC_DIR" !in cmakeArgs) {
cmakeArgs.add("-DGENERATED_SRC_DIR=${File(project.buildDir, "generated/source")}")
}
if ("-DPROJECT_BUILD_DIR" !in cmakeArgs) {
cmakeArgs.add("-DPROJECT_BUILD_DIR=${project.buildDir}")
}
if ("-DREACT_ANDROID_DIR" !in cmakeArgs) {
cmakeArgs.add(
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
}
if ("-DREACT_ANDROID_BUILD_DIR" !in cmakeArgs) {
cmakeArgs.add(
"-DREACT_ANDROID_BUILD_DIR=${extension.reactNativeDir.file("ReactAndroid/build").get().asFile}")
}
if ("-DANDROID_STL" !in cmakeArgs) {
cmakeArgs.add("-DANDROID_STL=c++_shared")
}
}
}
}
+4 -11
View File
@@ -33,15 +33,8 @@ function saveFilesToRestore(tmpPublishingFolder) {
function generateAndroidArtifacts(releaseVersion, tmpPublishingFolder) {
// -------- Generating Android Artifacts
env.REACT_NATIVE_SKIP_PREFAB = true;
if (exec('./gradlew :ReactAndroid:installArchives').code) {
echo('Could not generate artifacts');
exit(1);
}
// -------- Generating the Hermes Engine Artifacts
env.REACT_NATIVE_HERMES_SKIP_PREFAB = true;
if (exec('./gradlew :ReactAndroid:hermes-engine:installArchives').code) {
echo('Generating Android artifacts inside /tmp/maven-local');
if (exec('./gradlew publishAllToMavenTempLocal').code) {
echo('Could not generate artifacts');
exit(1);
}
@@ -63,12 +56,12 @@ function generateAndroidArtifacts(releaseVersion, tmpPublishingFolder) {
if (
!test(
'-e',
`./android/com/facebook/react/react-native/${releaseVersion}/${name}`,
`/tmp/maven-local/com/facebook/react/react-native/${releaseVersion}/${name}`,
)
) {
echo(
`Failing as expected file: \n\
android/com/facebook/react/react-native/${releaseVersion}/${name}\n\
/tmp/maven-local/com/facebook/react/react-native/${releaseVersion}/${name}\n\
was not correctly generated.`,
);
exit(1);
+5 -66
View File
@@ -1,7 +1,7 @@
apply plugin: "com.android.application"
apply plugin: "com.facebook.react"
import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
@@ -82,8 +82,6 @@ project.ext.react = [
enableHermes: true, // clean and rebuild if changing
]
apply from: "../../node_modules/react-native/react.gradle"
/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
@@ -140,40 +138,6 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) {
// We configure the CMake build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
cmake {
arguments "-DPROJECT_BUILD_DIR=$buildDir",
"-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
"-DANDROID_STL=c++_shared"
}
}
if (!enableSeparateBuildPerCPUArchitecture) {
ndk {
abiFilters (*reactNativeArchitectures())
}
}
}
}
if (isNewArchitectureEnabled()) {
// We configure the CMake build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
cmake {
path "$projectDir/src/main/jni/CMakeLists.txt"
}
}
buildFeatures {
prefab true
}
}
packagingOptions {
pickFirst '**/libc++_shared.so'
pickFirst '**/libfbjni.so'
}
splits {
@@ -225,10 +189,10 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-native")
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
@@ -237,35 +201,10 @@ dependencies {
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
if (enableHermes) {
//noinspection GradleDynamicVersion
implementation("com.facebook.react:hermes-engine:+") // From node_modules
implementation("com.facebook.react:hermes-engine")
} else {
implementation jscFlavor
}
}
if (isNewArchitectureEnabled()) {
// If new architecture is enabled, we let you build RN from source
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
// This will be applied to all the imported transitive dependency.
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid"))
.because("On New Architecture we're building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture we're building Hermes from source")
}
}
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}
@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.13)
# Define the library name here.
project(appmodules)
# This file includes all the necessary to let you build your application with the New Architecture.
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
@@ -1,50 +0,0 @@
#include <DefaultComponentsRegistry.h>
#include <DefaultTurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <rncli.h>
namespace facebook {
namespace react {
void registerComponents(
std::shared_ptr<ComponentDescriptorProviderRegistry const> registry) {
// Custom Fabric Components go here. You can register custom
// components coming from your App or from 3rd party libraries here.
//
// providerRegistry->add(concreteComponentDescriptorProvider<
// AocViewerComponentDescriptor>());
// By default we just use the components autolinked by RN CLI
rncli_registerProviders(registry);
}
std::shared_ptr<TurboModule> provideModules(
const std::string &name,
const JavaTurboModule::InitParams &params) {
// Here you can provide your own module provider for TurboModules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a library called `samplelibrary`):
//
// auto module = samplelibrary_ModuleProvider(moduleName, params);
// if (module != nullptr) {
// return module;
// }
// return rncore_ModuleProvider(moduleName, params);
// By default we just use the module providers autolinked by RN CLI
return rncli_ModuleProvider(name, params);
}
} // namespace react
} // namespace facebook
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::DefaultTurboModuleManagerDelegate::
moduleProvidersFromEntryPoint = &facebook::react::provideModules;
facebook::react::DefaultComponentsRegistry::
registerComponentDescriptorsFromEntryPoint =
&facebook::react::registerComponents;
});
}
+1 -8
View File
@@ -17,7 +17,6 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle:7.3.0")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:5.0.1")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -33,13 +32,7 @@ allprojects {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.
content {
excludeGroup "com.facebook.react"
}
}
mavenCentral()
google()
maven { url 'https://www.jitpack.io' }
}
-7
View File
@@ -2,10 +2,3 @@ rootProject.name = 'HelloWorld'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
include(":ReactAndroid:hermes-engine")
project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
}
-5
View File
@@ -7960,11 +7960,6 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-native-gradle-plugin@0.71.4:
version "0.71.4"
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.4.tgz#dd000c1539e0ce465237637d3e16fe619cd84467"
integrity sha512-5izzWXIlr5DL5+cx3a6oSA4cgSCw9Kv7WQjHqLxV2I1fSfzjzEdYTaDfrNjdcy71BHeeUB6BEyl70yXpjkCkdA==
react-refresh@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.0.tgz#d421f9bd65e0e4b9822a399f14ac56bda9c92292"