mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Summary: This PR is part of Android Gradle Plugin v9 adoption. With this PR, we adopt the AGP9 repository wide and address the deprecated APIs with the newer ones. This is in combination with https://github.com/facebook/react-native/pull/57038 <details> <summary> <b>Changes to `configureBuildConfigFieldsForLibraries` and `configureNamespaceForLibraries`</b> </summary> <br/> These helpers are called from `ReactPlugin.apply`, but they currently iterate over `rootProject.allprojects`. Since `com.facebook.react` is applied by multiple Android library projects, each application of the plugin repeats the same traversal and attempts to register `finalizeDsl` callbacks for every Android library project. The first traversal can register the callbacks successfully. However, a later traversal can reach a project whose Android DSL finalization phase has already completed. Starting with AGP 9, AGP explicitly errors when `finalizeDsl` is called after that phase has passed, which causes the build failure. [see](https://issuetracker.google.com/issues/436595826) To understand this, consider following modules: ``` :react-native-safe-area-context :react-native-mmkv :react-native-skia ``` The current code on main, would result in executing the following block 3 times: ```kt fun configureBuildConfigFieldsForLibraries(appProject: Project) { appProject.rootProject.allprojects { subproject -> println("=== subproject ${subproject.name}") subproject.pluginManager.withPlugin("com.android.library") { subproject.extensions .getByType(LibraryAndroidComponentsExtension::class.java) .finalizeDsl { ext -> ext.buildFeatures.buildConfig = true } } } } ``` The output would be: ``` > Configure project: react-native-safe-area-context === subproject RNProject === subproject app === subproject react-native-safe-area-context === subproject react-native-mmkv === subproject react-native-skia > Configure project: react-native-mmkv === subproject RNProject === subproject app === subproject react-native-safe-area-context === subproject react-native-mmkv === subproject react-native-skia > Configure project: react-native-skia === subproject RNProject === subproject app === subproject react-native-safe-area-context === subproject react-native-mmkv === subproject react-native-skia ``` Now with AGP9, the same code will throw this error: ``` > Configure project: react-native-safe-area-context === subproject RNProject === subproject app === subproject react-native-safe-area-context === subproject react-native-mmkv === subproject react-native-skia > Configure project: react-native-mmkv === subproject RNProject === subproject app === subproject react-native-safe-area-context === subproject react-native-mmkv * What went wrong: A problem occurred evaluating project': react-native-mmkv'. > Failed to apply plugin 'com. facebook. react' > It is too late to call finalizeDst as the DSL finalization blocks have already been executed. \n In particular, you cannot call 'finalizeDsl' within the "beforeVariants' or "onVariants' blocks. Instead, you must call finalizeDsl' directly within the "androidComponents' block ``` **Solution:** Since these helpers are only intended to configure Android library projects that apply the React plugin, we can configure the current project inside `pluginManager.withPlugin("com.android.library")` instead of repeatedly configuring all projects from every plugin application. ```kt fun configureBuildConfigFieldsForLibraries(project: Project) { project.extensions .getByType(LibraryAndroidComponentsExtension::class.java) .finalizeDsl { ext -> ext.buildFeatures.buildConfig = true } } ``` ```kt fun configureNamespaceForLibraries(project: Project) { project.extensions .getByType(LibraryAndroidComponentsExtension::class.java) .finalizeDsl { ext -> if (ext.namespace == null) { val manifestFile = project.layout.projectDirectory.file("src/main/AndroidManifest.xml").asFile manifestFile .takeIf { it.exists() } ?.let { file -> getPackageNameFromManifest(file)?.let { packageName -> ext.namespace = packageName } } } } } ``` One important note for `configureNamespaceForLibraries` is that the old `com.android.build.gradle.LibraryExtension` is deprecated in favor of `com.android.build.api.dsl.LibraryExtension` - which does not expose `manifestFile` from the `sourceSets`. So we have to define a path for it. For most libraries, this should be OK but for the ones which define custom path, this will fail. Hence, I believe, if it's important to have this fallback, we take this tradeoff. Otherwise, since there has been 2 years passed for AGP8 adoption and the time when this fallback was added, we may safely remove this function as almost all libraries now define a `namespace` in `android { }` DSL. With the above in place, we make one final change and that is to move these two functions inside the `withPlugin("com.android.library")` as these are only intended for libraries and that way, we also ensure that these will only be applied once the `com.android.library` plugin has been applied. ```kt project.pluginManager.withPlugin("com.android.library") { configureBuildConfigFieldsForLibraries(project) configureNamespaceForLibraries(project) configureCodegen(project, extension, rootExtension, isLibrary = true) } ``` </details> ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [BREAKING] - Adopt AGP v9 Pull Request resolved: https://github.com/facebook/react-native/pull/57038 Test Plan: - CI passes - Verified on RN Tester - Verified on Local RN App https://github.com/user-attachments/assets/b424c211-6876-42b0-a5d1-f9ecade39a3a Reviewed By: cipolleschi Differential Revision: D107656378 Pulled By: cortinico fbshipit-source-id: 38fd7191e089ce29ccb84fa25bff6d9e920cf322
21 lines
806 B
Properties
21 lines
806 B
Properties
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -Dfile.encoding=UTF-8
|
|
org.gradle.parallel=true
|
|
org.gradle.caching=true
|
|
|
|
android.useAndroidX=true
|
|
|
|
|
|
# Use this property to specify which architecture you want to build.
|
|
# You can also override it from the CLI using
|
|
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
|
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
|
|
|
# Controls whether to use Hermes from stable builds. This will force hermes version
|
|
# set in the sdks/hermes-engine/version.properties file to be used. This has a higher
|
|
# priority than react.internal.useHermesNightly.
|
|
react.internal.useHermesStable=false
|
|
|
|
# Controls whether to use Hermes from nightly builds. This will speed up builds
|
|
# but should NOT be turned on for CI or release builds.
|
|
react.internal.useHermesNightly=true
|