Merge pull request #35510 from facebook/nc/71rc3-pick-requests

This commit is contained in:
Lorenzo Sciandra
2022-11-30 11:42:50 +00:00
committed by GitHub
38 changed files with 449 additions and 261 deletions
+2 -1
View File
@@ -64,7 +64,8 @@ buck-out
.gradle
local.properties
*.iml
/android/
/android/*
!/android/README.md
# Node
node_modules
+1 -1
View File
@@ -115,7 +115,7 @@ rn_xplat_cxx_library2(
react_native_root_target("React/CoreModules:CoreModules"),
react_native_xplat_target("cxxreact:bridge"),
react_native_xplat_target("cxxreact:jsbigstring"),
react_native_xplat_target("jsi:JSCRuntime"),
react_native_xplat_target("jsc:JSCRuntime"),
react_native_xplat_target("jsiexecutor:jsiexecutor"),
react_native_xplat_target("reactperflogger:reactperflogger"),
],
+1 -1
View File
@@ -7,7 +7,7 @@
#include "JSCExecutorFactory.h"
#import <jsi/JSCRuntime.h>
#import <jsc/JSCRuntime.h>
#import <memory>
+55 -21
View File
@@ -144,6 +144,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
new Pair(new File(buildDir, "third-party-ndk/boost/boost_1_76_0/").absolutePath, ""),
new Pair(new File(buildDir, "third-party-ndk/double-conversion/").absolutePath, ""),
new Pair(new File(buildDir, "third-party-ndk/folly/").absolutePath, ""),
new Pair(new File(buildDir, "third-party-ndk/glog/exported/").absolutePath, ""),
new Pair("../ReactCommon/butter/", "butter/"),
new Pair("../ReactCommon/callinvoker/", ""),
new Pair("../ReactCommon/react/bridging/", "react/bridging/"),
@@ -152,6 +153,8 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
new Pair("../ReactCommon/react/nativemodule/core/platform/android/", ""),
new Pair("../ReactCommon/react/renderer/componentregistry/", "react/renderer/componentregistry/"),
new Pair("../ReactCommon/react/renderer/components/root/", "react/renderer/components/root/"),
new Pair("../ReactCommon/react/renderer/core/", "react/renderer/core/"),
new Pair("../ReactCommon/react/renderer/debug/", "react/renderer/debug/"),
new Pair("../ReactCommon/react/renderer/leakchecker/", "react/renderer/leakchecker/"),
new Pair("../ReactCommon/react/renderer/mapbuffer/", "react/renderer/mapbuffer/"),
new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"),
@@ -159,6 +162,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"),
new Pair("../ReactCommon/react/renderer/telemetry/", "react/renderer/telemetry/"),
new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"),
new Pair("../ReactCommon/react/debug/", "react/debug/"),
new Pair("../ReactCommon/react/utils/", "react/utils/"),
new Pair("src/main/jni/react/jni", "react/jni/"),
]
@@ -174,6 +178,35 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
"rrc_image",
new Pair("../ReactCommon/react/renderer/components/image/", "react/renderer/components/image/")
),
// These prefab targets are used by Expo & Reanimated
new PrefabPreprocessingEntry(
"hermes_executor",
// "hermes_executor" is statically linking against "hermes_executor_common"
// and "hermes_inspector". Here we expose only the headers that we know are needed.
new Pair("../ReactCommon/hermes/inspector/", "hermes/inspector/")
),
new PrefabPreprocessingEntry(
"jscexecutor",
// "jscexecutor" is statically linking against "jscruntime"
// Here we expose only the headers that we know are needed.
new Pair("../ReactCommon/jsc/", "jsc/")
),
new PrefabPreprocessingEntry(
"react_render_uimanager",
new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"),
),
new PrefabPreprocessingEntry(
"react_render_scheduler",
new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"),
),
new PrefabPreprocessingEntry(
"react_render_mounting",
new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"),
),
new PrefabPreprocessingEntry(
"reactnativejni",
new Pair("src/main/jni/react/jni", "react/jni/"),
),
]
)
it.outputDir.set(prefabHeadersDir)
@@ -402,12 +435,12 @@ android {
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_PLATFORM=android-21"
targets "reactnativejni",
"jscexecutor",
targets "jscexecutor",
"jsijniprofiler",
"reactnativeblob",
"reactperfloggerjni",
// prefab targets
"reactnativejni",
"react_render_debug",
"turbomodulejsijni",
"runtimeexecutor",
@@ -426,7 +459,11 @@ android {
"yoga",
"folly_runtime",
"react_nativemodule_core",
"react_render_imagemanager"
"react_render_imagemanager",
"react_render_uimanager",
"react_render_scheduler",
"react_render_mounting",
"hermes_executor"
}
}
ndk {
@@ -434,24 +471,6 @@ android {
}
}
buildTypes {
debug {
externalNativeBuild {
cmake {
targets "hermes-executor-debug"
}
}
}
release {
externalNativeBuild {
cmake {
targets "hermes-executor-release"
}
}
}
}
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
@@ -549,6 +568,21 @@ android {
react_render_imagemanager {
headers(new File(prefabHeadersDir, "react_render_imagemanager").absolutePath)
}
react_render_uimanager {
headers(new File(prefabHeadersDir, "react_render_uimanager").absolutePath)
}
react_render_scheduler {
headers(new File(prefabHeadersDir, "react_render_scheduler").absolutePath)
}
react_render_mounting {
headers(new File(prefabHeadersDir, "react_render_mounting").absolutePath)
}
reactnativejni {
headers(new File(prefabHeadersDir, "reactnativejni").absolutePath)
}
hermes_executor {
headers(new File(prefabHeadersDir, "hermes_executor").absolutePath)
}
}
publishing {
@@ -17,6 +17,7 @@ rn_android_library(
react_native_target("java/com/facebook/hermes/instrumentation:instrumentation"),
react_native_target("java/com/facebook/hermes/instrumentation:hermes_samplingprofiler"),
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/common:common"),
react_native_target("jni/react/hermes/reactexecutor:jni"),
":runtimeconfig",
],
@@ -9,6 +9,7 @@ package com.facebook.hermes.reactexecutor;
import com.facebook.jni.HybridData;
import com.facebook.react.bridge.JavaScriptExecutor;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.soloader.SoLoader;
import javax.annotation.Nullable;
@@ -23,11 +24,11 @@ public class HermesExecutor extends JavaScriptExecutor {
if (mode_ == null) {
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
SoLoader.loadLibrary("hermes");
try {
SoLoader.loadLibrary("hermes-executor-debug");
SoLoader.loadLibrary("hermes_executor");
// libhermes_executor is built differently for Debug & Release so we load the proper mode.
if (ReactBuildConfig.DEBUG == true) {
mode_ = "Debug";
} catch (UnsatisfiedLinkError e) {
SoLoader.loadLibrary("hermes-executor-release");
} else {
mode_ = "Release";
}
}
+1
View File
@@ -56,6 +56,7 @@ add_react_common_subdir(reactperflogger)
add_react_common_subdir(logger)
add_react_common_subdir(jsiexecutor)
add_react_common_subdir(cxxreact)
add_react_common_subdir(jsc)
add_react_common_subdir(jsi)
add_react_common_subdir(butter)
add_react_common_subdir(callinvoker)
@@ -14,6 +14,6 @@ rn_xplat_cxx_library(
headers = [],
header_namespace = "",
compiler_flags = ["-fexceptions"],
soname = "libhermes-executor.$(ext)",
soname = "libhermes_executor.$(ext)",
visibility = ["PUBLIC"],
)
@@ -8,29 +8,20 @@ set(CMAKE_VERBOSE_MAKEFILE on)
file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp)
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
set(HERMES_TARGET_SUFFIX debug)
else()
set(HERMES_TARGET_SUFFIX release)
endif()
set(HERMES_TARGET_NAME hermes-executor-${HERMES_TARGET_SUFFIX})
add_library(
${HERMES_TARGET_NAME}
add_library(hermes_executor
SHARED
${hermes_executor_SRC}
)
target_compile_options(
${HERMES_TARGET_NAME}
hermes_executor
PRIVATE
$<$<CONFIG:Debug>:-DHERMES_ENABLE_DEBUGGER=1>
-fexceptions
)
target_include_directories(${HERMES_TARGET_NAME} PRIVATE .)
target_include_directories(hermes_executor PRIVATE .)
target_link_libraries(
${HERMES_TARGET_NAME}
hermes-executor-common
hermes_executor
hermes_executor_common
jsireact
fb
fbjni
@@ -16,7 +16,7 @@ rn_xplat_cxx_library(
deps = [
FBJNI_TARGET,
react_native_target("jni/react/jni:jni"),
react_native_xplat_target("jsi:JSCRuntime"),
react_native_xplat_target("jsc:JSCRuntime"),
react_native_xplat_target("jsiexecutor:jsiexecutor"),
],
)
@@ -6,7 +6,7 @@
*/
#include <fbjni/fbjni.h>
#include <jsi/JSCRuntime.h>
#include <jsc/JSCRuntime.h>
#include <jsireact/JSIExecutor.h>
#include <react/jni/JReactMarker.h>
#include <react/jni/JSLogging.h>
+6 -5
View File
@@ -8,21 +8,22 @@ set(CMAKE_VERBOSE_MAKEFILE on)
file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp)
add_library(
hermes-executor-common
hermes_executor_common
STATIC
${hermes_executor_SRC}
)
target_include_directories(hermes-executor-common PUBLIC .)
target_link_libraries(hermes-executor-common
target_include_directories(hermes_executor_common PUBLIC .)
target_link_libraries(hermes_executor_common
jsireact
hermes-engine::libhermes
jsi
debug hermes-inspector
debug
hermes_inspector
)
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
target_compile_options(
hermes-executor-common
hermes_executor_common
PRIVATE
-DHERMES_ENABLE_DEBUGGER=1
)
+4 -4
View File
@@ -8,20 +8,20 @@ set(CMAKE_VERBOSE_MAKEFILE on)
file(GLOB hermesinspector_SRC CONFIGURE_DEPENDS *.cpp detail/*.cpp chrome/*.cpp)
add_library(hermes-inspector
add_library(hermes_inspector
STATIC
${hermesinspector_SRC})
target_compile_options(
hermes-inspector
hermes_inspector
PRIVATE
-DHERMES_ENABLE_DEBUGGER=1
-DHERMES_INSPECTOR_FOLLY_KLUDGE=1
-fexceptions
)
target_include_directories(hermes-inspector PUBLIC ${REACT_COMMON_DIR})
target_link_libraries(hermes-inspector
target_include_directories(hermes_inspector PUBLIC ${REACT_COMMON_DIR})
target_link_libraries(hermes_inspector
jsinspector
fb
fbjni
+6
View File
@@ -0,0 +1,6 @@
---
Checks: '>
clang-diagnostic-*,
'
InheritParentConfig: true
...
+34
View File
@@ -0,0 +1,34 @@
load("//tools/build_defs/oss:rn_defs.bzl", "APPLE", "IOS", "MACOSX", "get_apple_compiler_flags", "get_apple_inspector_flags", "get_preprocessor_flags_for_build_mode", "react_native_xplat_dep", "rn_xplat_cxx_library")
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
rn_xplat_cxx_library(
name = "JSCRuntime",
srcs = [
"JSCRuntime.cpp",
],
header_namespace = "jsc",
exported_headers = [
"JSCRuntime.h",
],
apple_sdks = (IOS, MACOSX),
compiler_flags_pedantic = True,
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS + [
"-Os",
],
fbobjc_frameworks = [
"$SDKROOT/System/Library/Frameworks/JavaScriptCore.framework",
],
fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(),
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = APPLE,
visibility = ["PUBLIC"],
xplat_mangled_args = {
"soname": "libjscjsi.$(ext)",
},
exported_deps = [
react_native_xplat_dep("jsi:jsi"),
],
)
+35
View File
@@ -0,0 +1,35 @@
# 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.
##################
### jscruntime ###
##################
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fexceptions
-frtti
-O3
-Wno-unused-lambda-capture
-DLOG_TAG=\"ReactNative\")
add_library(jscruntime
STATIC
JSCRuntime.h
JSCRuntime.cpp)
target_include_directories(jscruntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(jscruntime
folly_runtime
jsc
jsi
glog)
# TODO: Remove this flag when ready.
# Android has this enabled by default, but the flag is still needed for iOS.
target_compile_options(jscruntime PRIVATE -DRN_FABRIC_ENABLED)
@@ -28,12 +28,8 @@ Pod::Spec.new do |s|
s.source_files = "JSCRuntime.{cpp,h}"
s.exclude_files = "**/test/*"
s.framework = "JavaScriptCore"
s.dependency "React-jsi", version
s.default_subspec = "Default"
s.subspec "Default" do
# no-op
end
s.dependency "React-jsi", version
s.subspec "Fabric" do |ss|
ss.pod_target_xcconfig = { "OTHER_CFLAGS" => "$(inherited) -DRN_FABRIC_ENABLED" }
+1 -31
View File
@@ -1,4 +1,4 @@
load("//tools/build_defs/oss:rn_defs.bzl", "APPLE", "IOS", "MACOSX", "react_native_xplat_dep", "rn_xplat_cxx_library")
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_xplat_dep", "rn_xplat_cxx_library")
rn_xplat_cxx_library(
name = "jsi",
@@ -56,33 +56,3 @@ rn_xplat_cxx_library(
react_native_xplat_dep("jsi:jsi"),
],
)
rn_xplat_cxx_library(
name = "JSCRuntime",
srcs = [
"JSCRuntime.cpp",
],
header_namespace = "jsi",
exported_headers = [
"JSCRuntime.h",
],
apple_sdks = (IOS, MACOSX),
compiler_flags_pedantic = True,
fbobjc_compiler_flags = [
"-Os",
],
fbobjc_frameworks = [
"$SDKROOT/System/Library/Frameworks/JavaScriptCore.framework",
],
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = APPLE,
visibility = ["PUBLIC"],
xplat_mangled_args = {
"soname": "libjscjsi.$(ext)",
},
exported_deps = [
react_native_xplat_dep("jsi:jsi"),
],
)
-16
View File
@@ -25,19 +25,3 @@ target_include_directories(jsi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(jsi
folly_runtime
glog)
##################
### jscruntime ###
##################
add_library(jscruntime STATIC
JSCRuntime.h
JSCRuntime.cpp)
target_include_directories(jscruntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(jscruntime folly_runtime jsc glog)
# TODO: Remove this flag when ready.
# Android has this enabled by default, but the flag is still needed for iOS.
target_compile_options(jscruntime PRIVATE -DRN_FABRIC_ENABLED)
+21
View File
@@ -0,0 +1,21 @@
# The `/android` folder inside `react-native`
Starting from React Native 0.71, we're not shipping the `/android` folder inside the React Native NPM package
anymore due to sizing constraints on NPM. The Android artifacts are distributed via Maven Central.
You can read more about it in this RFC:
https://github.com/react-native-community/discussions-and-proposals/pull/508
If you're a library author and you're manipulating the React Native .aar files, to extract headers,
extract `.so` files or do anything with it, you're probably doing something wrong. React Native
0.71 ships with all the necessary logic to let you consume it transparently by just using:
```
implementation("com.facebook.react:react-android")
// or to keep backward compatibility with older versions of React Native:
implementation("com.facebook.react:react-native:+")
```
You should consider refactoring your library code not to unzip/manipulate the React Native .aar files.
This README.md file is kept in this folder as some libraries are checking the existence of the `/android` folder
and failing user builds if the folder is missing.
@@ -33,7 +33,7 @@ group = "com.facebook.react"
dependencies {
implementation(gradleApi())
implementation("com.android.tools.build:gradle:7.3.1")
implementation("com.android.tools.build:gradle:7.4.0-beta05")
implementation("com.google.code.gson:gson:2.8.9")
implementation("com.google.guava:guava:31.0.1-jre")
implementation("com.squareup:javapoet:1.13.0")
@@ -50,8 +50,8 @@ dependencies {
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
@@ -14,6 +14,7 @@ import com.facebook.react.tasks.GenerateCodegenArtifactsTask
import com.facebook.react.tasks.GenerateCodegenSchemaTask
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFields
import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.readVersionString
@@ -46,9 +47,12 @@ class ReactPlugin : Plugin<Project> {
configureReactNativeNdk(project, extension)
configureBuildConfigFields(project)
configureDevPorts(project)
configureBackwardCompatibilityReactMap(project)
project.extensions.getByType(AndroidComponentsExtension::class.java).onVariants { variant ->
project.configureReactTasks(variant = variant, config = extension)
project.extensions.getByType(AndroidComponentsExtension::class.java).apply {
onVariants(selector().all()) { variant ->
project.configureReactTasks(variant = variant, config = extension)
}
}
configureCodegen(project, extension, isLibrary = false)
}
@@ -96,7 +100,8 @@ class ReactPlugin : Plugin<Project> {
// Please note that appNeedsCodegen is triggering a read of the package.json at
// configuration time as we need to feed the onlyIf condition of this task.
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) }
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
}
// We create the task to produce schema from JS files.
@@ -120,7 +125,8 @@ class ReactPlugin : Plugin<Project> {
} else {
it.jsRootDir.set(extension.jsRootDir)
}
it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(parsedPackageJson) }
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
}
// We create the task to generate Java code from schema.
@@ -130,7 +136,6 @@ class ReactPlugin : Plugin<Project> {
it.dependsOn(generateCodegenSchemaTask)
it.reactNativeDir.set(extension.reactNativeDir)
it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
it.codegenDir.set(extension.codegenDir)
it.generatedSrcDir.set(generatedSrcDir)
it.packageJsonFile.set(findPackageJsonFile(project, extension))
it.codegenJavaPackageName.set(extension.codegenJavaPackageName)
@@ -139,7 +144,8 @@ class ReactPlugin : Plugin<Project> {
// Please note that appNeedsCodegen is triggering a read of the package.json at
// configuration time as we need to feed the onlyIf condition of this task.
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) }
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
}
// We update the android configuration to include the generated sources.
@@ -46,8 +46,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
config.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) }
configureNewArchPackagingOptions(project, variant)
configureJsEnginePackagingOptions(
config, variant, isHermesEnabledInThisVariant, isDebuggableVariant)
configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant)
if (!isDebuggableVariant) {
val bundleTask =
@@ -26,8 +26,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
@get:Internal abstract val reactNativeDir: DirectoryProperty
@get:Internal abstract val codegenDir: DirectoryProperty
@get:Internal abstract val generatedSrcDir: DirectoryProperty
@get:InputFile abstract val packageJsonFile: RegularFileProperty
@@ -38,10 +36,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
@get:Input abstract val libraryName: Property<String>
@get:InputFile
val combineJsToSchemaCli: Provider<RegularFile> =
codegenDir.file("lib/cli/combine/combine-js-to-schema-cli.js")
@get:InputFile
val generatedSchemaFile: Provider<RegularFile> = generatedSrcDir.file("schema.json")
@@ -0,0 +1,48 @@
/*
* 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 java.util.*
import org.gradle.api.Project
internal object BackwardCompatUtils {
fun configureBackwardCompatibilityReactMap(project: Project) {
if (project.extensions.extraProperties.has("react")) {
@Suppress("UNCHECKED_CAST")
val reactMap =
project.extensions.extraProperties.get("react") as? Map<String, Any?> ?: mapOf()
if (reactMap.isNotEmpty()) {
project.logger.error(
"""
********************************************************************************
ERROR: Using old project.ext.react configuration.
We identified that your project is using a old configuration block as:
project.ext.react = [
// ...
]
You should migrate to the new configuration:
react {
// ...
}
You can find documentation inside `android/app/build.gradle` on how to use it.
********************************************************************************
"""
.trimIndent())
}
}
// We set an empty react[] map so if a library is reading it, they will find empty values.
project.extensions.extraProperties.set("react", mapOf<String, String>())
}
}
@@ -15,44 +15,57 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository
internal object DependencyUtils {
/**
* This method takes care of configuring the repositories{} block for both the app and all the 3rd
* party libraries which are auto-linked.
*/
fun configureRepositories(project: Project, reactNativeDir: File) {
with(project) {
if (hasProperty("REACT_NATIVE_MAVEN_LOCAL_REPO")) {
mavenRepoFromUrl("file://${property("REACT_NATIVE_MAVEN_LOCAL_REPO")}")
project.rootProject.allprojects { eachProject ->
with(eachProject) {
if (hasProperty("REACT_NATIVE_MAVEN_LOCAL_REPO")) {
val mavenLocalRepoPath = property("REACT_NATIVE_MAVEN_LOCAL_REPO") as String
mavenRepoFromURI(File(mavenLocalRepoPath).toURI())
}
// We add the snapshot for users on nightlies.
mavenRepoFromUrl("https://oss.sonatype.org/content/repositories/snapshots/")
repositories.mavenCentral()
// Android JSC is installed from npm
mavenRepoFromURI(File(reactNativeDir, "../jsc-android/dist").toURI())
repositories.google()
mavenRepoFromUrl("https://www.jitpack.io")
}
// We add the snapshot for users on nightlies.
mavenRepoFromUrl("https://oss.sonatype.org/content/repositories/snapshots/")
repositories.mavenCentral()
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
mavenRepoFromUrl("file://${reactNativeDir}/android")
// Android JSC is installed from npm
mavenRepoFromUrl("file://${reactNativeDir}/../jsc-android/dist")
repositories.google()
mavenRepoFromUrl("https://www.jitpack.io")
}
}
/**
* This method takes care of configuring the resolution strategy for both the app and all the 3rd
* party libraries which are auto-linked. Specifically it takes care of:
* - Forcing the react-android/hermes-android version to the one specified in the package.json
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
*/
fun configureDependencies(project: Project, versionString: String) {
if (versionString.isBlank()) return
project.configurations.all { configuration ->
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
// coordinates are voided due to https://github.com/facebook/react-native/issues/35210
// This allows users to import libraries that are still using
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
it.substitute(it.module("com.facebook.react:react-native"))
.using(it.module("com.facebook.react:react-android:${versionString}"))
.because(
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
it.substitute(it.module("com.facebook.react:hermes-engine"))
.using(it.module("com.facebook.react:hermes-android:${versionString}"))
.because(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
project.rootProject.allprojects { eachProject ->
eachProject.configurations.all { configuration ->
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
// coordinates are voided due to https://github.com/facebook/react-native/issues/35210
// This allows users to import libraries that are still using
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
it.substitute(it.module("com.facebook.react:react-native"))
.using(it.module("com.facebook.react:react-android:${versionString}"))
.because(
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
it.substitute(it.module("com.facebook.react:hermes-engine"))
.using(it.module("com.facebook.react:hermes-android:${versionString}"))
.because(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
}
configuration.resolutionStrategy.force(
"com.facebook.react:react-android:${versionString}",
"com.facebook.react:hermes-android:${versionString}",
)
}
configuration.resolutionStrategy.force(
"com.facebook.react:react-android:${versionString}",
"com.facebook.react:hermes-android:${versionString}",
)
}
}
@@ -70,4 +83,7 @@ internal object DependencyUtils {
fun Project.mavenRepoFromUrl(url: String): MavenArtifactRepository =
project.repositories.maven { it.url = URI.create(url) }
fun Project.mavenRepoFromURI(uri: URI): MavenArtifactRepository =
project.repositories.maven { it.url = uri }
}
@@ -112,36 +112,25 @@ internal object NdkConfiguratorUtils {
config: ReactExtension,
variant: Variant,
hermesEnabled: Boolean,
debuggableVariant: Boolean
) {
if (config.enableSoCleanup.get()) {
val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled, debuggableVariant)
val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled)
variant.packaging.jniLibs.excludes.addAll(excludes)
variant.packaging.jniLibs.pickFirsts.addAll(includes)
}
}
fun getPackagingOptionsForVariant(
hermesEnabled: Boolean,
debuggableVariant: Boolean
): Pair<List<String>, List<String>> {
fun getPackagingOptionsForVariant(hermesEnabled: Boolean): Pair<List<String>, List<String>> {
val excludes = mutableListOf<String>()
val includes = mutableListOf<String>()
if (hermesEnabled) {
excludes.add("**/libjsc.so")
excludes.add("**/libjscexecutor.so")
includes.add("**/libhermes.so")
if (debuggableVariant) {
excludes.add("**/libhermes-executor-release.so")
includes.add("**/libhermes-executor-debug.so")
} else {
excludes.add("**/libhermes-executor-debug.so")
includes.add("**/libhermes-executor-release.so")
}
includes.add("**/libhermes_executor.so")
} else {
excludes.add("**/libhermes.so")
excludes.add("**/libhermes-executor-debug.so")
excludes.add("**/libhermes-executor-release.so")
excludes.add("**/libhermes_executor.so")
includes.add("**/libjsc.so")
includes.add("**/libjscexecutor.so")
}
@@ -29,28 +29,16 @@ class GenerateCodegenArtifactsTaskTest {
val codegenDir = tempFolder.newFolder("codegen")
val outputDir = tempFolder.newFolder("output")
val task =
createTestTask<GenerateCodegenArtifactsTask> {
it.codegenDir.set(codegenDir)
it.generatedSrcDir.set(outputDir)
}
val task = createTestTask<GenerateCodegenArtifactsTask> { it.generatedSrcDir.set(outputDir) }
assertEquals(
File(codegenDir, "lib/cli/combine/combine-js-to-schema-cli.js"),
task.combineJsToSchemaCli.get().asFile)
assertEquals(File(outputDir, "schema.json"), task.generatedSchemaFile.get().asFile)
}
@Test
fun generateCodegenSchema_outputFile_isSetCorrectly() {
val codegenDir = tempFolder.newFolder("codegen")
val outputDir = tempFolder.newFolder("output")
val task =
createTestTask<GenerateCodegenArtifactsTask> {
it.codegenDir.set(codegenDir)
it.generatedSrcDir.set(outputDir)
}
val task = createTestTask<GenerateCodegenArtifactsTask> { it.generatedSrcDir.set(outputDir) }
assertEquals(File(outputDir, "java"), task.generatedJavaFiles.get().asFile)
assertEquals(File(outputDir, "jni"), task.generatedJniFiles.get().asFile)
@@ -80,13 +68,11 @@ class GenerateCodegenArtifactsTaskTest {
@WithOs(OS.LINUX)
fun setupCommandLine_willSetupCorrectly() {
val reactNativeDir = tempFolder.newFolder("node_modules/react-native/")
val codegenDir = tempFolder.newFolder("codegen")
val outputDir = tempFolder.newFolder("output")
val task =
createTestTask<GenerateCodegenArtifactsTask> {
it.reactNativeDir.set(reactNativeDir)
it.codegenDir.set(codegenDir)
it.generatedSrcDir.set(outputDir)
it.nodeExecutableAndArgs.set(listOf("--verbose"))
}
@@ -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.BackwardCompatUtils.configureBackwardCompatibilityReactMap
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
class BackwardCompatUtilsTest {
@get:Rule val tempFolder = TemporaryFolder()
@Test
fun configureBackwardCompatibilityReactMap_addsEmptyReactMap() {
val project = createProject()
configureBackwardCompatibilityReactMap(project)
assertTrue(project.extensions.extraProperties.has("react"))
@Suppress("UNCHECKED_CAST")
assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
}
@Test
fun configureBackwardCompatibilityReactMap_withExistingMapSetByUser_wipesTheMap() {
val project = createProject()
project.extensions.extraProperties.set("react", mapOf("enableHermes" to true))
configureBackwardCompatibilityReactMap(project)
assertTrue(project.extensions.extraProperties.has("react"))
@Suppress("UNCHECKED_CAST")
assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
}
}
@@ -10,10 +10,12 @@ package com.facebook.react.utils
import com.facebook.react.tests.createProject
import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.mavenRepoFromURI
import com.facebook.react.utils.DependencyUtils.mavenRepoFromUrl
import com.facebook.react.utils.DependencyUtils.readVersionString
import java.net.URI
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test
@@ -26,9 +28,9 @@ class DependencyUtilsTest {
@Test
fun configureRepositories_withProjectPropertySet_configuresMavenLocalCorrectly() {
val localMaven = tempFolder.newFolder("m2")
val localMavenURI = URI.create("file://$localMaven/")
val localMavenURI = localMaven.toURI()
val project = createProject()
project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven)
project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven.absolutePath)
configureRepositories(project, tempFolder.root)
@@ -51,21 +53,6 @@ class DependencyUtilsTest {
})
}
@Test
fun configureRepositories_containsReactNativeNpmLocalMavenRepo() {
val projectFolder = tempFolder.newFolder()
val reactNativeDir = tempFolder.newFolder("react-native")
val repositoryURI = URI.create("file://${reactNativeDir}/android")
val project = createProject(projectFolder)
configureRepositories(project, reactNativeDir)
assertNotNull(
project.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
}
@Test
fun configureRepositories_containsJscLocalMavenRepo() {
val projectFolder = tempFolder.newFolder()
@@ -124,10 +111,10 @@ class DependencyUtilsTest {
@Test
fun configureRepositories_withProjectPropertySet_hasHigherPriorityThanMavenCentral() {
val localMaven = tempFolder.newFolder("m2")
val localMavenURI = URI.create("file://$localMaven/")
val localMavenURI = localMaven.toURI()
val mavenCentralURI = URI.create("https://repo.maven.apache.org/maven2/")
val project = createProject()
project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven)
project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven.absolutePath)
configureRepositories(project, tempFolder.root)
@@ -161,6 +148,46 @@ class DependencyUtilsTest {
assertTrue(indexOfSnapshotRepo < indexOfMavenCentral)
}
@Test
fun configureRepositories_appliesToAllProjects() {
val repositoryURI = URI.create("https://repo.maven.apache.org/maven2/")
val rootProject = ProjectBuilder.builder().build()
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
configureRepositories(appProject, tempFolder.root)
assertNotNull(
appProject.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
assertNotNull(
libProject.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
}
@Test
fun configureRepositories_withPreviousExclusionRulesOnMavenCentral_appliesCorrectly() {
val repositoryURI = URI.create("https://repo.maven.apache.org/maven2/")
val rootProject = ProjectBuilder.builder().build()
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
// Let's emulate a library which set an `excludeGroup` on `com.facebook.react` for Central.
libProject.repositories.mavenCentral { repo ->
repo.content { content -> content.excludeGroup("com.facebook.react") }
}
configureRepositories(appProject, tempFolder.root)
// We need to make sure we have Maven Central defined twice, one by the library,
// and another is the override by RNGP.
assertEquals(
2,
libProject.repositories.count { it is MavenArtifactRepository && it.url == repositoryURI })
}
@Test
fun configureDependencies_withEmptyVersion_doesNothing() {
val project = createProject()
@@ -181,6 +208,24 @@ class DependencyUtilsTest {
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
}
@Test
fun configureDependencies_withVersionString_appliesOnAllProjects() {
val rootProject = ProjectBuilder.builder().build()
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
appProject.plugins.apply("com.android.application")
libProject.plugins.apply("com.android.library")
configureDependencies(appProject, "1.2.3")
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
assertTrue(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
assertTrue(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
}
@Test
fun readVersionString_withCorrectVersionString_returnsIt() {
val propertiesFile =
@@ -253,4 +298,13 @@ class DependencyUtilsTest {
assertEquals(URI.create("https://hello.world"), mavenRepo.url)
}
@Test
fun mavenRepoFromURI_worksCorrectly() {
val process = createProject()
val repoFolder = tempFolder.newFolder("maven-repo")
val mavenRepo = process.mavenRepoFromURI(repoFolder.toURI())
assertEquals(repoFolder.toURI(), mavenRepo.url)
}
}
@@ -15,70 +15,28 @@ import org.junit.Test
class NdkConfiguratorUtilsTest {
@Test
fun getPackagingOptionsForVariant_withHermesEnabled_andDebuggableVariant() {
val (excludes, includes) =
getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = true)
fun getPackagingOptionsForVariant_withHermesEnabled() {
val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = true)
assertTrue("**/libjsc.so" in excludes)
assertTrue("**/libjscexecutor.so" in excludes)
assertTrue("**/libhermes-executor-release.so" in excludes)
assertFalse("**/libjsc.so" in includes)
assertFalse("**/libjscexecutor.so" in includes)
assertFalse("**/libhermes-executor-release.so" in includes)
assertTrue("**/libhermes.so" in includes)
assertTrue("**/libhermes-executor-debug.so" in includes)
assertTrue("**/libhermes_executor.so" in includes)
assertFalse("**/libhermes.so" in excludes)
assertFalse("**/libhermes-executor-debug.so" in excludes)
assertFalse("**/libhermes_executor.so" in excludes)
}
@Test
fun getPackagingOptionsForVariant_withHermesEnabled_andNonDebuggableVariant() {
val (excludes, includes) =
getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = false)
assertTrue("**/libjsc.so" in excludes)
assertTrue("**/libjscexecutor.so" in excludes)
assertTrue("**/libhermes-executor-debug.so" in excludes)
assertFalse("**/libjsc.so" in includes)
assertFalse("**/libjscexecutor.so" in includes)
assertFalse("**/libhermes-executor-debug.so" in includes)
assertTrue("**/libhermes.so" in includes)
assertTrue("**/libhermes-executor-release.so" in includes)
assertFalse("**/libhermes.so" in excludes)
assertFalse("**/libhermes-executor-release.so" in excludes)
}
@Test
fun getPackagingOptionsForVariant_withHermesDisabled_andDebuggableVariant() {
val (excludes, includes) =
getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = true)
fun getPackagingOptionsForVariant_withHermesDisabled() {
val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = false)
assertTrue("**/libhermes.so" in excludes)
assertTrue("**/libhermes-executor-debug.so" in excludes)
assertTrue("**/libhermes-executor-release.so" in excludes)
assertTrue("**/libhermes_executor.so" in excludes)
assertFalse("**/libhermes.so" in includes)
assertFalse("**/libhermes-executor-debug.so" in includes)
assertFalse("**/libhermes-executor-release.so" in includes)
assertTrue("**/libjsc.so" in includes)
assertTrue("**/libjscexecutor.so" in includes)
assertFalse("**/libjsc.so" in excludes)
assertFalse("**/libjscexecutor.so" in excludes)
}
@Test
fun getPackagingOptionsForVariant_withHermesDisabled_andNonDebuggableVariant() {
val (excludes, includes) =
getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = false)
assertTrue("**/libhermes.so" in excludes)
assertTrue("**/libhermes-executor-debug.so" in excludes)
assertTrue("**/libhermes-executor-release.so" in excludes)
assertFalse("**/libhermes.so" in includes)
assertFalse("**/libhermes-executor-debug.so" in includes)
assertFalse("**/libhermes-executor-release.so" in includes)
assertFalse("**/libhermes_executor.so" in includes)
assertTrue("**/libjsc.so" in includes)
assertTrue("**/libjscexecutor.so" in includes)
@@ -412,6 +412,7 @@
5CF0FD27207FC6EC00C13D65 /* Start Metro */,
2FCDFB64B37634EC8EC3139B /* [CP] Embed Pods Frameworks */,
A8DE6393E2BB72D8FBBF6C27 /* [CP] Copy Pods Resources */,
992FB5A50F2847F7EB2C285C /* [RN] Copy Hermes Framework */,
);
buildRules = (
);
@@ -696,6 +697,24 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
992FB5A50F2847F7EB2C285C /* [RN] Copy Hermes Framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "[RN] Copy Hermes Framework";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = ". ../../sdks/hermes-engine/utils/copy-hermes-xcode.sh";
};
9A596313B3964A4DEB794409 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
+2 -2
View File
@@ -442,11 +442,11 @@ afterEvaluate {
if (cleanup) {
// Reduce size by deleting the debugger/inspector
include '**/libhermes-executor-debug.so'
include '**/libhermes_executor_debug.so'
} else {
// Release libs take precedence and must be removed
// to allow debugging
include '**/libhermes-executor-release.so'
include '**/libhermes_executor_release.so'
}
} else {
// For JSC, delete all the libhermes* files
+3 -3
View File
@@ -44,7 +44,7 @@ class JSEngineTests < Test::Unit::TestCase
# Assert
assert_equal($podInvocationCount, 2)
assert_equal($podInvocation["React-jsi"][:path], "../../ReactCommon/jsi")
assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsi")
assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsc")
end
def test_setupJsc_installsPods_installsFabricSubspecWhenFabricEnabled
@@ -57,8 +57,8 @@ class JSEngineTests < Test::Unit::TestCase
# Assert
assert_equal($podInvocationCount, 3)
assert_equal($podInvocation["React-jsi"][:path], "../../ReactCommon/jsi")
assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsi")
assert_equal($podInvocation["React-jsc/Fabric"][:path], "../../ReactCommon/jsi")
assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsc")
assert_equal($podInvocation["React-jsc/Fabric"][:path], "../../ReactCommon/jsc")
end
# ================== #
+2 -2
View File
@@ -11,9 +11,9 @@ require_relative './utils.rb'
# @parameter fabric_enabled: whether Fabirc is enabled
def setup_jsc!(react_native_path: "../node_modules/react-native", fabric_enabled: false)
pod 'React-jsi', :path => "#{react_native_path}/ReactCommon/jsi"
pod 'React-jsc', :path => "#{react_native_path}/ReactCommon/jsi"
pod 'React-jsc', :path => "#{react_native_path}/ReactCommon/jsc"
if fabric_enabled
pod 'React-jsc/Fabric', :path => "#{react_native_path}/ReactCommon/jsi"
pod 'React-jsc/Fabric', :path => "#{react_native_path}/ReactCommon/jsc"
end
end
+1 -1
View File
@@ -15,7 +15,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.android.tools.build:gradle:7.4.0-beta05")
classpath("com.facebook.react:react-native-gradle-plugin")
}
}