Skip to content

perry/ui FFI symbols undefined on --target harmonyos (perry_ui_embed_nsview, others) — block on .so load #395

Description

@proggeramlug

Summary

Compiling a Perry app that imports embedNSView (or other perry/ui FFI helpers exported as extern fn) for --target harmonyos produces a libentry.so whose dynamic loader rejects the bundle at app launch:

Error relocating /data/storage/el1/bundle/libs/arm64/libentry.so: perry_ui_embed_nsview: symbol not found.
[ecmascript] export objects of native so is undefined, so name is @normalized:Y&&&libentry.so&
TypeError: Cannot read property run of undefined

Repro

Mango (~/projects/mango) at v1.1.29 imports @honeide/editor whose editor-component.ts calls embedNSView(hone_editor_nsview(handle)) to splice the editor's native view into the Perry widget tree. With Hone's new native/harmonyos/ no-op stub crate (PerryTS/hone#TBD, v0.2.1), the hone_editor_* symbols all resolve, but perry_ui_embed_nsview becomes the next undefined symbol and trips the loader.

cd ~/projects/mango
perry compile src/app.ts --target harmonyos -o /tmp/libentry.so
llvm-nm -D --undefined-only /tmp/libentry.so | grep "perry_ui_"
# →                  U perry_ui_embed_nsview
#   (and likely others if the user calls more perry/ui FFI in non-harvested code paths)

The .so builds cleanly; the error only surfaces at app launch on the device.

Why it happens

HarmonyOS goes through the perry-codegen-arkts harvest model — App({body: VStack([...])}) is destructively rewritten into ArkUI source so LLVM never sees perry_ui_* calls for the harvested widget tree. There is no perry-ui-harmonyos crate by design.

But embedNSView (and the other perry/ui extern declarations in user-facing code paths that aren't part of an App({body: ...}) literal) survive into the lowered .so because they're called from inside library code (e.g. Hone's createEditorPerryWidget()), not from the harvest target. Codegen-arkts can't see them, codegen-llvm doesn't strip them, and there's nothing on the HarmonyOS link line that defines them.

Other platforms each export the symbol from their UI crate:

  • crates/perry-ui-macos/src/lib.rs — real impl (widgets::register_external_nsview)
  • crates/perry-ui-android/src/lib.rs:1682 — Android stub
  • crates/perry-ui-gtk4/src/lib.rs:166 — GTK4 stub with debug log
  • crates/perry-ui-windows/src/lib.rs:1390 — Windows stub
  • crates/perry-ui-harmonyos/doesn't exist

Suggested fix

Two options:

Option A (minimum viable): add a no-op perry_ui_embed_nsview (+ any sibling perry_ui_* FFI that might leak through library code) to crates/perry-runtime/src/ui_text_registry.rs (already gated #[cfg(not(feature = "ohos-napi"))] for the cross-platform stubs that route to a NULL handler when no UI lib is linked — same pattern as v0.5.419's showToast/setText cross-platform sweep). Returns 0; Hone's embedNSView(hone_editor_nsview(0)) becomes a no-op chain that link-resolves and runs without crashing. The editor renders blank but the app boots.

Option B (proper): create crates/perry-ui-harmonyos as a parallel to perry-ui-android etc, exporting every perry_ui_* FFI that user library code might reference. Codegen-arkts continues to handle the harvest path; this crate handles the residue. Bigger refactor, follows the existing per-platform UI crate convention. Probably the right long-term direction.

To find the full list of perry_ui_* symbols that can leak: build a Mango-shaped corpus (any Perry app pulling in a third-party widget library) for --target harmonyos and run llvm-nm -D --undefined-only over the resulting .so.

Affected versions

Found on Perry v0.5.471 (HarmonyOS bringup landed in v0.5.399 / v0.5.418-v0.5.447, sequence of Phase 2 v1-v13). All HarmonyOS releases are affected; this gap was masked until Hone's HarmonyOS no-op stub crate landed and pushed the next undefined symbol into view.

Blocking

This is the next blocker after PerryTS/hone#TBD ("Hone editor on HarmonyOS no-op stub") — once perry/ui exports are present on HarmonyOS, Mango (and any Perry app embedding a Perry-widget-using third-party library) should at minimum boot to the auto-generated ArkUI Index.ets page on the emulator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions