@ohos-ports/react-native-gradle-plugin 0.71.19-beta.0 → 0.86.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +11 -4
  2. package/build.gradle.kts +33 -41
  3. package/gradle/libs.versions.toml +22 -0
  4. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  5. package/gradle/wrapper/gradle-wrapper.properties +3 -1
  6. package/gradle.properties +2 -0
  7. package/gradlew +32 -18
  8. package/gradlew.bat +22 -18
  9. package/package.json +21 -11
  10. package/react-native-gradle-plugin/README.md +17 -0
  11. package/react-native-gradle-plugin/build.gradle.kts +83 -0
  12. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/ReactExtension.kt +78 -10
  13. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +320 -0
  14. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactRootProjectPlugin.kt +86 -0
  15. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/TaskConfiguration.kt +36 -25
  16. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/internal/PrivateReactExtension.kt +11 -4
  17. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt +60 -50
  18. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt +252 -0
  19. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +8 -3
  20. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +11 -18
  21. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateEntryPointTask.kt +108 -0
  22. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GeneratePackageListTask.kt +214 -0
  23. package/{src/main/kotlin/com/facebook/react/tasks → react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal}/BuildCodegenCLITask.kt +24 -17
  24. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/CustomExecTask.kt +46 -0
  25. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareBoostTask.kt +10 -4
  26. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PrepareGflagsTask.kt +119 -0
  27. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareGlogTask.kt +26 -18
  28. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt +28 -12
  29. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntry.kt +4 -3
  30. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +163 -0
  31. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +71 -0
  32. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +299 -0
  33. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JdkConfiguratorUtils.kt +64 -0
  34. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +59 -65
  35. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/PathUtils.kt +44 -30
  36. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +119 -0
  37. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt +96 -0
  38. package/settings-plugin/build.gradle.kts +73 -0
  39. package/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt +217 -0
  40. package/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsPlugin.kt +23 -0
  41. package/settings-plugin/src/test/kotlin/com/facebook/react/ReactSettingsExtensionTest.kt +475 -0
  42. package/settings.gradle.kts +10 -1
  43. package/shared/build.gradle.kts +52 -0
  44. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingAndroidProjectJson.kt +18 -0
  45. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingConfigJson.kt +14 -0
  46. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesJson.kt +18 -0
  47. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesPlatformAndroidJson.kt +23 -0
  48. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesPlatformJson.kt +12 -0
  49. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingProjectJson.kt +10 -0
  50. package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt +2 -1
  51. package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelPackageJson.kt +1 -1
  52. package/shared/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt +43 -0
  53. package/shared/src/main/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtils.kt +32 -0
  54. package/{src → shared/src}/main/kotlin/com/facebook/react/utils/Os.kt +7 -6
  55. package/{src → shared/src}/main/kotlin/com/facebook/react/utils/TaskUtils.kt +4 -5
  56. package/shared/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt +382 -0
  57. package/shared/src/test/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtilsTest.kt +82 -0
  58. package/shared/src/test/kotlin/com/facebook/react/utils/OsTest.kt +87 -0
  59. package/shared/src/test/kotlin/com/facebook/react/utils/TaskUtilsTest.kt +76 -0
  60. package/shared-testutil/build.gradle.kts +46 -0
  61. package/shared-testutil/src/main/kotlin/com/facebook/react/tests/OsRule.kt +52 -0
  62. package/shared-testutil/src/main/kotlin/com/facebook/react/tests/WithOs.kt +17 -0
  63. package/build/libs/react-native-gradle-plugin.jar +0 -0
  64. package/index.js +0 -73
  65. package/src/main/kotlin/com/facebook/react/ReactPlugin.kt +0 -212
  66. package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareJSCTask.kt +0 -50
  67. package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareLibeventTask.kt +0 -51
  68. package/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +0 -54
  69. package/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +0 -48
  70. package/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +0 -109
  71. package/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt +0 -21
  72. package/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +0 -55
  73. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/FileUtils.kt +0 -0
  74. /package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt +0 -0
@@ -0,0 +1,320 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react
9
+
10
+ import com.android.build.api.variant.ApplicationAndroidComponentsExtension
11
+ import com.android.build.api.variant.LibraryAndroidComponentsExtension
12
+ import com.android.build.gradle.internal.tasks.factory.dependsOn
13
+ import com.facebook.react.internal.PrivateReactExtension
14
+ import com.facebook.react.tasks.GenerateAutolinkingNewArchitecturesFileTask
15
+ import com.facebook.react.tasks.GenerateCodegenArtifactsTask
16
+ import com.facebook.react.tasks.GenerateCodegenSchemaTask
17
+ import com.facebook.react.tasks.GenerateEntryPointTask
18
+ import com.facebook.react.tasks.GeneratePackageListTask
19
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForApp
20
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForLibraries
21
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildTypesForApp
22
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureDevServerLocation
23
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureNamespaceForLibraries
24
+ import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
25
+ import com.facebook.react.utils.DependencyUtils.configureDependencies
26
+ import com.facebook.react.utils.DependencyUtils.configureRepositories
27
+ import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
28
+ import com.facebook.react.utils.JdkConfiguratorUtils.configureJavaToolChains
29
+ import com.facebook.react.utils.JsonUtils
30
+ import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
31
+ import com.facebook.react.utils.ProjectUtils.isHermesV1Enabled
32
+ import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
33
+ import com.facebook.react.utils.findPackageJsonFile
34
+ import java.io.File
35
+ import kotlin.system.exitProcess
36
+ import org.gradle.api.Plugin
37
+ import org.gradle.api.Project
38
+ import org.gradle.api.Task
39
+ import org.gradle.api.file.Directory
40
+ import org.gradle.api.provider.Provider
41
+ import org.gradle.internal.jvm.Jvm
42
+
43
+ class ReactPlugin : Plugin<Project> {
44
+ override fun apply(project: Project) {
45
+ checkJvmVersion(project)
46
+ val extension = project.extensions.create("react", ReactExtension::class.java, project)
47
+
48
+ // We register a private extension on the rootProject so that project wide configs
49
+ // like codegen config can be propagated from app project to libraries.
50
+ val rootExtension =
51
+ project.rootProject.extensions.findByType(PrivateReactExtension::class.java)
52
+ ?: project.rootProject.extensions.create(
53
+ "privateReact",
54
+ PrivateReactExtension::class.java,
55
+ project,
56
+ )
57
+
58
+ if (!project.rootProject.isHermesV1Enabled) {
59
+ rootExtension.hermesV1Enabled.set(false)
60
+ }
61
+
62
+ // App Only Configuration
63
+ project.pluginManager.withPlugin("com.android.application") {
64
+ // We wire the root extension with the values coming from the app (either user populated or
65
+ // defaults).
66
+ rootExtension.root.set(extension.root)
67
+ rootExtension.reactNativeDir.set(extension.reactNativeDir)
68
+ rootExtension.codegenDir.set(extension.codegenDir)
69
+ rootExtension.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
70
+
71
+ project.afterEvaluate {
72
+ val reactNativeDir = extension.reactNativeDir.get().asFile
73
+ val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
74
+ val hermesVersionPropertiesFile =
75
+ File(reactNativeDir, "sdks/hermes-engine/version.properties")
76
+ val versionAndGroupStrings =
77
+ readVersionAndGroupStrings(project, propertiesFile, hermesVersionPropertiesFile)
78
+ val hermesV1Enabled = rootExtension.hermesV1Enabled.get()
79
+ configureDependencies(project, versionAndGroupStrings, hermesV1Enabled)
80
+ configureRepositories(project, versionAndGroupStrings.isNightly)
81
+ }
82
+
83
+ configureReactNativeNdk(project, extension)
84
+ configureBuildConfigFieldsForApp(project, extension)
85
+ configureDevServerLocation(project)
86
+ configureBackwardCompatibilityReactMap(project)
87
+ configureJavaToolChains(project)
88
+
89
+ project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).apply {
90
+ onVariants(selector().all()) { variant ->
91
+ project.configureReactTasks(variant = variant, config = extension)
92
+ }
93
+ }
94
+ configureAutolinking(project, extension)
95
+ configureCodegen(project, extension, rootExtension, isLibrary = false)
96
+ configureResources(project, extension)
97
+ configureBuildTypesForApp(project)
98
+ }
99
+
100
+ // Library Only Configuration
101
+ configureBuildConfigFieldsForLibraries(project)
102
+ configureNamespaceForLibraries(project)
103
+ project.pluginManager.withPlugin("com.android.library") {
104
+ configureCodegen(project, extension, rootExtension, isLibrary = true)
105
+ }
106
+ }
107
+
108
+ private fun checkJvmVersion(project: Project) {
109
+ val jvmVersion = Jvm.current().javaVersion?.majorVersion
110
+ if ((jvmVersion?.toIntOrNull() ?: 0) <= 16) {
111
+ project.logger.error(
112
+ """
113
+
114
+ ********************************************************************************
115
+
116
+ ERROR: requires JDK17 or higher.
117
+ Incompatible major version detected: '$jvmVersion'
118
+
119
+ ********************************************************************************
120
+
121
+ """
122
+ .trimIndent()
123
+ )
124
+ exitProcess(1)
125
+ }
126
+ }
127
+
128
+ /** This function configures Android resources - in this case just the bundle */
129
+ private fun configureResources(project: Project, reactExtension: ReactExtension) {
130
+ project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).finalizeDsl {
131
+ ext ->
132
+ val bundleFileExtension = reactExtension.bundleAssetName.get().substringAfterLast('.', "")
133
+ if (!reactExtension.enableBundleCompression.get() && bundleFileExtension.isNotBlank()) {
134
+ ext.androidResources.noCompress.add(bundleFileExtension)
135
+ }
136
+ }
137
+ }
138
+
139
+ /** This function sets up `react-native-codegen` in our Gradle plugin. */
140
+ @Suppress("UnstableApiUsage")
141
+ private fun configureCodegen(
142
+ project: Project,
143
+ localExtension: ReactExtension,
144
+ rootExtension: PrivateReactExtension,
145
+ isLibrary: Boolean,
146
+ ) {
147
+ // First, we set up the output dir for the codegen.
148
+ val generatedSrcDir: Provider<Directory> =
149
+ project.layout.buildDirectory.dir("generated/source/codegen")
150
+
151
+ // We specify the default value (convention) for jsRootDir.
152
+ // It's the root folder for apps (so ../../ from the Gradle project)
153
+ // and the package folder for library (so ../ from the Gradle project)
154
+ if (isLibrary) {
155
+ localExtension.jsRootDir.convention(project.layout.projectDirectory.dir("../"))
156
+ } else {
157
+ localExtension.jsRootDir.convention(localExtension.root)
158
+ }
159
+
160
+ // We create the task to produce schema from JS files.
161
+ val generateCodegenSchemaTask =
162
+ project.tasks.register(
163
+ "generateCodegenSchemaFromJavaScript",
164
+ GenerateCodegenSchemaTask::class.java,
165
+ ) { it ->
166
+ it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
167
+ it.codegenDir.set(rootExtension.codegenDir)
168
+ it.generatedSrcDir.set(generatedSrcDir)
169
+ it.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
170
+
171
+ // We're reading the package.json at configuration time to properly feed
172
+ // the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
173
+ // parsePackageJson should be invoked inside this lambda.
174
+ val packageJson = findPackageJsonFile(project, rootExtension.root)
175
+ val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
176
+
177
+ val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
178
+ val includesGeneratedCode =
179
+ parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
180
+ if (jsSrcsDirInPackageJson != null) {
181
+ it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
182
+ } else {
183
+ it.jsRootDir.set(localExtension.jsRootDir)
184
+ }
185
+ it.jsInputFiles.set(
186
+ project.fileTree(it.jsRootDir) { tree ->
187
+ tree.include("**/*.js")
188
+ tree.include("**/*.jsx")
189
+ tree.include("**/*.ts")
190
+ tree.include("**/*.tsx")
191
+
192
+ tree.exclude("node_modules/**/*")
193
+ tree.exclude("**/*.d.ts")
194
+ // We want to exclude the build directory, to don't pick them up for execution
195
+ // avoidance.
196
+ tree.exclude("**/build/**/*")
197
+ }
198
+ )
199
+
200
+ val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
201
+ it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
202
+ }
203
+
204
+ // We create the task to generate Java code from schema.
205
+ val generateCodegenArtifactsTask =
206
+ project.tasks.register(
207
+ "generateCodegenArtifactsFromSchema",
208
+ GenerateCodegenArtifactsTask::class.java,
209
+ ) { task ->
210
+ task.dependsOn(generateCodegenSchemaTask)
211
+ task.reactNativeDir.set(rootExtension.reactNativeDir)
212
+ task.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
213
+ task.generatedSrcDir.set(generatedSrcDir)
214
+ task.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root))
215
+ task.codegenJavaPackageName.set(localExtension.codegenJavaPackageName)
216
+ task.libraryName.set(localExtension.libraryName)
217
+ task.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
218
+
219
+ // Please note that appNeedsCodegen is triggering a read of the package.json at
220
+ // configuration time as we need to feed the onlyIf condition of this task.
221
+ // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
222
+ val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
223
+ val packageJson = findPackageJsonFile(project, rootExtension.root)
224
+ val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
225
+ val includesGeneratedCode =
226
+ parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
227
+ task.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
228
+ }
229
+
230
+ // We update the android configuration to include the generated sources.
231
+ // This equivalent to this DSL:
232
+ //
233
+ // android { sourceSets { main { java { srcDirs += "$generatedSrcDir/java" } } } }
234
+ if (isLibrary) {
235
+ project.extensions.getByType(LibraryAndroidComponentsExtension::class.java).finalizeDsl { ext
236
+ ->
237
+ ext.sourceSets.getByName("main").java.srcDir(generatedSrcDir.get().dir("java").asFile)
238
+ }
239
+ } else {
240
+ project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).finalizeDsl {
241
+ ext ->
242
+ ext.sourceSets.getByName("main").java.srcDir(generatedSrcDir.get().dir("java").asFile)
243
+ }
244
+ }
245
+
246
+ // `preBuild` is one of the base tasks automatically registered by AGP.
247
+ // This will invoke the codegen before compiling the entire project.
248
+ project.tasks.named("preBuild", Task::class.java).dependsOn(generateCodegenArtifactsTask)
249
+ }
250
+
251
+ /** This function sets up Autolinking for App users */
252
+ private fun configureAutolinking(
253
+ project: Project,
254
+ extension: ReactExtension,
255
+ ) {
256
+ val generatedAutolinkingJavaDir: Provider<Directory> =
257
+ project.layout.buildDirectory.dir("generated/autolinking/src/main/java")
258
+ val generatedAutolinkingJniDir: Provider<Directory> =
259
+ project.layout.buildDirectory.dir("generated/autolinking/src/main/jni")
260
+
261
+ // The autolinking.json file is available in the root build folder as it's generated
262
+ // by ReactSettingsPlugin.kt
263
+ val rootGeneratedAutolinkingFile =
264
+ project.rootProject.layout.buildDirectory.file("generated/autolinking/autolinking.json")
265
+
266
+ // We add a task called generateAutolinkingPackageList to do not clash with the existing task
267
+ // called generatePackageList. This can to be renamed once we unlink the rn <-> cli
268
+ // dependency.
269
+ val generatePackageListTask =
270
+ project.tasks.register(
271
+ "generateAutolinkingPackageList",
272
+ GeneratePackageListTask::class.java,
273
+ ) { task ->
274
+ task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
275
+ task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
276
+ }
277
+
278
+ // We add a task called generateAutolinkingPackageList to do not clash with the existing task
279
+ // called generatePackageList. This can to be renamed once we unlink the rn <-> cli
280
+ // dependency.
281
+ val generateEntryPointTask =
282
+ project.tasks.register(
283
+ "generateReactNativeEntryPoint",
284
+ GenerateEntryPointTask::class.java,
285
+ ) { task ->
286
+ task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
287
+ task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
288
+ }
289
+
290
+ // We also need to generate code for C++ Autolinking
291
+ val generateAutolinkingNewArchitectureFilesTask =
292
+ project.tasks.register(
293
+ "generateAutolinkingNewArchitectureFiles",
294
+ GenerateAutolinkingNewArchitecturesFileTask::class.java,
295
+ ) { task ->
296
+ task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
297
+ task.generatedOutputDirectory.set(generatedAutolinkingJniDir)
298
+ }
299
+ project.tasks
300
+ .named("preBuild", Task::class.java)
301
+ .dependsOn(generateAutolinkingNewArchitectureFilesTask)
302
+
303
+ // We let generateAutolinkingPackageList and generateEntryPoint depend on the preBuild task so
304
+ // it's executed before
305
+ // everything else.
306
+ project.tasks
307
+ .named("preBuild", Task::class.java)
308
+ .dependsOn(generatePackageListTask, generateEntryPointTask)
309
+
310
+ // We tell Android Gradle Plugin that inside /build/generated/autolinking/src/main/java there
311
+ // are sources to be compiled as well.
312
+ project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).apply {
313
+ onVariants(selector().all()) { variant ->
314
+ variant.sources.java?.addStaticSourceDirectory(
315
+ generatedAutolinkingJavaDir.get().asFile.absolutePath
316
+ )
317
+ }
318
+ }
319
+ }
320
+ }
@@ -0,0 +1,86 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react
9
+
10
+ import com.facebook.react.utils.PropertyUtils
11
+ import org.gradle.api.Plugin
12
+ import org.gradle.api.Project
13
+ import org.jetbrains.kotlin.gradle.plugin.extraProperties
14
+
15
+ /**
16
+ * Gradle plugin applied to the `android/build.gradle` file.
17
+ *
18
+ * This plugin allows to specify project wide configurations that can be applied to both apps and
19
+ * libraries before they're evaluated.
20
+ */
21
+ class ReactRootProjectPlugin : Plugin<Project> {
22
+ override fun apply(project: Project) {
23
+ checkLegacyArchProperty(project)
24
+ project.subprojects { subproject ->
25
+ // As the :app project (i.e. ReactPlugin) configures both namespaces and JVM toolchains
26
+ // for libraries, its evaluation must happen before the libraries' evaluation.
27
+ // Eventually the configuration of namespace/JVM toolchain can be moved inside this plugin.
28
+ if (subproject.path != ":app") {
29
+ subproject.evaluationDependsOn(":app")
30
+ }
31
+ // We set the New Architecture properties to true for all subprojects. So that
32
+ // libraries don't need to be modified and can keep on using the isNewArchEnabled()
33
+ // function to check if property is set.
34
+ if (subproject.hasProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED)) {
35
+ subproject.setProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED, "true")
36
+ }
37
+ if (subproject.hasProperty(PropertyUtils.NEW_ARCH_ENABLED)) {
38
+ subproject.setProperty(PropertyUtils.NEW_ARCH_ENABLED, "true")
39
+ }
40
+ subproject.extraProperties.set(PropertyUtils.NEW_ARCH_ENABLED, "true")
41
+ subproject.extraProperties.set(PropertyUtils.SCOPED_NEW_ARCH_ENABLED, "true")
42
+ }
43
+ // We need to make sure that `:app:preBuild` task depends on all other subprojects' preBuild
44
+ // tasks. This is necessary in order to have all the codegen generated code before the CMake
45
+ // configuration build kicks in.
46
+ project.gradle.projectsEvaluated {
47
+ val appProject = project.rootProject.subprojects.find { it.name == "app" }
48
+ val appPreBuild = appProject?.tasks?.findByName("preBuild")
49
+ if (appPreBuild != null) {
50
+ // Find all other subprojects' preBuild tasks
51
+ val otherPreBuildTasks =
52
+ project.rootProject.subprojects
53
+ .filter { it != appProject }
54
+ .mapNotNull { it.tasks.findByName("preBuild") }
55
+ // Make :app:preBuild depend on all others
56
+ appPreBuild.dependsOn(otherPreBuildTasks)
57
+ }
58
+ }
59
+ }
60
+
61
+ private fun checkLegacyArchProperty(project: Project) {
62
+ if (
63
+ (project.hasProperty(PropertyUtils.NEW_ARCH_ENABLED) &&
64
+ !project.property(PropertyUtils.NEW_ARCH_ENABLED).toString().toBoolean()) ||
65
+ (project.hasProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED) &&
66
+ !project.property(PropertyUtils.SCOPED_NEW_ARCH_ENABLED).toString().toBoolean())
67
+ ) {
68
+ project.logger.error(
69
+ """
70
+ ********************************************************************************
71
+
72
+ WARNING: Setting `newArchEnabled=false` in your `gradle.properties` file is not
73
+ supported anymore since React Native 0.82.
74
+
75
+ You can remove the line from your `gradle.properties` file.
76
+
77
+ The application will run with the New Architecture enabled by default.
78
+
79
+ ********************************************************************************
80
+
81
+ """
82
+ .trimIndent()
83
+ )
84
+ }
85
+ }
86
+ }
@@ -9,9 +9,12 @@ package com.facebook.react
9
9
 
10
10
  import com.android.build.api.variant.Variant
11
11
  import com.facebook.react.tasks.BundleHermesCTask
12
+ import com.facebook.react.utils.BackwardCompatUtils.showJSCRemovalMessage
13
+ import com.facebook.react.utils.KotlinStdlibCompatUtils.capitalizeCompat
12
14
  import com.facebook.react.utils.NdkConfiguratorUtils.configureJsEnginePackagingOptions
13
15
  import com.facebook.react.utils.NdkConfiguratorUtils.configureNewArchPackagingOptions
14
16
  import com.facebook.react.utils.ProjectUtils.isHermesEnabled
17
+ import com.facebook.react.utils.ProjectUtils.useThirdPartyJSC
15
18
  import com.facebook.react.utils.detectedCliFile
16
19
  import com.facebook.react.utils.detectedEntryFile
17
20
  import java.io.File
@@ -19,9 +22,10 @@ import org.gradle.api.Project
19
22
 
20
23
  @Suppress("SpreadOperator", "UnstableApiUsage")
21
24
  internal fun Project.configureReactTasks(variant: Variant, config: ReactExtension) {
22
- val targetName = variant.name.replaceFirstChar { it.uppercase() }
25
+ val targetName = variant.name.capitalizeCompat()
23
26
  val targetPath = variant.name
24
27
 
28
+ val buildDir = layout.buildDirectory.get().asFile
25
29
  // Resources: generated/assets/react/<variant>/index.android.bundle
26
30
  val resourcesDir = File(buildDir, "generated/res/react/$targetPath")
27
31
  // Bundle: generated/assets/react/<variant>/index.android.bundle
@@ -46,36 +50,43 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
46
50
  }
47
51
  val isDebuggableVariant =
48
52
  config.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) }
53
+ val useThirdPartyJSC = project.useThirdPartyJSC
49
54
 
50
- configureNewArchPackagingOptions(project, variant)
51
- configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant)
55
+ configureNewArchPackagingOptions(project, config, variant)
56
+ configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant, useThirdPartyJSC)
57
+ if (
58
+ !isHermesEnabledInThisVariant &&
59
+ !useThirdPartyJSC &&
60
+ rootProject.name != "react-native-github"
61
+ ) {
62
+ showJSCRemovalMessage(project)
63
+ }
52
64
 
53
65
  if (!isDebuggableVariant) {
54
66
  val entryFileEnvVariable = System.getenv("ENTRY_FILE")
55
67
  val bundleTask =
56
- tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) {
57
- it.root.set(config.root)
58
- it.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
59
- it.cliFile.set(cliFile)
60
- it.bundleCommand.set(config.bundleCommand)
61
- it.entryFile.set(detectedEntryFile(config, entryFileEnvVariable))
62
- it.extraPackagerArgs.set(config.extraPackagerArgs)
63
- it.bundleConfig.set(config.bundleConfig)
64
- it.bundleAssetName.set(config.bundleAssetName)
65
- it.jsBundleDir.set(jsBundleDir)
66
- it.resourcesDir.set(resourcesDir)
67
- it.hermesEnabled.set(isHermesEnabledInThisVariant)
68
- it.minifyEnabled.set(!isHermesEnabledInThisVariant)
69
- it.devEnabled.set(false)
70
- it.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
71
- it.jsSourceMapsDir.set(jsSourceMapsDir)
72
- it.hermesCommand.set(config.hermesCommand)
73
- it.hermesFlags.set(config.hermesFlags)
74
- it.reactNativeDir.set(config.reactNativeDir)
68
+ tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) { task
69
+ ->
70
+ task.root.set(config.root)
71
+ task.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
72
+ task.cliFile.set(cliFile)
73
+ task.bundleCommand.set(config.bundleCommand)
74
+ task.entryFile.set(detectedEntryFile(config, entryFileEnvVariable))
75
+ task.extraPackagerArgs.set(config.extraPackagerArgs)
76
+ task.bundleConfig.set(config.bundleConfig)
77
+ task.bundleAssetName.set(config.bundleAssetName)
78
+ task.jsBundleDir.set(jsBundleDir)
79
+ task.resourcesDir.set(resourcesDir)
80
+ task.hermesEnabled.set(isHermesEnabledInThisVariant)
81
+ task.minifyEnabled.set(!isHermesEnabledInThisVariant)
82
+ task.devEnabled.set(false)
83
+ task.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
84
+ task.jsSourceMapsDir.set(jsSourceMapsDir)
85
+ task.hermesCommand.set(config.hermesCommand)
86
+ task.hermesFlags.set(config.hermesFlags)
87
+ task.reactNativeDir.set(config.reactNativeDir)
75
88
  }
76
- // Currently broken inside AGP 7.3 We need to wait for a release of AGP 7.4 in order to use
77
- // the addGeneratedSourceDirectory API.
78
- // variant.sources.res?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::resourcesDir)
89
+ variant.sources.res?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::resourcesDir)
79
90
  variant.sources.assets?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::jsBundleDir)
80
91
  }
81
92
  }
@@ -11,6 +11,7 @@ import javax.inject.Inject
11
11
  import org.gradle.api.Project
12
12
  import org.gradle.api.file.DirectoryProperty
13
13
  import org.gradle.api.provider.ListProperty
14
+ import org.gradle.api.provider.Property
14
15
 
15
16
  /**
16
17
  * A private extension we set on the rootProject to make easier to share values at execution time
@@ -30,7 +31,7 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
30
31
  .directoryProperty()
31
32
  .convention(
32
33
  // This is the default for the project root if the users hasn't specified anything.
33
- // If the project is called "react-native-github"
34
+ // If the project is called "react-native-github" or "react-native-build-from-source"
34
35
  // - We're inside the Github Repo -> root is defined by RN Tester (so no default
35
36
  // needed)
36
37
  // - We're inside an includedBuild as we're performing a build from source
@@ -39,11 +40,15 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
39
40
  // - We're inside a user project, so inside the ./android folder. Default should be
40
41
  // ../
41
42
  // User can always override this default by setting a `root =` inside the template.
42
- if (project.rootProject.name == "react-native-github") {
43
+ if (
44
+ project.rootProject.name == "react-native-github" ||
45
+ project.rootProject.name == "react-native-build-from-source"
46
+ ) {
43
47
  project.rootProject.layout.projectDirectory.dir("../../")
44
48
  } else {
45
49
  project.rootProject.layout.projectDirectory.dir("../")
46
- })
50
+ }
51
+ )
47
52
 
48
53
  val reactNativeDir: DirectoryProperty =
49
54
  objects.directoryProperty().convention(root.dir("node_modules/react-native"))
@@ -52,5 +57,7 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
52
57
  objects.listProperty(String::class.java).convention(listOf("node"))
53
58
 
54
59
  val codegenDir: DirectoryProperty =
55
- objects.directoryProperty().convention(root.dir("node_modules/react-native-codegen"))
60
+ objects.directoryProperty().convention(root.dir("node_modules/@react-native/codegen"))
61
+
62
+ val hermesV1Enabled: Property<Boolean> = objects.property(Boolean::class.java).convention(true)
56
63
  }