diff --git a/packages/react-native/ReactAndroid/hermes-engine/build.gradle b/packages/react-native/ReactAndroid/hermes-engine/build.gradle index 176ee40db0c..88f47e54b96 100644 --- a/packages/react-native/ReactAndroid/hermes-engine/build.gradle +++ b/packages/react-native/ReactAndroid/hermes-engine/build.gradle @@ -42,6 +42,16 @@ def downloadsDir = customDownloadDir ? new File(customDownloadDir) : new File(re def overrideHermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") != null def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: new File(reactNativeRootDir, "sdks/hermes") def hermesBuildDir = new File("$buildDir/hermes") +def hermesCOutputBinary = new File("$buildDir/hermes/bin/hermesc") +// This filetree represents the file of the Hermes build that we want as input/output +// of the buildHermesC task. Gradle will compute the hash of files in the file tree +// and won't rebuilt hermesc unless those files are changing. +def hermesBuildOutputFileTree = fileTree(hermesBuildDir.toString()) + .exclude('**/*.make') + .exclude('**/*.internal') + .exclude('**/external/**') + .exclude('**/hermes.framework/**') + .exclude('**/bin/hermesc') def hermesVersion = "main" def hermesVersionFile = new File(reactNativeRootDir, "sdks/.hermesversion") @@ -86,12 +96,36 @@ task unzipHermes(dependsOn: downloadHermes, type: Copy) { task configureBuildForHermes(type: Exec) { workingDir(hermesDir) - commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), Os.isFamily(Os.FAMILY_WINDOWS) ? "-GNMake Makefiles" : "", "-S", ".", "-B", hermesBuildDir.toString(), "-DJSI_DIR=" + jsiDir.absolutePath)) + inputs.dir(hermesDir) + outputs.files(hermesBuildOutputFileTree) + commandLine( + windowsAwareCommandLine( + findCmakePath(cmakeVersion), + Os.isFamily(Os.FAMILY_WINDOWS) ? "-GNMake Makefiles" : "", + "-S", + ".", + "-B", + hermesBuildDir.toString(), + "-DJSI_DIR=" + jsiDir.absolutePath + ) + ) } -task buildHermes(dependsOn: configureBuildForHermes, type: Exec) { +task buildHermesC(dependsOn: configureBuildForHermes, type: Exec) { workingDir(hermesDir) - commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), "--build", hermesBuildDir.toString(), "--target", "hermesc", "-j", ndkBuildJobs)) + inputs.files(hermesBuildOutputFileTree) + outputs.file(hermesCOutputBinary) + commandLine( + windowsAwareCommandLine( + findCmakePath(cmakeVersion), + "--build", + hermesBuildDir.toString(), + "--target", + "hermesc", + "-j", + ndkBuildJobs, + ) + ) } task prepareHeadersForPrefab(type: Copy) { @@ -258,9 +292,9 @@ afterEvaluate { configureBuildForHermes.dependsOn(unzipHermes) prepareHeadersForPrefab.dependsOn(unzipHermes) } - preBuild.dependsOn(buildHermes) + preBuild.dependsOn(buildHermesC) preBuild.dependsOn(prepareHeadersForPrefab) - prepareHeadersForPrefab.dependsOn(buildHermes) + prepareHeadersForPrefab.dependsOn(buildHermesC) } /* Publishing Configuration */ diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index 3c0874e82c9..a4d46e130a4 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -181,7 +181,7 @@ android { afterEvaluate { // As we're consuming Hermes from source, we want to make sure // `hermesc` is built before we actually invoke the `emit*HermesResource` task - createBundleHermesReleaseJsAndAssets.dependsOn(":packages:react-native:ReactAndroid:hermes-engine:buildHermes") + createBundleHermesReleaseJsAndAssets.dependsOn(":packages:react-native:ReactAndroid:hermes-engine:buildHermesC") // As we're building 4 native flavors in parallel, there is clash on the `.cxx/Debug` and // `.cxx/Release` folder where the CMake intermediates are stored.