Skip to content

Commit edd8a81

Browse files
committed
[android][gradle] Use Node's module resolution algo to find JSC & Hermes
The Gradle build file looks up jsc-android and hermes-engine using hard-coded paths. Rather than assuming the location of these packages, which are distributed and installed as npm packages, this commit makes the Gradle file use Node's standard module resolution algorithm. It looks up the file hierarchy until it finds a matching npm package or reaches the root directory. Test plan: Ensure that CI tests pass, and that `./gradlew :ReactAndroid:installArchives` works. Printed out the paths that the Gradle script found for jsc-android and hermes-engine (both were `<my stuff>/react-native/node_modules/jsc-android|hermes-engine`).
1 parent 86af90f commit edd8a81

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

ReactAndroid/build.gradle

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ plugins {
99
id("de.undercouch.download")
1010
}
1111

12+
import java.nio.file.Paths
13+
1214
import de.undercouch.gradle.tasks.download.Download
1315
import org.apache.tools.ant.taskdefs.condition.Os
1416
import org.apache.tools.ant.filters.ReplaceTokens
@@ -92,8 +94,14 @@ task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy
9294
}
9395

9496
task prepareHermes() {
95-
def hermesAAR = file("$projectDir/../node_modules/hermes-engine/android/hermes-debug.aar")
96-
if (!hermesAAR.exists()) {
97+
def hermesAAR = null
98+
def hermesPackagePath = findNodeModulePath(projectDir, "hermes-engine")
99+
if (hermesPackagePath) {
100+
hermesAAR = file("$hermesPackagePath/android/hermes-debug.aar")
101+
if (!hermesAAR.exists()) {
102+
throw new GradleScriptException("The hermes-engine npm package is missing \"android/hermes-debug.aar\"")
103+
}
104+
} else {
97105
// For an app to build from RN source, hermes-engine is located at /path/to/app/node_modules
98106
// and $projectDir is located at /path/to/app/node_modules/react-native/ReactAndroid
99107
hermesAAR = file("$projectDir/../../hermes-engine/android/hermes-debug.aar")
@@ -160,16 +168,22 @@ task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy)
160168
// Create Android.mk library module based on jsc from npm
161169
task prepareJSC {
162170
doLast {
163-
def jscPackageRoot = file("$projectDir/../node_modules/jsc-android/dist")
164-
if (!jscPackageRoot.exists()) {
171+
def jscDist = null
172+
def jscPackagePath = findNodeModulePath(projectDir, "jsc-android")
173+
if (jscPackagePath) {
174+
jscDist = file("$jscPackagePath/dist")
175+
if (!jscDist.exists()) {
176+
throw new GradleScriptException("The jsc-android npm package is missing its \"dist\" directory")
177+
}
178+
} else {
165179
// For an app to build from RN source, the jsc-android is located at /path/to/app/node_modules
166180
// and $projectDir may located at /path/to/app/node_modules/react-native/ReactAndroid
167-
jscPackageRoot = file("$projectDir/../../jsc-android/dist")
181+
jscDist = file("$projectDir/../../jsc-android/dist")
168182
}
169-
def jscAAR = fileTree(jscPackageRoot).matching({ it.include "**/android-jsc/**/*.aar" }).singleFile
183+
def jscAAR = fileTree(jscDist).matching({ it.include "**/android-jsc/**/*.aar" }).singleFile
170184
def soFiles = zipTree(jscAAR).matching({ it.include "**/*.so" })
171185

172-
def headerFiles = fileTree(jscPackageRoot).matching({ it.include "**/include/*.h" })
186+
def headerFiles = fileTree(jscDist).matching({ it.include "**/include/*.h" })
173187

174188
copy {
175189
from(soFiles)
@@ -192,6 +206,20 @@ task downloadNdkBuildDependencies {
192206
dependsOn(downloadGlog)
193207
}
194208

209+
def findNodeModulePath(baseDir, packageName) {
210+
def basePath = baseDir.toPath().normalize()
211+
// Node's module resolution algorithm searches up to the root directory,
212+
// after which the base path will be null
213+
while (basePath) {
214+
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
215+
if (candidatePath.toFile().exists()) {
216+
return candidatePath.toString()
217+
}
218+
basePath = basePath.getParent()
219+
}
220+
return null
221+
}
222+
195223
def getNdkBuildName() {
196224
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
197225
return "ndk-build.cmd"

0 commit comments

Comments
 (0)