Skip to content

Commit 2e0bd13

Browse files
j-piaseckifacebook-github-bot
authored andcommitted
Use hermesc from node_modules when consuming prebuilt hermes (#53581)
Summary: Pull Request resolved: #53581 Changelog: [General][Changed] - Changed the source of hermesc binary to be an npm package Reviewed By: cipolleschi, cortinico Differential Revision: D81224001 fbshipit-source-id: 552d0e66fb891974d7b688bfc0bec95e19345d86
1 parent 3e9990f commit 2e0bd13

4 files changed

Lines changed: 45 additions & 6 deletions

File tree

packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ abstract class BundleHermesCTask : DefaultTask() {
9494
runCommand(bundleCommand)
9595

9696
if (hermesEnabled.get()) {
97-
val detectedHermesCommand = detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get())
97+
val hermesV1Enabled =
98+
if (project.rootProject.hasProperty("hermesV1Enabled"))
99+
project.rootProject.findProperty("hermesV1Enabled") == "true"
100+
else false
101+
val detectedHermesCommand =
102+
detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get(), hermesV1Enabled)
98103
val bytecodeFile = File("${bundleFile}.hbc")
99104
val outputSourceMap = resolveOutputSourceMap(bundleAssetFilename)
100105
val compilerSourceMap = resolveCompilerSourceMap(bundleAssetFilename)

packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,16 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
122122
* used if the user is building Hermes from source.
123123
* 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
124124
* is substituted with the correct OS arch. This will be used if the user is using a precompiled
125-
* hermes-engine package.
125+
* hermes-engine package. Or, if the user has opted in to use Hermes V1, the used file will be
126+
* located in `node_modules/hermes-compiler/%OS-BIN%/hermesc` where `%OS-BIN%` is substituted
127+
* with the correct OS arch.
126128
* 4. Fails otherwise
127129
*/
128-
internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String): String {
129-
// 1. If the project specifies a Hermes command, don't second guess it.
130+
internal fun detectOSAwareHermesCommand(
131+
projectRoot: File,
132+
hermesCommand: String,
133+
hermesV1Enabled: Boolean = false,
134+
): String { // 1. If the project specifies a Hermes command, don't second guess it.
130135
if (hermesCommand.isNotBlank()) {
131136
val osSpecificHermesCommand =
132137
if ("%OS-BIN%" in hermesCommand) {
@@ -146,9 +151,12 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
146151
return builtHermesc.cliPath(projectRoot)
147152
}
148153

149-
// 3. If the react-native contains a pre-built hermesc, use it.
154+
// 3. If Hermes V1 is enabled, use hermes-compiler from npm, otherwise, if the
155+
// react-native contains a pre-built hermesc, use it.
156+
val hermesCPath = if (hermesV1Enabled) HERMES_COMPILER_NPM_DIR else HERMESC_IN_REACT_NATIVE_DIR
150157
val prebuiltHermesPath =
151-
HERMESC_IN_REACT_NATIVE_DIR.plus(getHermesCBin())
158+
hermesCPath
159+
.plus(getHermesCBin())
152160
.replace("%OS-BIN%", getHermesOSBin())
153161
// Execution on Windows fails with / as separator
154162
.replace('/', File.separatorChar)
@@ -233,6 +241,7 @@ internal fun readPackageJsonFile(
233241
return packageJson?.let { JsonUtils.fromPackageJson(it) }
234242
}
235243

244+
private const val HERMES_COMPILER_NPM_DIR = "node_modules/hermes-compiler/%OS-BIN%/"
236245
private const val HERMESC_IN_REACT_NATIVE_DIR = "node_modules/react-native/sdks/hermesc/%OS-BIN%/"
237246
private const val HERMESC_BUILT_FROM_SOURCE_DIR =
238247
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/"

packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ class PathUtilsTest {
162162
assertThat(detectOSAwareHermesCommand(tempFolder.root, "")).isEqualTo(expected.toString())
163163
}
164164

165+
@Test
166+
@WithOs(OS.MAC)
167+
fun detectOSAwareHermesCommand_withHermesV1Enabled() {
168+
tempFolder.newFolder("node_modules/hermes-compiler/osx-bin/")
169+
val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin//hermesc")
170+
171+
assertThat(detectOSAwareHermesCommand(tempFolder.root, "", hermesV1Enabled = true))
172+
.isEqualTo(expected.toString())
173+
}
174+
165175
@Test(expected = IllegalStateException::class)
166176
@WithOs(OS.MAC)
167177
fun detectOSAwareHermesCommand_failsIfNotFound() {

packages/react-native/sdks/hermes-engine/hermes-engine.podspec

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,21 @@ Pod::Spec.new do |spec|
6363
ss.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermesvm.framework"
6464
end
6565

66+
# When using the local prebuilt tarball, it should include hermesc compatible with the used VM.
67+
# In other cases, when using Hermes V1, the prebuilt versioned binaries can be used.
68+
# TODO: T236142916 hermesc should be consumed from NPM even when not using Hermes V1
69+
if source_type != HermesEngineSourceType::LOCAL_PREBUILT_TARBALL && ENV['RCT_HERMES_V1_ENABLED'] == "1"
70+
hermes_compiler_path = File.dirname(Pod::Executable.execute_command('node', ['-p',
71+
'require.resolve(
72+
"hermes-compiler",
73+
{paths: [process.argv[1]]}
74+
)', __dir__]).strip
75+
)
76+
77+
spec.user_target_xcconfig = {
78+
'HERMES_CLI_PATH' => "#{hermes_compiler_path}/osx-bin/hermesc"
79+
}
80+
end
6681

6782
# Right now, even reinstalling pods with the PRODUCTION flag turned on, does not change the version of hermes that is downloaded
6883
# To remove the PRODUCTION flag, we want to download the right version of hermes on the flight

0 commit comments

Comments
 (0)