Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for react-native 0.71 #1199

Merged
merged 1 commit into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,30 @@ To avoid issues, remember to clear out `node_modules` folders before you run
yarn clean
yarn
```

## Adding Support For New React Native Versions

First, create a new issue using the "New `react-native` version" template,
update the title, and fill out all the required fields.

When opening a PR, link to the issue that was created, and use the table below
to paste in screenshots as you test the different configurations:

```markdown
| Configuration | Android | iOS | macOS | Windows |
| :-------------- | :-----: | :--: | :---: | :-----: |
| JSC | TODO | TODO | TODO | TODO |
| Hermes | TODO | TODO | TODO | TODO |
| Fabric | TODO | TODO | TODO | TODO |
| Fabric + Hermes | TODO | TODO | TODO | TODO |
```

You can use the test script to both test and capture screenshots. For instance,
to test 0.71, run:

```sh
scripts/test-matrix.sh 0.71
```

At the minimum, we should be testing the lowest supported version (0.64 at the
time of writing) in addition to the new version.
173 changes: 92 additions & 81 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ plugins {
id("org.jetbrains.kotlin.kapt") version "${kotlinVersion}"
}

def enableNewArchitecture = isNewArchitectureEnabled(project)
def reactNativeVersion = getPackageVersionNumber("react-native", rootDir)
def reactNativePath = file(findNodeModulesPath("react-native", rootDir))

if (reactNativeVersion == 0 || enableNewArchitecture) {
if (autodetectReactNativeVersion || enableNewArchitecture) {
apply(plugin: "com.facebook.react")

if (enableNewArchitecture) {
react {
codegenDir = file(findNodeModulesPath("react-native-codegen", reactNativePath))
reactNativeDir = reactNativePath
react {
reactNativeDir = reactNativePath
codegenDir = file(findNodeModulesPath("react-native-codegen", reactNativePath))
}

// We don't want the React plugin to bundle.
tasks.whenTaskAdded { task ->
// The task name can be found in `react-native-gradle-plugin`:
// https://github.com/facebook/react-native/blob/0.71-stable/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt#L54
if (task.name.startsWith("createBundle") && task.name.endsWith("JsAndAssets")) {
task.enabled = false
}
}
}
Expand Down Expand Up @@ -67,6 +72,7 @@ project.ext.react = [
appName : getAppName(),
applicationId : getApplicationId(),
architectures : getArchitectures(),
bundleInRelease : false,
enableCamera : !getSingleAppMode(),
enableFabric : isFabricEnabled(project),
enableFlipper : getFlipperVersion(rootDir),
Expand All @@ -85,6 +91,12 @@ android {
ndkVersion project.ext.ndkVersion
}

if (usePrefabs) {
buildFeatures {
prefab true
}
}

// TODO: Remove this block when minSdkVersion >= 24. See
// https://stackoverflow.com/q/53402639 for details.
if (reactNativeVersion > 0 && reactNativeVersion < 6900) {
Expand Down Expand Up @@ -128,7 +140,7 @@ android {

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

if (project.ext.react.enableNewArchitecture) {
if (enableNewArchitecture) {
externalNativeBuild {
if (reactNativeVersion > 0 && reactNativeVersion < 7000) {
ndkBuild {
Expand Down Expand Up @@ -171,7 +183,7 @@ android {
}
}

if (project.ext.react.enableNewArchitecture) {
if (enableNewArchitecture) {
externalNativeBuild {
if (reactNativeVersion > 0 && reactNativeVersion < 7000) {
ndkBuild {
Expand All @@ -184,50 +196,52 @@ android {
}
}

def reactAndroidProjectDir = project(":ReactAndroid").projectDir
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
from("${reactAndroidProjectDir}/src/main/jni/prebuilt/lib")
into("${buildDir}/react-ndk/exported")
}
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
from("${reactAndroidProjectDir}/src/main/jni/prebuilt/lib")
into("${buildDir}/react-ndk/exported")
}

afterEvaluate {
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
if (!usePrefabs) {
def reactAndroidProjectDir = project(":ReactAndroid").projectDir
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
from("${reactAndroidProjectDir}/src/main/jni/prebuilt/lib")
into("${buildDir}/react-ndk/exported")
}
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
from("${reactAndroidProjectDir}/src/main/jni/prebuilt/lib")
into("${buildDir}/react-ndk/exported")
}

if (reactNativeVersion > 0 && reactNativeVersion < 7000) {
// Due to a bug in AGP, we have to explicitly set a dependency
// between configureNdkBuild* tasks and the preBuild tasks. This can
// be removed once this issue is resolved:
// https://issuetracker.google.com/issues/207403732
configureNdkBuildRelease.dependsOn(preReleaseBuild)
configureNdkBuildDebug.dependsOn(preDebugBuild)
project.ext.react.architectures.each { architecture ->
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
} else if (reactNativeVersion > 0 && reactNativeVersion < 7100) {
// Due to a bug in AGP, we have to explicitly set a dependency
// between configureCMakeDebug* tasks and the preBuild tasks. This can
// be removed once this issue is resolved:
// https://issuetracker.google.com/issues/207403732
configureCMakeDebug.dependsOn(preDebugBuild)
configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
project.ext.react.architectures.each { architecture ->
tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
afterEvaluate {
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)

if (reactNativeVersion < 7000) {
// Due to a bug in AGP, we have to explicitly set a dependency
// between configureNdkBuild* tasks and the preBuild tasks. This can
// be removed once this issue is resolved:
// https://issuetracker.google.com/issues/207403732
configureNdkBuildRelease.dependsOn(preReleaseBuild)
configureNdkBuildDebug.dependsOn(preDebugBuild)
project.ext.react.architectures.each { architecture ->
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
} else {
// Due to a bug in AGP, we have to explicitly set a dependency
// between configureCMakeDebug* tasks and the preBuild tasks. This can
// be removed once this issue is resolved:
// https://issuetracker.google.com/issues/207403732
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be fixed in AGP 7.3.0-alpha9; since 0.71 uses AGP 7.3.1 should we have a separate if statement for 7100?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Starting with 7100, usePrefabs is true, so we won't go into this path any longer. Eventually, we will just remove this branch.

configureCMakeDebug.dependsOn(preDebugBuild)
configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
project.ext.react.architectures.each { architecture ->
tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
}
}
Expand All @@ -239,12 +253,7 @@ android {
}
}

// Nightlies are downloaded from Sonatype and cannot be found under
// `node_modules`. Instead, they can be found in Gradle's cache folder,
// `.gradle/caches/modules-2/files-2.1/com.facebook.react/react-native`.
// For now, we will simply disable this step as we only need to verify
// that things build.
if (reactNativeVersion > 0 && reactNativeVersion < 7100) {
if (!usePrefabs) {
def version = getPackageVersion("react-native", rootDir)
def allAar = file("${reactNativePath}/android/com/facebook/react/react-native/${version}/react-native-${version}.aar")

Expand Down Expand Up @@ -320,7 +329,7 @@ android {
}

// TODO: Remove this block when we drop support for 0.65.
if (project.ext.react.enableNewArchitecture) {
if (enableNewArchitecture) {
main.java.srcDirs += "src/turbomodule/java"
} else {
main.java.srcDirs += "src/no-turbomodule/java"
Expand Down Expand Up @@ -349,8 +358,8 @@ dependencies {
implementation project(":support")

if (project.ext.react.enableHermes) {
if (reactNativeVersion == 0) {
implementation("com.facebook.react:hermes-engine")
if (autodetectReactNativeVersion) {
implementation("com.facebook.react:hermes-android")
} else if (reactNativeVersion >= 6900) {
implementation("com.facebook.react:hermes-engine:+") {
exclude(group: "com.facebook.fbjni")
Expand All @@ -370,10 +379,12 @@ dependencies {
}
}

if (project.ext.react.enableNewArchitecture) {
if (autodetectReactNativeVersion) {
implementation("com.facebook.react:react-android")
} else if (enableNewArchitecture) {
// This is only valid for 0.68 - 0.70. From 0.71 and on, we should be
// using prefabs.
implementation project(":ReactAndroid")
} else if (reactNativeVersion == 0 || reactNativeVersion >= 7100) {
implementation("com.facebook.react:react-native")
} else {
def version = getPackageVersion("react-native", rootDir)
implementation("com.facebook.react:react-native:${version}")
Expand Down Expand Up @@ -425,25 +436,25 @@ dependencies {
}
}

if (project.ext.react.enableNewArchitecture) {
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid"))
.because("On New Architecture, we are building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture, we are building Hermes from source")
}
}
} else if (reactNativeVersion > 0 && reactNativeVersion < 7100) {
if (!usePrefabs) {
configurations.all {
resolutionStrategy {
// Force version here otherwise Gradle will pick up a newer version:
// https://github.com/facebook/react-native/issues/35210
def version = getPackageVersion("react-native", rootDir)
force("com.facebook.react:react-native:${version}")
force("com.facebook.react:hermes-engine:${version}")
if (enableNewArchitecture) {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid"))
.because("On New Architecture, we are building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture, we are building Hermes from source")
}
} else {
resolutionStrategy {
// Force version here otherwise Gradle will pick up a newer version:
// https://github.com/facebook/react-native/issues/35210
def version = getPackageVersion("react-native", rootDir)
force("com.facebook.react:react-native:${version}")
force("com.facebook.react:hermes-engine:${version}")
}
}
}
}
Expand Down
16 changes: 7 additions & 9 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.microsoft.reacttestapp">

package="com.microsoft.reacttestapp"
>
<uses-feature android:name="android.hardware.camera.any" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Expand All @@ -18,13 +19,11 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:targetApi="m">

tools:targetApi="m"
>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

<activity
android:name="com.microsoft.reacttestapp.MainActivity"
android:exported="true">
<activity android:name="com.microsoft.reacttestapp.MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand All @@ -33,5 +32,4 @@

<activity android:name="com.microsoft.reacttestapp.component.ComponentActivity" />
</application>

</manifest>
32 changes: 20 additions & 12 deletions android/app/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,31 @@ set(REACTTESTAPP_SOURCE_FILES
AppRegistry.h
)

# Suppress 'Manually-specified variables were not used by the project' warning
set(UNUSED_VARIABLES ${REACT_COMMON_DIR} ${REACT_JNILIBS_DIR})

if(DEFINED REACT_ANDROID_DIR)
# New architecture
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
target_sources(${THIS_LIBRARY} PRIVATE ${REACTTESTAPP_SOURCE_FILES})
else()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BUILD_VARIANT debug)
else()
set(BUILD_VARIANT release)
endif()
set(JSI_LIBRARY ${REACT_JNILIBS_DIR}/${BUILD_VARIANT}/jni/${ANDROID_ABI}/libjsi.so)

if(EXISTS ${JSI_LIBRARY})
add_library(${THIS_LIBRARY} SHARED ${REACTTESTAPP_SOURCE_FILES})
target_include_directories(${THIS_LIBRARY} PRIVATE ${REACT_COMMON_DIR}/jsi)
target_link_libraries(${THIS_LIBRARY} ${JSI_LIBRARY})
# On old architecture, use prefabs if they can be found. Otherwise, look for
# the `libjsi.so` we extracted from the `.aar`.
add_library(${THIS_LIBRARY} SHARED ${REACTTESTAPP_SOURCE_FILES})
find_package(ReactAndroid CONFIG)
if(ReactAndroid_FOUND)
target_link_libraries(${THIS_LIBRARY} ReactAndroid::jsi)
else()
add_library(${THIS_LIBRARY} SHARED ${REACTTESTAPP_SOURCE_FILES})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BUILD_VARIANT debug)
else()
set(BUILD_VARIANT release)
endif()
set(JSI_LIBRARY ${REACT_JNILIBS_DIR}/${BUILD_VARIANT}/jni/${ANDROID_ABI}/libjsi.so)
if(EXISTS ${JSI_LIBRARY})
target_include_directories(${THIS_LIBRARY} PRIVATE ${REACT_COMMON_DIR}/jsi)
target_link_libraries(${THIS_LIBRARY} ${JSI_LIBRARY})
endif()
endif()
endif()

Expand Down
7 changes: 5 additions & 2 deletions android/app/src/main/jni/ComponentsRegistry.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "ComponentsRegistry.h"

#include <CoreComponentsRegistry.h>
#include <rncli.h>

#include <fbjni/fbjni.h>
#if __has_include(<react/fabric/CoreComponentsRegistry.h>) // >= 0.71
#include <react/fabric/CoreComponentsRegistry.h>
#else // < 0.71
#include <CoreComponentsRegistry.h>
#endif

#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
Expand Down
Loading