Skip to content

fix(hermes): enable HermesV1 (hermesvm.xcframework) resolution#3011

Open
Saadnajmi wants to merge 7 commits into
microsoft:0.83-mergefrom
Saadnajmi:hermes-v1-enable
Open

fix(hermes): enable HermesV1 (hermesvm.xcframework) resolution#3011
Saadnajmi wants to merge 7 commits into
microsoft:0.83-mergefrom
Saadnajmi:hermes-v1-enable

Conversation

@Saadnajmi

Copy link
Copy Markdown
Collaborator

Summary

Enables HermesV1 (hermesvm.xcframework) resolution on 0.83-merge by aligning both the producer (Resolve Hermes CI) and consumer (podspec / Ruby / SPM) sides with the V1 engine.

Consolidates the Hermes-V1 enablement work previously split across #2952 (JS/CI side) and #2957 (Ruby side, by @tvinhas), cleanly re-based onto the current 0.83-merge now that #3007 has landed.

Changes

  • microsoft-hermes.jshermesCommitAtMergeBase() clones/inspects Hermes static_h instead of main; added hermesV1Tag() reading sdks/.hermesv1version.
  • resolve-hermes.mts — recompose now operates on hermesvm.xcframework / hermesvm.framework throughout.
  • microsoft-resolve-hermes.yml — cache keys bumped hermes-v1-…hermesv1-engine-… so stale V0-shaped caches aren't reused as V1 artifacts.
  • Package.swift — define HERMES_V1_ENABLED so V1-aware guards take effect.
  • build-apple-framework.sh — pass CMAKE_BUILD_TYPE for host hermesc + tolerate missing legacy inspector headers under HermesV1.
  • hermes-utils.rb (by @tvinhas, from fix(hermes): pick static_h vs main branch by RCT_HERMES_V1_ENABLED in hermes-utils.rb #2957) — pick static_h vs main by RCT_HERMES_V1_ENABLED on the from-source consumer path.

Supersedes

Test plan

  • CI: Resolve Hermes produces hermesvm.xcframework (tarball fast-path or from-source static_h fallback).
  • CI: downstream Build <platform> jobs find hermesvm.xcframework.

@Saadnajmi Saadnajmi requested a review from a team as a code owner July 7, 2026 10:04
Comment on lines +130 to +131
cmake -S . -B build_host_hermesc -DJSI_DIR="$JSI_PATH" -DCMAKE_BUILD_TYPE=Release
cmake --build ./build_host_hermesc --target hermesc -j "$(sysctl -n hw.ncpu)"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check with Facebook's yaml

Comment thread packages/react-native/Package.swift Outdated
Comment on lines +948 to +952
// [macOS] The SPM build links against hermesvm.xcframework (HermesV1).
// Several headers (e.g. ReactCommon/hermes/inspector-modern/chrome/Registration.h)
// gate legacy inspector code on `!defined(HERMES_V1_ENABLED)`, matching what the
// CocoaPods path sets via cocoapods/utils.rb when RCT_HERMES_V1_ENABLED=1.
.define("HERMES_V1_ENABLED", to: "1"),

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem macOS specific

Saadnajmi and others added 5 commits July 7, 2026 14:17
Package.swift and ios-prebuild/hermes.js already reference hermesvm.xcframework
(the HermesV1 product introduced in RN 0.83), but the Resolve Hermes job still
recomposed hermes.xcframework and resolved Hermes commits on the legacy `main`
branch. With the upstream build scripts now unconditionally producing hermesvm,
this left the SPM build path internally inconsistent.

- microsoft-hermes.js: resolve commits on Hermes `static_h` branch; add
  `hermesV1Tag()` helper that reads sdks/.hermesv1version
- resolve-hermes.mts: recompose hermesvm.xcframework / hermesvm.framework
- microsoft-resolve-hermes.yml: bump cache key (hermes-v1- -> hermesv1-engine-)
  so stale V0-shaped caches aren't reused as V1 artifacts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HermesV1's static_h CMakeLists requires CMAKE_BUILD_TYPE to be set; the
upstream `build_host_hermesc` helper in build-apple-framework.sh doesn't
pass it, so the from-source fallback in Resolve Hermes failed at the
hermesc step with "Please set CMAKE_BUILD_TYPE". Invoke cmake directly
from the workflow with -DCMAKE_BUILD_TYPE=Release (the host compiler is
always built Release for perf, matching configure_apple_framework's
behavior in Debug builds of the apple frameworks).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HermesV1 (static_h) replaces the legacy API/hermes/inspector/ headers with
API/hermes/cdp/, so the unconditional cp commands in build_apple_framework
and prepare_dest_root_for_ci fail with 'No such file or directory' when
building from V1 sources. Guard each copy with compgen so the copy is
skipped cleanly when the source directory is empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Package.swift links against hermesvm.xcframework (HermesV1) but never
defines HERMES_V1_ENABLED, so headers like
ReactCommon/hermes/inspector-modern/chrome/Registration.h still try to
#include <hermes/inspector/RuntimeAdapter.h> — a legacy header V1 dropped.
Set HERMES_V1_ENABLED=1 in the shared cxxSettings (alongside USE_HERMES);
this matches what cocoapods/utils.rb does when RCT_HERMES_V1_ENABLED=1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Saadnajmi and others added 2 commits July 8, 2026 14:14
… 0.84

Upstream 0.83-stable defaults to Hermes V0 (sdks/.hermesversion =
hermes-v0.14.1); V1 is opt-in via RCT_HERMES_V1_ENABLED and only becomes
the default in 0.84 (react#54989, commit bbe02de, not
backported to 0.83). The `hermes` -> `hermesvm` product rename, however,
already landed in 0.83 (react#53094), so the fork's
resolve-hermes.mts genuinely needed to catch up to the new artifact name.

Reduce the PR to just that V0-compatible rename catch-up and revert the
V1-engine bits to match upstream 0.83:

- resolve-hermes.mts: keep hermes.* -> hermesvm.* (needed on 0.83).
- Package.swift: drop HERMES_V1_ENABLED define (inherited at 0.84 merge).
- microsoft-hermes.js: revert static_h -> main; drop unused hermesV1Tag().
- hermes-utils.rb: revert static_h/main gate back to main (V0).
- build-apple-framework.sh: revert inspector-header guard (V0 ships them).
- microsoft-resolve-hermes.yml: revert cache-key rename + cmake hermesc
  change (build_host_hermesc works for V0).

Net: 6 files -> 1; the five reverted files now match upstream/0.83-merge.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… coordinate

resolve-hermes.mts queried com/facebook/react/react-native-artifacts/<rn-version>
for the Hermes tarball, but upstream publishes prebuilt Hermes under
com/facebook/hermes/hermes-ios/<HERMES_VERSION> (keyed by the Hermes version,
not the react-native version). That coordinate has no Hermes classifier, so the
download always 404'd and every 0.83 Resolve Hermes run fell back to an
expensive from-source build.

Point the download at upstream's real coordinate and read the Hermes version
from sdks/hermes-engine/version.properties, mirroring the CocoaPods
release_tarball_url: HERMES_VERSION_NAME by default (RN 0.83 ships V0 0.14.0),
or HERMES_V1_VERSION_NAME when RCT_HERMES_V1_ENABLED=1. The existing recompose
step then merges the standalone macOS slice into the universal xcframework.

Verified locally end-to-end:
- download-hermes Debug -> hermes-ios/0.14.0 (200), recompose -> hermesvm.xcframework
  with 8 slices incl. macos-arm64_x86_64 (recomposed=true)
- RCT_HERMES_V1_ENABLED=1 -> hermes-ios/250829098.0.2 (200)
- V0/V1 x debug/release URLs all resolve 200 on repo1.maven.org

Result: 0.83 downloads upstream's prebuilt Hermes (on par with RN 0.83's default
V0 engine) and no longer builds Hermes from source, so the from-source V1
machinery is unnecessary on 0.83.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants