-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Neon Rust bindings support #193
Comments
Did some digging, tl;dr is it builds but crashes without error when trying to run. Prerequisites
Findingsneon projects don't have a
ErrorsRequiring the Trying to build the apk with |
So I realized that I can check the Android Studio Logcat and there's actually an error:
stacktraceat Object.Module._extensions..node (internal/modules/cjs/loader.js:717:18) at Module.load (internal/modules/cjs/loader.js:598:32) at tryModuleLoad (internal/modules/cjs/loader.js:537:12) at Function.Module._load (internal/modules/cjs/loader.js:529:3) at Module.require (internal/modules/cjs/loader.js:636:17) at require (internal/modules/cjs/helpers.js:20:18) at Object. (/data/data/com.neontest/files/nodejs-project/node_modules/neon-test/lib/index.js:1:75) at Module._compile (internal/modules/cjs/loader.js:688:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10) at Module.load (internal/modules/cjs/loader.js:598:32) 11909-11914/com.neontest A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x5d8 in tid 11914 (Jit thread pool), pid 11909 (com.neontest)To actually get neon to build successfully, it's needed to set some rust cargo build environment variables and have the neon-cli respect the
(I've pushed the neon change to a fork, so it's possible to add Also, rust needs the targets installed, on linux these are:
|
There's also the matter of having to link the final binary with nodejs-mobile for it to load successfully at runtime (this might be why the It's working now, then? |
Thanks for the hint. I've tried to let neon use the |
Here's the output from nodejs-mobile-gyp configure and build (run by neon-runtime): gyp configure
gyp build
It says |
Hi @stoically , The resulting binary files need to be linked to the nodejs-mobile shared library : https://github.com/janeasystems/nodejs-mobile/blob/2101f2096d59d2a081f64da2f10fd7385222ac8a/common.gypi#L517-L538 One way of debugging this would be to verify if the resulting ELF binary (the
This gives the following output:
The line for |
The
But that binary is not used. The neon-runtime proceeds to compile a And the resulting
So my best guess at the moment is that it's needed to let the neon-runtime Cargo.toml point to the nodejs-mobile lib files in its link section. |
Linking the
in the Now
So my next best guess was that
I'm not sure what exactly needs to compiled with |
Hi @stoically , The error here is Node Modules register themselves by declaring themselves through Here's an example of such a function being declared: Some build systems might not include these symbols when building something from a static library, since these symbols were not referenced anywhere in the code that's using the static library. You mentioned the module is first built as a static library and then into a shared library, so it's possible there's some issues there. There's also some changes to nodejs-mobile headers that might be related to this, in order to properly build the nodejs-mobile library for iOS (builds into a static library that is used by a There might be some way to use the NDK's I hope this is helpful :) |
Hey @jaimecbernardo - thanks again for another, indeed helpful, hint! Checked the registered constructors in the final shared library with
which is the responsible code for calling The |
Hi @stoically , I'm not familiar enough with Rust's toolset to understand what could be going on, but my first step would be comparing the commands being run when compiling to run in the Desktop, if the symbols are being correctly exported to the final |
Forgot to add that you need to also add in the android/iOS target here like so:
https://github.com/neon-bindings/neon/blob/37191e316e12bdbd8f84d3cd42739263d3312455/src/lib.rs#L87 |
@cgdusek Cool stuff, thanks! I guess we can close this issue then. Would you be interested in opening an PR against Neon with those changes? |
I've been following this thread closely, and the tips you've put @stoically @cgdusek @jaimecbernardo have been very helpful. I managed to get my Neon-built npm package working with nodejs-mobile, and for reference I'll list here the right configurations and changes that made it possible: These changes to the ──────────────────────────────────────────────────────────────────────────────────────────────────────────
modified: cli/src/build-settings.ts
──────────────────────────────────────────────────────────────────────────────────────────────────────────
@ cli/src/build-settings.ts:60 @ export default class BuildSettings {
npm_config_disturl: process.env.npm_config_disturl || null,
npm_config_runtime: process.env.npm_config_runtime || null,
npm_config_build_from_source: process.env.npm_config_build_from_source || null,
- npm_config_devdir: process.env.npm_config_devdir || null
+ npm_config_devdir: process.env.npm_config_devdir || null,
+ npm_config_node_engine: process.env.npm_config_node_engine || null,
+ npm_config_nodedir: process.env.npm_config_nodedir || null,
+ npm_config_node_gyp: process.env.npm_config_node_gyp || null,
+ npm_config_platform: process.env.npm_config_platform || null
});
}
──────────────────────────────────────────────────────────────────────────────────────────────────────────
modified: crates/neon-sys/build.rs
──────────────────────────────────────────────────────────────────────────────────────────────────────────
@ crates/neon-sys/build.rs:97 @ mod build {
//
// gyp verb architecture ia32
fn parse_node_arch(node_gyp_output: &str) -> String {
- let version_regex = Regex::new(r"gyp verb architecture (?P<arch>ia32|x64)").unwrap();
+ let version_regex = Regex::new(r"gyp verb architecture (?P<arch>ia32|x64|arm|arm64)").unwrap();
let captures = version_regex.captures(&node_gyp_output).unwrap();
String::from(&captures["arch"])
}
──────────────────────────────────────────────────────────────────────────────────────────────────────────
modified: src/lib.rs
──────────────────────────────────────────────────────────────────────────────────────────────────────────
@ src/lib.rs:108 @ macro_rules! register_module {
// Mark this function as a global constructor (like C++).
#[allow(improper_ctypes)]
#[cfg_attr(target_os = "linux", link_section = ".ctors")]
+ #[cfg_attr(target_os = "android", link_section = ".ctors")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
#[used] These rustup targets need to be installed:
The Cargo.toml of the Neon-built npm package needs this: diff --git a/node_modules/ssb-neon-keys/native/Cargo.toml b/node_modules/ssb-neon-keys/native/Cargo.toml
index 4e72059..6fc3dbb 100644
--- a/node_modules/ssb-neon-keys/native/Cargo.toml
+++ b/node_modules/ssb-neon-keys/native/Cargo.toml
@@ -4,6 +4,7 @@ version = "8.0.0"
authors = ["Andre Staltz <[email protected]>"]
license = "AGPL-3.0"
build = "build.rs"
+links = "node"
exclude = ["artifacts.json", "index.node"]
edition = "2018" The Neon-built npm package needs this additional config file (it uses absolute paths, so this file should be created locally via a script):
The project compiled correctly and ran successfully in runtime. Only on Android. I'm still trying to figure out iOS and would I appreciate a lot if anyone has made progress on iOS. |
I just figured out iOS support! Compiled and tested on an iPad. You should assume that the following changes build on top of my previous comment, I can't guarantee that this will work if you don't apply the changes from the previous comment. These changes to the ──────────────────────────────────────────────────────────────────────────────────────────────────────────
modified: src/lib.rs
──────────────────────────────────────────────────────────────────────────────────────────────────────────
@ src/lib.rs:108 @ macro_rules! register_module {
// Mark this function as a global constructor (like C++).
#[allow(improper_ctypes)]
#[cfg_attr(target_os = "linux", link_section = ".ctors")]
#[cfg_attr(target_os = "android", link_section = ".ctors")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
+ #[cfg_attr(target_os = "ios", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
#[used] These rustup targets need to be installed:
nodejs-mobile-react-native/scripts/ios-build-native-modules.sh needs these changes to add pushd $CODESIGNING_FOLDER_PATH/nodejs-project/
if [ "$PLATFORM_NAME" == "iphoneos" ]
then
- GYP_DEFINES="OS=ios" npm_config_nodedir="$NODEJS_HEADERS_DIR" npm_config_node_gyp="$NODEJS_MOBILE_GYP_BIN_FILE" npm_config_platform="ios" npm_config_format="make-ios" npm_config_node_engine="chakracore" npm_config_arch="arm64" npm --verbose rebuild --build-from-source
+ GYP_DEFINES="OS=ios" CARGO_BUILD_TARGET="aarch64-apple-ios" npm_config_nodedir="$NODEJS_HEADERS_DIR" npm_config_node_gyp="$NODEJS_MOBILE_GYP_BIN_FILE" npm_config_platform="ios" npm_config_format="make-ios" npm_config_node_engine="chakracore" npm_config_arch="arm64" npm --verbose rebuild --build-from-source
else
- GYP_DEFINES="OS=ios" npm_config_nodedir="$NODEJS_HEADERS_DIR" npm_config_node_gyp="$NODEJS_MOBILE_GYP_BIN_FILE" npm_config_platform="ios" npm_config_format="make-ios" npm_config_node_engine="chakracore" npm_config_arch="x64" npm --verbose rebuild --build-from-source
+ GYP_DEFINES="OS=ios" CARGO_BUILD_TARGET="x86_64-apple-ios" npm_config_nodedir="$NODEJS_HEADERS_DIR" npm_config_node_gyp="$NODEJS_MOBILE_GYP_BIN_FILE" npm_config_platform="ios" npm_config_format="make-ios" npm_config_node_engine="chakracore" npm_config_arch="x64" npm --verbose rebuild --build-from-source
fi
popd Finally, the {
"name": "my-neon-package",
...
"scripts": {
+ "postinstall": "mv native/index.node native/index && mkdir native/index.node && mv native/index native/index.node/index"
}
} |
neon compiles Rust code to native nodejs modules and provides bindings to work with those native modules. Would be awesome if nodejs-mobile could support neon compiled native modules.
Notes
"Related" issues over at neon:
Also, maybe it's already possible by manually building #173 the neon module and providing it to nodejs-mobile? I've just naively tried to copy over my neon-build module into the nodejs-mobile node_modules folder, but that makes
react-native run-android
fail with':app:packageDebug'. > org.gradle.tooling.BuildException (no error message)
.The text was updated successfully, but these errors were encountered: