Skip to content

Commit

Permalink
Update the template to use RNGP (#35075)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #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
  • Loading branch information
cortinico authored and facebook-github-bot committed Oct 25, 2022
1 parent 1d6b732 commit c96c76e
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 226 deletions.
13 changes: 12 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions ReactAndroid/publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -68,6 +69,10 @@ publishing {
name = "npm"
url = androidOutputUrl
}
maven {
name = "mavenTempLocal"
url = mavenTempLocalUrl
}
}

if (signingKey && signingPwd) {
Expand Down
10 changes: 5 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-gradle-plugin/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
}
}
Expand Down
15 changes: 4 additions & 11 deletions scripts/release-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
71 changes: 5 additions & 66 deletions template/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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}") {
Expand All @@ -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"
}
7 changes: 0 additions & 7 deletions template/android/app/src/main/jni/CMakeLists.txt

This file was deleted.

Loading

0 comments on commit c96c76e

Please sign in to comment.