Repository navigation
Link addons against a generated Hermes stub via --node-api-linkage - #501
kraenhansen wants to merge 3 commits into
Conversation
Generate a link-time stub of libhermesvm from getNodeApiFunctions() and build it alongside weak-node-api. Add `--node-api-linkage <weak-node-api|hermes|none>` to cmake-rn (defined once in the host), replacing `--no-weak-node-api-linkage`, and a neutral `node-api-linkage` CMake target that follows the selected mode. The async test addon now links the neutral target and node-addon-examples builds with `--node-api-linkage hermes`, so the iOS and Android test app jobs exercise an addon calling Hermes directly, and verify its linkage and imports against the app's real Hermes. Refs #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U2xSE4PR7T7WFxexRhihBT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U2xSE4PR7T7WFxexRhihBT
|
Three changes needed here. Please fix the failing jobs first, because they're the proof that this works. 1.
|
- Add a `node-api-stub` package holding `getNodeApiFunctions()`, `generateFunction` and the stub generator with its CMake project. weak-node-api's generator and the host's injector generator now read the function list from it, and weak-node-api no longer builds a stub. - In `hermes` mode, cmake-rn adds the stub to the addon's own build (and leaves it out of the prebuilds), so the addon doesn't need weak-node-api to be built. - Rename the CMake target to `node-api` (`node-api-config.cmake`). - Remove `tests/async/binding.gyp`, which made gyp-to-cmake overwrite the hand-written CMakeLists.txt with one linking weak-node-api. - Port verify-hermes-linkage to TypeScript, comparing the real Hermes against node-api-headers' symbol list instead of a stub binary. Refs #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U2xSE4PR7T7WFxexRhihBT
A first pass at #494: an addon can link Node-API against a generated stub of
libhermesvminstead ofweak-node-api. It then recordshermesvmand calls Hermes directly. The existing iOS and Android test-app jobs check this end to end.What's in here
node-api-stubpackage:src/node-api-functions.ts(getNodeApiFunctions(),nodeApiHeaders) andgenerateFunction, both moved fromweak-node-api.scripts/generate-stub.ts, which generatesgenerated/node_api_stub.cpp. Every function body isabort(), and there's noWEAK_NODE_API_UNREACHABLE.CMakeLists.txtdefining thenode-api-stubtarget, excluded fromall. The library name comes fromNODE_API_STUB_LIBRARY_NAME(defaulthermesvm), and the headers come fromNODE_API_INC.node-api-headersandzod, not onreact-native-node-apiorcmake-rn, so it stays out of the existing dev-dependency loop betweencmake-rnandweak-node-api.weak-node-api: its generator, and the host'sgenerate-injector.mts, now get the function list fromnode-api-stub.weak-node-apino longer builds a stub. It no longer exportsgetNodeApiFunctions, and itsnode-api-headersdependency moved tonode-api-stub. The weak-node-api source it generates is byte-identical to before.--node-api-linkage <weak-node-api|hermes|none>:packages/host/src/node/cli/options.tsand used bycmake-rn. It replaces--no-weak-node-api-linkage, with no alias.cmake-rndepends onnode-api-stubdirectly.node-apiCMake target (cmake-rn/cmake/node-api-config.cmake, loaded withfind_package(node-api REQUIRED CONFIG)):weak-node-apimode it's the importedweak-node-apilibrary.hermesmode, the config addsnode-api-stubto the addon's own build, once per build, andnode-apilinks it.cmake-rnleaves the stub target out of the prebuilds. Ahermesaddon doesn't needweak-node-apito be built.hermesmode theweak-node-apitarget is still defined whenever its prebuild exists, so addons that name it directly build alongside. node-addon-examples relies on this.tests/async/binding.gypis removed.gyp-to-cmakewas regeneratingtests/async/CMakeLists.txtfrom it withweak-node-api, which is why the first run failed. The hand-writtenCMakeLists.txtnow linksnode-api.--node-api-linkage hermes.scripts/verify-hermes-linkage.mts(TypeScript, run withnode --run verify:hermes-linkage). It checks that the async prebuild depends onhermesvmand not onweak-node-api. It fails if the real Hermes shipped in the built app is missing anynapi_*the addon imports. It warns about Node-API functions in the stub (taken fromnode-api-headers' v10 list) that the real Hermes doesn't export.Local verification (Linux)
find_package(node-api), through the new config inhermesmode. The stub is built once, and both addons' onlyNEEDEDentries arelibhermesvm.soand libc.verify-hermes-linkage.mtspasses on that build and fails on the negative cases (an addon that doesn't linkhermesvm, and a library missing the imported symbols).tsc --build, thecmake-rntests,prettier:check,depcheck, andpublintonnode-api-stubandcmake-rnall pass.pnpm install --frozen-lockfileaccepts the lockfile.verify-prebuilds.mtscouldn't be type-checked locally.Open questions / not done yet
ferricand thegyp-to-cmakefollow-up (step 4 in the issue): not done.cmake-rn initstill scaffoldsweak-node-api.Versions/A). I haven't checked it against the real macOShermesvm, and test-macos is disabled anyway.napi_fatal_error, not the host's override (refactor(host): drop the shadowing napi_fatal_error #492).Refs #494
🤖 Generated with Claude Code
https://claude.ai/code/session_01U2xSE4PR7T7WFxexRhihBT