diff --git a/crates/perry-ui-ios/src/widgets/securefield.rs b/crates/perry-ui-ios/src/widgets/securefield.rs index 6abcaa75d..9779f7a4b 100644 --- a/crates/perry-ui-ios/src/widgets/securefield.rs +++ b/crates/perry-ui-ios/src/widgets/securefield.rs @@ -100,7 +100,17 @@ pub fn create(placeholder_ptr: *const u8, on_change: f64) -> i64 { std::mem::forget(target); let view: Retained = Retained::cast_unchecked(text_field); - super::register_widget(view) + let handle = super::register_widget(view); + #[cfg(feature = "geisterhand")] + { + extern "C" { + fn perry_geisterhand_register(h: i64, wt: u8, ck: u8, cb: f64, lbl: *const u8); + } + unsafe { + perry_geisterhand_register(handle, 1, 1, on_change, placeholder_ptr); + } + } + handle } } diff --git a/crates/perry/src/commands/compile/library_search.rs b/crates/perry/src/commands/compile/library_search.rs index 9a260f00f..6e6125cc1 100644 --- a/crates/perry/src/commands/compile/library_search.rs +++ b/crates/perry/src/commands/compile/library_search.rs @@ -1197,7 +1197,17 @@ pub(super) fn build_geisterhand_libs(target: Option<&str>, format: OutputFormat) .arg("--features") .arg(format!("{}/geisterhand", ui_crate)) .arg("-p") - .arg("perry-ui-geisterhand"); + .arg("perry-ui-geisterhand") + // Build perry-stdlib in the same invocation so the geisterhand lib + // set is complete and its shared `perry-runtime` is hash-consistent + // with the runtime/ui libs above (a separate `cargo build -p + // perry-stdlib` would resolve `perry-runtime` without the geisterhand + // feature → a second runtime variant → undefined-symbol link errors). + // Without stdlib here, apps that pull native-FFI packages depending on + // perry-stdlib's async surface (`perry_ffi_promise_*`) had no + // consistent stdlib to link against under --enable-geisterhand (#1383). + .arg("-p") + .arg("perry-stdlib"); // Add cross-compilation target if needed if let Some(triple) = rust_target_triple(target) {