Skip to content

Link addons against a generated Hermes stub instead of weak-node-api #494

Open

Description

@kraenhansen

Let an addon link Node-API against a generated stub of Hermes instead of weak-node-api, so it records hermesvm and calls Hermes directly. This is what the RFC in #447 needs. Background and tradeoffs are in #493.

A stub is used at link time only and never ships, unlike weak-node-api, which is a shim with code that runs. Addons still compile against node-api-headers, which defines the interface, so only the link step is specific to React Native and building an addon doesn't require installing react-native.

Our host keeps providing the napi host here. Moving it into core is tracked in #495. Stub addons don't use the injected function table, so they can sit alongside weak-node-api addons with no host changes, and the shim can stay in the app.

Decisions

  • Option: --node-api-linkage <mode>, spelled the same on cmake-rn and ferric. It's named after what the build controls, which is what the addon links to. Names like "supplier" don't fit, because the facade in Prebuilt node-api facade for published addons #496 links node-api while Hermes supplies the symbols.
  • Modes: weak-node-api, hermes and none, leaving room for facade later. hermes describes what the addon links to, and the stub is how that gets built.
  • Default: weak-node-api, so existing builds don't change.
  • --no-weak-node-api-linkage: removed with no deprecated alias, as part of the major version on next. --node-api-linkage none replaces it.

Proposed

  • Add a CMake target with a neutral name. Addon CMakeLists.txt files name the weak-node-api target directly, so --node-api-linkage alone can't switch them. They would link the neutral target instead, and the mode decides what it points at.
  • Define the option once in packages/host/src/node/cli/options.ts, with its modes and .choices(), and export it through the host's node entry point for cmake-rn and ferric to use. That's how they already share SUPPORTED_TRIPLETS, and the host would need the modes too if prebuilds record their linkage.
  • hermes needs no React Native package option, because the stub carries the hermesvm name and doesn't need an install.
  • gyp-to-cmake's --weak-node-api chooses which target name goes into a generated CMakeLists.txt. With the neutral target it may no longer be needed, so it isn't part of this decision.

Open questions

Steps

  • Link one addon, such as async, against a stub of libhermesvm. Check that it records only hermesvm, then run the test app on iOS and Android and confirm its calls land in Hermes. The spike in How should addons get Node-API from the app's Hermes? #493 tested addon → facade → Hermes, not this direct link.
  • Generate the stub from getNodeApiFunctions(), with the library name as a parameter, and check it against the real Hermes.
  • Add --node-api-linkage to cmake-rn, replacing --no-weak-node-api-linkage. Addons move to the neutral CMake target. A hand-written CMake example may be enough for the RFC, in which case this can follow it.
  • Add --node-api-linkage to ferric, and follow up in gyp-to-cmake.

Limits

Metadata

Metadata

Assignees

Labels

CMake RNOur `cmake` wrapping CLILinking 🔗Discovering and copying prebuilds from packages into the hostenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions