@react-native/gradle-plugin 0.72.2 → 0.72.4
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.
- package/build.gradle.kts +1 -1
- package/package.json +1 -1
- package/src/main/kotlin/com/facebook/react/ReactExtension.kt +3 -3
- package/src/main/kotlin/com/facebook/react/ReactPlugin.kt +48 -20
- package/src/main/kotlin/com/facebook/react/TaskConfiguration.kt +9 -6
- package/src/main/kotlin/com/facebook/react/internal/PrivateReactExtension.kt +56 -0
- package/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt +28 -22
- package/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +5 -3
- package/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +5 -3
- package/src/main/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntry.kt +3 -2
- package/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +8 -0
- package/src/main/kotlin/com/facebook/react/utils/Os.kt +14 -1
- package/src/main/kotlin/com/facebook/react/utils/PathUtils.kt +30 -19
- package/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +12 -3
package/build.gradle.kts
CHANGED
|
@@ -33,7 +33,7 @@ group = "com.facebook.react"
|
|
|
33
33
|
|
|
34
34
|
dependencies {
|
|
35
35
|
implementation(gradleApi())
|
|
36
|
-
implementation("com.android.tools.build:gradle:7.4.
|
|
36
|
+
implementation("com.android.tools.build:gradle:7.4.1")
|
|
37
37
|
implementation("com.google.code.gson:gson:2.8.9")
|
|
38
38
|
implementation("com.google.guava:guava:31.0.1-jre")
|
|
39
39
|
implementation("com.squareup:javapoet:1.13.0")
|
package/package.json
CHANGED
|
@@ -89,7 +89,7 @@ abstract class ReactExtension @Inject constructor(project: Project) {
|
|
|
89
89
|
* will:
|
|
90
90
|
* - Not be bundled (the bundle file will not be created and won't be copied over).
|
|
91
91
|
* - Have the Hermes Debug flags set. That's useful if you have another variant (say `canary`)
|
|
92
|
-
*
|
|
92
|
+
* where you want dev mode to be enabled. Default: ['debug']
|
|
93
93
|
*/
|
|
94
94
|
val debuggableVariants: ListProperty<String> =
|
|
95
95
|
objects.listProperty(String::class.java).convention(listOf("debug"))
|
|
@@ -129,9 +129,9 @@ abstract class ReactExtension @Inject constructor(project: Project) {
|
|
|
129
129
|
/**
|
|
130
130
|
* The root directory for all JS files for the app.
|
|
131
131
|
*
|
|
132
|
-
* Default:
|
|
132
|
+
* Default: the parent folder of the `/android` folder.
|
|
133
133
|
*/
|
|
134
|
-
val jsRootDir: DirectoryProperty = objects.directoryProperty()
|
|
134
|
+
val jsRootDir: DirectoryProperty = objects.directoryProperty()
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
137
|
* The library name that will be used for the codegen artifacts.
|
|
@@ -9,6 +9,7 @@ package com.facebook.react
|
|
|
9
9
|
|
|
10
10
|
import com.android.build.api.variant.AndroidComponentsExtension
|
|
11
11
|
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
12
|
+
import com.facebook.react.internal.PrivateReactExtension
|
|
12
13
|
import com.facebook.react.tasks.BuildCodegenCLITask
|
|
13
14
|
import com.facebook.react.tasks.GenerateCodegenArtifactsTask
|
|
14
15
|
import com.facebook.react.tasks.GenerateCodegenSchemaTask
|
|
@@ -34,8 +35,22 @@ class ReactPlugin : Plugin<Project> {
|
|
|
34
35
|
checkJvmVersion(project)
|
|
35
36
|
val extension = project.extensions.create("react", ReactExtension::class.java, project)
|
|
36
37
|
|
|
38
|
+
// We register a private extension on the rootProject so that project wide configs
|
|
39
|
+
// like codegen config can be propagated from app project to libraries.
|
|
40
|
+
val rootExtension =
|
|
41
|
+
project.rootProject.extensions.findByType(PrivateReactExtension::class.java)
|
|
42
|
+
?: project.rootProject.extensions.create(
|
|
43
|
+
"privateReact", PrivateReactExtension::class.java, project)
|
|
44
|
+
|
|
37
45
|
// App Only Configuration
|
|
38
46
|
project.pluginManager.withPlugin("com.android.application") {
|
|
47
|
+
// We wire the root extension with the values coming from the app (either user populated or
|
|
48
|
+
// defaults).
|
|
49
|
+
rootExtension.root.set(extension.root)
|
|
50
|
+
rootExtension.reactNativeDir.set(extension.reactNativeDir)
|
|
51
|
+
rootExtension.codegenDir.set(extension.codegenDir)
|
|
52
|
+
rootExtension.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
|
|
53
|
+
|
|
39
54
|
project.afterEvaluate {
|
|
40
55
|
val reactNativeDir = extension.reactNativeDir.get().asFile
|
|
41
56
|
val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
|
|
@@ -54,12 +69,12 @@ class ReactPlugin : Plugin<Project> {
|
|
|
54
69
|
project.configureReactTasks(variant = variant, config = extension)
|
|
55
70
|
}
|
|
56
71
|
}
|
|
57
|
-
configureCodegen(project, extension, isLibrary = false)
|
|
72
|
+
configureCodegen(project, extension, rootExtension, isLibrary = false)
|
|
58
73
|
}
|
|
59
74
|
|
|
60
75
|
// Library Only Configuration
|
|
61
76
|
project.pluginManager.withPlugin("com.android.library") {
|
|
62
|
-
configureCodegen(project, extension, isLibrary = true)
|
|
77
|
+
configureCodegen(project, extension, rootExtension, isLibrary = true)
|
|
63
78
|
}
|
|
64
79
|
}
|
|
65
80
|
|
|
@@ -82,25 +97,36 @@ class ReactPlugin : Plugin<Project> {
|
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
99
|
|
|
85
|
-
/**
|
|
86
|
-
* A plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for more
|
|
87
|
-
* information: https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html
|
|
88
|
-
*/
|
|
100
|
+
/** This function sets up `react-native-codegen` in our Gradle plugin. */
|
|
89
101
|
@Suppress("UnstableApiUsage")
|
|
90
|
-
private fun configureCodegen(
|
|
102
|
+
private fun configureCodegen(
|
|
103
|
+
project: Project,
|
|
104
|
+
localExtension: ReactExtension,
|
|
105
|
+
rootExtension: PrivateReactExtension,
|
|
106
|
+
isLibrary: Boolean
|
|
107
|
+
) {
|
|
91
108
|
// First, we set up the output dir for the codegen.
|
|
92
109
|
val generatedSrcDir = File(project.buildDir, "generated/source/codegen")
|
|
93
110
|
|
|
111
|
+
// We specify the default value (convention) for jsRootDir.
|
|
112
|
+
// It's the root folder for apps (so ../../ from the Gradle project)
|
|
113
|
+
// and the package folder for library (so ../ from the Gradle project)
|
|
114
|
+
if (isLibrary) {
|
|
115
|
+
localExtension.jsRootDir.convention(project.layout.projectDirectory.dir("../"))
|
|
116
|
+
} else {
|
|
117
|
+
localExtension.jsRootDir.convention(localExtension.root)
|
|
118
|
+
}
|
|
119
|
+
|
|
94
120
|
val buildCodegenTask =
|
|
95
121
|
project.tasks.register("buildCodegenCLI", BuildCodegenCLITask::class.java) {
|
|
96
|
-
it.codegenDir.set(
|
|
122
|
+
it.codegenDir.set(rootExtension.codegenDir)
|
|
97
123
|
val bashWindowsHome = project.findProperty("REACT_WINDOWS_BASH") as String?
|
|
98
124
|
it.bashWindowsHome.set(bashWindowsHome)
|
|
99
125
|
|
|
100
126
|
// Please note that appNeedsCodegen is triggering a read of the package.json at
|
|
101
127
|
// configuration time as we need to feed the onlyIf condition of this task.
|
|
102
128
|
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
|
|
103
|
-
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(
|
|
129
|
+
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
|
|
104
130
|
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
|
|
105
131
|
}
|
|
106
132
|
|
|
@@ -109,23 +135,24 @@ class ReactPlugin : Plugin<Project> {
|
|
|
109
135
|
project.tasks.register(
|
|
110
136
|
"generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) { it ->
|
|
111
137
|
it.dependsOn(buildCodegenTask)
|
|
112
|
-
it.nodeExecutableAndArgs.set(
|
|
113
|
-
it.codegenDir.set(
|
|
138
|
+
it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
|
139
|
+
it.codegenDir.set(rootExtension.codegenDir)
|
|
114
140
|
it.generatedSrcDir.set(generatedSrcDir)
|
|
115
141
|
|
|
116
142
|
// We're reading the package.json at configuration time to properly feed
|
|
117
143
|
// the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
|
|
118
144
|
// parsePackageJson should be invoked inside this lambda.
|
|
119
|
-
val packageJson = findPackageJsonFile(project,
|
|
145
|
+
val packageJson = findPackageJsonFile(project, rootExtension.root)
|
|
120
146
|
val parsedPackageJson = packageJson?.let { JsonUtils.fromCodegenJson(it) }
|
|
121
147
|
|
|
122
148
|
val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
|
|
123
149
|
if (jsSrcsDirInPackageJson != null) {
|
|
124
150
|
it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
|
|
125
151
|
} else {
|
|
126
|
-
it.jsRootDir.set(
|
|
152
|
+
it.jsRootDir.set(localExtension.jsRootDir)
|
|
127
153
|
}
|
|
128
|
-
val needsCodegenFromPackageJson =
|
|
154
|
+
val needsCodegenFromPackageJson =
|
|
155
|
+
project.needsCodegenFromPackageJson(rootExtension.root)
|
|
129
156
|
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
|
|
130
157
|
}
|
|
131
158
|
|
|
@@ -134,17 +161,18 @@ class ReactPlugin : Plugin<Project> {
|
|
|
134
161
|
project.tasks.register(
|
|
135
162
|
"generateCodegenArtifactsFromSchema", GenerateCodegenArtifactsTask::class.java) {
|
|
136
163
|
it.dependsOn(generateCodegenSchemaTask)
|
|
137
|
-
it.reactNativeDir.set(
|
|
138
|
-
it.nodeExecutableAndArgs.set(
|
|
164
|
+
it.reactNativeDir.set(rootExtension.reactNativeDir)
|
|
165
|
+
it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
|
139
166
|
it.generatedSrcDir.set(generatedSrcDir)
|
|
140
|
-
it.packageJsonFile.set(findPackageJsonFile(project,
|
|
141
|
-
it.codegenJavaPackageName.set(
|
|
142
|
-
it.libraryName.set(
|
|
167
|
+
it.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root))
|
|
168
|
+
it.codegenJavaPackageName.set(localExtension.codegenJavaPackageName)
|
|
169
|
+
it.libraryName.set(localExtension.libraryName)
|
|
143
170
|
|
|
144
171
|
// Please note that appNeedsCodegen is triggering a read of the package.json at
|
|
145
172
|
// configuration time as we need to feed the onlyIf condition of this task.
|
|
146
173
|
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
|
|
147
|
-
val needsCodegenFromPackageJson =
|
|
174
|
+
val needsCodegenFromPackageJson =
|
|
175
|
+
project.needsCodegenFromPackageJson(rootExtension.root)
|
|
148
176
|
it.onlyIf { isLibrary || needsCodegenFromPackageJson }
|
|
149
177
|
}
|
|
150
178
|
|
|
@@ -22,14 +22,16 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
|
|
|
22
22
|
val targetName = variant.name.replaceFirstChar { it.uppercase() }
|
|
23
23
|
val targetPath = variant.name
|
|
24
24
|
|
|
25
|
-
//
|
|
25
|
+
// Resources: generated/assets/react/<variant>/index.android.bundle
|
|
26
26
|
val resourcesDir = File(buildDir, "generated/res/react/$targetPath")
|
|
27
|
-
// Bundle: generated/assets/react
|
|
27
|
+
// Bundle: generated/assets/react/<variant>/index.android.bundle
|
|
28
28
|
val jsBundleDir = File(buildDir, "generated/assets/react/$targetPath")
|
|
29
|
-
// Sourcemap: generated/sourcemaps/react
|
|
29
|
+
// Sourcemap: generated/sourcemaps/react/<variant>/index.android.bundle.map
|
|
30
30
|
val jsSourceMapsDir = File(buildDir, "generated/sourcemaps/react/$targetPath")
|
|
31
|
-
// Intermediate packager:
|
|
32
|
-
//
|
|
31
|
+
// Intermediate packager:
|
|
32
|
+
// intermediates/sourcemaps/react/<variant>/index.android.bundle.packager.map
|
|
33
|
+
// Intermediate compiler:
|
|
34
|
+
// intermediates/sourcemaps/react/<variant>/index.android.bundle.compiler.map
|
|
33
35
|
val jsIntermediateSourceMapsDir = File(buildDir, "intermediates/sourcemaps/react/$targetPath")
|
|
34
36
|
|
|
35
37
|
// The location of the cli.js file for React Native
|
|
@@ -49,13 +51,14 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
|
|
|
49
51
|
configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant)
|
|
50
52
|
|
|
51
53
|
if (!isDebuggableVariant) {
|
|
54
|
+
val entryFileEnvVariable = System.getenv("ENTRY_FILE")
|
|
52
55
|
val bundleTask =
|
|
53
56
|
tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) {
|
|
54
57
|
it.root.set(config.root)
|
|
55
58
|
it.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
|
|
56
59
|
it.cliFile.set(cliFile)
|
|
57
60
|
it.bundleCommand.set(config.bundleCommand)
|
|
58
|
-
it.entryFile.set(detectedEntryFile(config))
|
|
61
|
+
it.entryFile.set(detectedEntryFile(config, entryFileEnvVariable))
|
|
59
62
|
it.extraPackagerArgs.set(config.extraPackagerArgs)
|
|
60
63
|
it.bundleConfig.set(config.bundleConfig)
|
|
61
64
|
it.bundleAssetName.set(config.bundleAssetName)
|
|
@@ -0,0 +1,56 @@
|
|
|
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.internal
|
|
9
|
+
|
|
10
|
+
import javax.inject.Inject
|
|
11
|
+
import org.gradle.api.Project
|
|
12
|
+
import org.gradle.api.file.DirectoryProperty
|
|
13
|
+
import org.gradle.api.provider.ListProperty
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A private extension we set on the rootProject to make easier to share values at execution time
|
|
17
|
+
* between app project and library project.
|
|
18
|
+
*
|
|
19
|
+
* Specifically, the [codegenDir], [reactNativeDir] and other properties should be provided by apps
|
|
20
|
+
* (for setups like a monorepo which are app specific) and libraries should honor those values.
|
|
21
|
+
*
|
|
22
|
+
* Users are not supposed to access directly this extension from their build.gradle file.
|
|
23
|
+
*/
|
|
24
|
+
abstract class PrivateReactExtension @Inject constructor(project: Project) {
|
|
25
|
+
|
|
26
|
+
private val objects = project.objects
|
|
27
|
+
|
|
28
|
+
val root: DirectoryProperty =
|
|
29
|
+
objects
|
|
30
|
+
.directoryProperty()
|
|
31
|
+
.convention(
|
|
32
|
+
// 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
|
+
// - We're inside the Github Repo -> root is defined by RN Tester (so no default
|
|
35
|
+
// needed)
|
|
36
|
+
// - We're inside an includedBuild as we're performing a build from source
|
|
37
|
+
// (then we're inside `node_modules/react-native`, so default should be ../../)
|
|
38
|
+
// If the project is called in any other name
|
|
39
|
+
// - We're inside a user project, so inside the ./android folder. Default should be
|
|
40
|
+
// ../
|
|
41
|
+
// User can always override this default by setting a `root =` inside the template.
|
|
42
|
+
if (project.rootProject.name == "react-native-github") {
|
|
43
|
+
project.rootProject.layout.projectDirectory.dir("../../")
|
|
44
|
+
} else {
|
|
45
|
+
project.rootProject.layout.projectDirectory.dir("../")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
val reactNativeDir: DirectoryProperty =
|
|
49
|
+
objects.directoryProperty().convention(root.dir("node_modules/react-native"))
|
|
50
|
+
|
|
51
|
+
val nodeExecutableAndArgs: ListProperty<String> =
|
|
52
|
+
objects.listProperty(String::class.java).convention(listOf("node"))
|
|
53
|
+
|
|
54
|
+
val codegenDir: DirectoryProperty =
|
|
55
|
+
objects.directoryProperty().convention(root.dir("node_modules/@react-native/codegen"))
|
|
56
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.tasks
|
|
9
9
|
|
|
10
|
+
import com.facebook.react.utils.Os.cliPath
|
|
10
11
|
import com.facebook.react.utils.detectOSAwareHermesCommand
|
|
11
12
|
import com.facebook.react.utils.moveTo
|
|
12
13
|
import com.facebook.react.utils.windowsAwareCommandLine
|
|
@@ -135,8 +136,9 @@ abstract class BundleHermesCTask : DefaultTask() {
|
|
|
135
136
|
internal fun getBundleCommand(bundleFile: File, sourceMapFile: File): List<Any> =
|
|
136
137
|
windowsAwareCommandLine(
|
|
137
138
|
buildList {
|
|
139
|
+
val rootFile = root.get().asFile
|
|
138
140
|
addAll(nodeExecutableAndArgs.get())
|
|
139
|
-
add(cliFile.get().asFile.
|
|
141
|
+
add(cliFile.get().asFile.cliPath(rootFile))
|
|
140
142
|
add(bundleCommand.get())
|
|
141
143
|
add("--platform")
|
|
142
144
|
add("android")
|
|
@@ -144,16 +146,16 @@ abstract class BundleHermesCTask : DefaultTask() {
|
|
|
144
146
|
add(devEnabled.get().toString())
|
|
145
147
|
add("--reset-cache")
|
|
146
148
|
add("--entry-file")
|
|
147
|
-
add(entryFile.get().asFile.
|
|
149
|
+
add(entryFile.get().asFile.cliPath(rootFile))
|
|
148
150
|
add("--bundle-output")
|
|
149
|
-
add(bundleFile.
|
|
151
|
+
add(bundleFile.cliPath(rootFile))
|
|
150
152
|
add("--assets-dest")
|
|
151
|
-
add(resourcesDir.get().asFile.
|
|
153
|
+
add(resourcesDir.get().asFile.cliPath(rootFile))
|
|
152
154
|
add("--sourcemap-output")
|
|
153
|
-
add(sourceMapFile.
|
|
155
|
+
add(sourceMapFile.cliPath(rootFile))
|
|
154
156
|
if (bundleConfig.isPresent) {
|
|
155
157
|
add("--config")
|
|
156
|
-
add(bundleConfig.get().asFile.
|
|
158
|
+
add(bundleConfig.get().asFile.cliPath(rootFile))
|
|
157
159
|
}
|
|
158
160
|
add("--minify")
|
|
159
161
|
add(minifyEnabled.get().toString())
|
|
@@ -165,26 +167,30 @@ abstract class BundleHermesCTask : DefaultTask() {
|
|
|
165
167
|
hermesCommand: String,
|
|
166
168
|
bytecodeFile: File,
|
|
167
169
|
bundleFile: File
|
|
168
|
-
): List<Any>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
): List<Any> {
|
|
171
|
+
val rootFile = root.get().asFile
|
|
172
|
+
return windowsAwareCommandLine(
|
|
173
|
+
hermesCommand,
|
|
174
|
+
"-emit-binary",
|
|
175
|
+
"-out",
|
|
176
|
+
bytecodeFile.cliPath(rootFile),
|
|
177
|
+
bundleFile.cliPath(rootFile),
|
|
178
|
+
*hermesFlags.get().toTypedArray())
|
|
179
|
+
}
|
|
176
180
|
|
|
177
181
|
internal fun getComposeSourceMapsCommand(
|
|
178
182
|
composeScript: File,
|
|
179
183
|
packagerSourceMap: File,
|
|
180
184
|
compilerSourceMap: File,
|
|
181
185
|
outputSourceMap: File
|
|
182
|
-
): List<Any>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
): List<Any> {
|
|
187
|
+
val rootFile = root.get().asFile
|
|
188
|
+
return windowsAwareCommandLine(
|
|
189
|
+
*nodeExecutableAndArgs.get().toTypedArray(),
|
|
190
|
+
composeScript.cliPath(rootFile),
|
|
191
|
+
packagerSourceMap.cliPath(rootFile),
|
|
192
|
+
compilerSourceMap.cliPath(rootFile),
|
|
193
|
+
"-o",
|
|
194
|
+
outputSourceMap.cliPath(rootFile))
|
|
195
|
+
}
|
|
190
196
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
package com.facebook.react.tasks
|
|
9
9
|
|
|
10
10
|
import com.facebook.react.utils.JsonUtils
|
|
11
|
+
import com.facebook.react.utils.Os.cliPath
|
|
11
12
|
import com.facebook.react.utils.windowsAwareCommandLine
|
|
12
13
|
import org.gradle.api.file.Directory
|
|
13
14
|
import org.gradle.api.file.DirectoryProperty
|
|
@@ -63,16 +64,17 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
internal fun setupCommandLine(libraryName: String, codegenJavaPackageName: String) {
|
|
67
|
+
val workingDir = project.projectDir
|
|
66
68
|
commandLine(
|
|
67
69
|
windowsAwareCommandLine(
|
|
68
70
|
*nodeExecutableAndArgs.get().toTypedArray(),
|
|
69
|
-
reactNativeDir.file("scripts/generate-specs-cli.js").get().asFile.
|
|
71
|
+
reactNativeDir.file("scripts/generate-specs-cli.js").get().asFile.cliPath(workingDir),
|
|
70
72
|
"--platform",
|
|
71
73
|
"android",
|
|
72
74
|
"--schemaPath",
|
|
73
|
-
generatedSchemaFile.get().asFile.
|
|
75
|
+
generatedSchemaFile.get().asFile.cliPath(workingDir),
|
|
74
76
|
"--outputDir",
|
|
75
|
-
generatedSrcDir.get().asFile.
|
|
77
|
+
generatedSrcDir.get().asFile.cliPath(workingDir),
|
|
76
78
|
"--libraryName",
|
|
77
79
|
libraryName,
|
|
78
80
|
"--javaPackageName",
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.tasks
|
|
9
9
|
|
|
10
|
+
import com.facebook.react.utils.Os.cliPath
|
|
10
11
|
import com.facebook.react.utils.windowsAwareCommandLine
|
|
11
12
|
import org.gradle.api.file.DirectoryProperty
|
|
12
13
|
import org.gradle.api.file.RegularFile
|
|
@@ -63,6 +64,7 @@ abstract class GenerateCodegenSchemaTask : Exec() {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
internal fun setupCommandLine() {
|
|
67
|
+
val workingDir = project.projectDir
|
|
66
68
|
commandLine(
|
|
67
69
|
windowsAwareCommandLine(
|
|
68
70
|
*nodeExecutableAndArgs.get().toTypedArray(),
|
|
@@ -70,11 +72,11 @@ abstract class GenerateCodegenSchemaTask : Exec() {
|
|
|
70
72
|
.file("lib/cli/combine/combine-js-to-schema-cli.js")
|
|
71
73
|
.get()
|
|
72
74
|
.asFile
|
|
73
|
-
.
|
|
75
|
+
.cliPath(workingDir),
|
|
74
76
|
"--platform",
|
|
75
77
|
"android",
|
|
76
|
-
generatedSchemaFile.get().asFile.
|
|
77
|
-
jsRootDir.asFile.get().
|
|
78
|
+
generatedSchemaFile.get().asFile.cliPath(workingDir),
|
|
79
|
+
jsRootDir.asFile.get().cliPath(workingDir),
|
|
78
80
|
))
|
|
79
81
|
}
|
|
80
82
|
}
|
|
@@ -11,10 +11,11 @@ import java.io.Serializable
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* This data class represents an entry that can be consumed by the [PreparePrefabHeadersTask].
|
|
14
|
+
*
|
|
14
15
|
* @param libraryName The name of the library that you're preparing for Prefab
|
|
15
16
|
* @param pathToPrefixCouples A list of pairs Path to Header prefix. You can use this list to supply
|
|
16
|
-
*
|
|
17
|
-
* that will be used by prefab to re-created the header layout.
|
|
17
|
+
* a list of paths that you want to be considered for prefab. Each path can specify an header
|
|
18
|
+
* prefix that will be used by prefab to re-created the header layout.
|
|
18
19
|
*/
|
|
19
20
|
data class PrefabPreprocessingEntry(
|
|
20
21
|
val libraryName: String,
|
|
@@ -10,6 +10,7 @@ package com.facebook.react.utils
|
|
|
10
10
|
import com.android.build.api.variant.AndroidComponentsExtension
|
|
11
11
|
import com.android.build.api.variant.Variant
|
|
12
12
|
import com.facebook.react.ReactExtension
|
|
13
|
+
import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures
|
|
13
14
|
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
|
|
14
15
|
import java.io.File
|
|
15
16
|
import org.gradle.api.Project
|
|
@@ -49,6 +50,13 @@ internal object NdkConfiguratorUtils {
|
|
|
49
50
|
if ("-DANDROID_STL" !in cmakeArgs) {
|
|
50
51
|
cmakeArgs.add("-DANDROID_STL=c++_shared")
|
|
51
52
|
}
|
|
53
|
+
|
|
54
|
+
val architectures = project.getReactNativeArchitectures()
|
|
55
|
+
// abiFilters are split ABI are not compatible each other, so we set the abiFilters
|
|
56
|
+
// only if the user hasn't enabled the split abi feature.
|
|
57
|
+
if (architectures.isNotEmpty() && !ext.splits.abi.isEnable) {
|
|
58
|
+
ext.defaultConfig.ndk.abiFilters.addAll(architectures)
|
|
59
|
+
}
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.utils
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
import java.io.File
|
|
11
|
+
|
|
12
|
+
internal object Os {
|
|
11
13
|
|
|
12
14
|
fun isWindows(): Boolean =
|
|
13
15
|
System.getProperty("os.name")?.lowercase()?.contains("windows") ?: false
|
|
@@ -28,4 +30,15 @@ object Os {
|
|
|
28
30
|
it
|
|
29
31
|
}
|
|
30
32
|
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* As Gradle doesn't support well path with spaces on Windows, we need to return relative path on
|
|
36
|
+
* Win. On Linux & Mac we'll default to return absolute path.
|
|
37
|
+
*/
|
|
38
|
+
fun File.cliPath(base: File): String =
|
|
39
|
+
if (isWindows()) {
|
|
40
|
+
this.relativeTo(base).path
|
|
41
|
+
} else {
|
|
42
|
+
this.absolutePath
|
|
43
|
+
}
|
|
31
44
|
}
|
|
@@ -11,8 +11,10 @@ package com.facebook.react.utils
|
|
|
11
11
|
|
|
12
12
|
import com.facebook.react.ReactExtension
|
|
13
13
|
import com.facebook.react.model.ModelPackageJson
|
|
14
|
+
import com.facebook.react.utils.Os.cliPath
|
|
14
15
|
import java.io.File
|
|
15
16
|
import org.gradle.api.Project
|
|
17
|
+
import org.gradle.api.file.DirectoryProperty
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Computes the entry file for React Native. The Algo follows this order:
|
|
@@ -23,9 +25,11 @@ import org.gradle.api.Project
|
|
|
23
25
|
*
|
|
24
26
|
* @param config The [ReactExtension] configured for this project
|
|
25
27
|
*/
|
|
26
|
-
internal fun detectedEntryFile(config: ReactExtension): File =
|
|
28
|
+
internal fun detectedEntryFile(config: ReactExtension, envVariableOverride: String? = null): File =
|
|
27
29
|
detectEntryFile(
|
|
28
|
-
entryFile = config.entryFile.orNull?.asFile,
|
|
30
|
+
entryFile = config.entryFile.orNull?.asFile,
|
|
31
|
+
reactRoot = config.root.get().asFile,
|
|
32
|
+
envVariableOverride = envVariableOverride)
|
|
29
33
|
|
|
30
34
|
/**
|
|
31
35
|
* Computes the CLI file for React Native. The Algo follows this order:
|
|
@@ -43,18 +47,22 @@ internal fun detectedCliFile(config: ReactExtension): File =
|
|
|
43
47
|
* Computes the `hermesc` command location. The Algo follows this order:
|
|
44
48
|
* 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
|
|
45
49
|
* 2. The file located in `node_modules/react-native/sdks/hermes/build/bin/hermesc`. This will be
|
|
46
|
-
*
|
|
50
|
+
* used if the user is building Hermes from source.
|
|
47
51
|
* 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
|
|
48
|
-
*
|
|
49
|
-
*
|
|
52
|
+
* is substituted with the correct OS arch. This will be used if the user is using a precompiled
|
|
53
|
+
* hermes-engine package.
|
|
50
54
|
* 4. Fails otherwise
|
|
51
55
|
*/
|
|
52
56
|
internal fun detectedHermesCommand(config: ReactExtension): String =
|
|
53
57
|
detectOSAwareHermesCommand(config.root.get().asFile, config.hermesCommand.get())
|
|
54
58
|
|
|
55
|
-
private fun detectEntryFile(
|
|
59
|
+
private fun detectEntryFile(
|
|
60
|
+
entryFile: File?,
|
|
61
|
+
reactRoot: File,
|
|
62
|
+
envVariableOverride: String? = null
|
|
63
|
+
): File =
|
|
56
64
|
when {
|
|
57
|
-
|
|
65
|
+
envVariableOverride != null -> File(reactRoot, envVariableOverride)
|
|
58
66
|
entryFile != null -> entryFile
|
|
59
67
|
File(reactRoot, "index.android.js").exists() -> File(reactRoot, "index.android.js")
|
|
60
68
|
else -> File(reactRoot, "index.js")
|
|
@@ -106,10 +114,10 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
|
|
|
106
114
|
* Computes the `hermesc` command location. The Algo follows this order:
|
|
107
115
|
* 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
|
|
108
116
|
* 2. The file located in `node_modules/react-native/sdks/hermes/build/bin/hermesc`. This will be
|
|
109
|
-
*
|
|
117
|
+
* used if the user is building Hermes from source.
|
|
110
118
|
* 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
|
|
111
|
-
*
|
|
112
|
-
*
|
|
119
|
+
* is substituted with the correct OS arch. This will be used if the user is using a precompiled
|
|
120
|
+
* hermes-engine package.
|
|
113
121
|
* 4. Fails otherwise
|
|
114
122
|
*/
|
|
115
123
|
internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String): String {
|
|
@@ -130,7 +138,7 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
|
|
|
130
138
|
val builtHermesc =
|
|
131
139
|
getBuiltHermescFile(projectRoot, System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR"))
|
|
132
140
|
if (builtHermesc.exists()) {
|
|
133
|
-
return builtHermesc.
|
|
141
|
+
return builtHermesc.cliPath(projectRoot)
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
// 3. If the react-native contains a pre-built hermesc, use it.
|
|
@@ -142,7 +150,7 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
|
|
|
142
150
|
|
|
143
151
|
val prebuiltHermes = File(projectRoot, prebuiltHermesPath)
|
|
144
152
|
if (prebuiltHermes.exists()) {
|
|
145
|
-
return prebuiltHermes.
|
|
153
|
+
return prebuiltHermes.cliPath(projectRoot)
|
|
146
154
|
}
|
|
147
155
|
|
|
148
156
|
error(
|
|
@@ -188,13 +196,13 @@ internal fun projectPathToLibraryName(projectPath: String): String =
|
|
|
188
196
|
* Gradle module (generally the case for library projects) or we fallback to looking into the `root`
|
|
189
197
|
* folder of a React Native project (generally the case for app projects).
|
|
190
198
|
*/
|
|
191
|
-
internal fun findPackageJsonFile(project: Project,
|
|
199
|
+
internal fun findPackageJsonFile(project: Project, rootProperty: DirectoryProperty): File? {
|
|
192
200
|
val inParent = project.file("../package.json")
|
|
193
201
|
if (inParent.exists()) {
|
|
194
202
|
return inParent
|
|
195
203
|
}
|
|
196
204
|
|
|
197
|
-
val fromExtension =
|
|
205
|
+
val fromExtension = rootProperty.file("package.json").orNull?.asFile
|
|
198
206
|
if (fromExtension?.exists() == true) {
|
|
199
207
|
return fromExtension
|
|
200
208
|
}
|
|
@@ -206,12 +214,15 @@ internal fun findPackageJsonFile(project: Project, extension: ReactExtension): F
|
|
|
206
214
|
* Function to look for the `package.json` and parse it. It returns a [ModelPackageJson] if found or
|
|
207
215
|
* null others.
|
|
208
216
|
*
|
|
209
|
-
* Please note that this function access the [
|
|
210
|
-
*
|
|
211
|
-
*
|
|
217
|
+
* Please note that this function access the [DirectoryProperty] parameter and calls .get() on them,
|
|
218
|
+
* so calling this during apply() of the ReactPlugin is not recommended. It should be invoked inside
|
|
219
|
+
* lazy lambdas or at execution time.
|
|
212
220
|
*/
|
|
213
|
-
internal fun readPackageJsonFile(
|
|
214
|
-
|
|
221
|
+
internal fun readPackageJsonFile(
|
|
222
|
+
project: Project,
|
|
223
|
+
rootProperty: DirectoryProperty
|
|
224
|
+
): ModelPackageJson? {
|
|
225
|
+
val packageJson = findPackageJsonFile(project, rootProperty)
|
|
215
226
|
return packageJson?.let { JsonUtils.fromCodegenJson(it) }
|
|
216
227
|
}
|
|
217
228
|
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
package com.facebook.react.utils
|
|
9
9
|
|
|
10
|
-
import com.facebook.react.ReactExtension
|
|
11
10
|
import com.facebook.react.model.ModelPackageJson
|
|
12
11
|
import org.gradle.api.Project
|
|
12
|
+
import org.gradle.api.file.DirectoryProperty
|
|
13
13
|
|
|
14
14
|
internal object ProjectUtils {
|
|
15
15
|
internal val Project.isNewArchEnabled: Boolean
|
|
@@ -35,12 +35,21 @@ internal object ProjectUtils {
|
|
|
35
35
|
HERMES_FALLBACK
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
internal fun Project.needsCodegenFromPackageJson(
|
|
39
|
-
val parsedPackageJson = readPackageJsonFile(this,
|
|
38
|
+
internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean {
|
|
39
|
+
val parsedPackageJson = readPackageJsonFile(this, rootProperty)
|
|
40
40
|
return needsCodegenFromPackageJson(parsedPackageJson)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
internal fun Project.needsCodegenFromPackageJson(model: ModelPackageJson?): Boolean {
|
|
44
44
|
return model?.codegenConfig != null
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
internal fun Project.getReactNativeArchitectures(): List<String> {
|
|
48
|
+
val architectures = mutableListOf<String>()
|
|
49
|
+
if (project.hasProperty("reactNativeArchitectures")) {
|
|
50
|
+
val architecturesString = project.property("reactNativeArchitectures").toString()
|
|
51
|
+
architectures.addAll(architecturesString.split(",").filter { it.isNotBlank() })
|
|
52
|
+
}
|
|
53
|
+
return architectures
|
|
54
|
+
}
|
|
46
55
|
}
|