JaneaSystems / nodejs-mobile

Full-fledged Node.js on Android and iOS
https://code.janeasystems.com/nodejs-mobile
Other
2.58k stars 182 forks source link

native modules #4

Open lukaskollmer opened 7 years ago

lukaskollmer commented 7 years ago

In your announcement blog post you write

JavaScript code can also make direct synchronous calls into native code (Java, Objective C, Swift) and get calls back from it, by means of Node’s native add-on APIs (the V8 API and N-API are both available).

How does this work exactly? I'm trying to use the ffi on iOS. I ship my own node_modules folder, which I add to process.env.NODE_PATH at runtime.

The issue is that node-gyp simply didn't build the native modules for arm64 in the first place.

const ffi = require('ffi');

throws the following error:

dlopen(PATH_TO_APP/Frameworks/NodeJSKit.framework/node_modules/ref/build/Release/binding.node, 1): no suitable image found.  Did find:
    PATH_TO_APP/Frameworks/NodeJSKit.framework/node_modules/ref/build/Release/binding.node: mach-o, but wrong architecture
    PATH_TO_APP/Frameworks/NodeJSKit.framework/node_modules/ref/build/Release/binding.node: mach-o, but wrong architecture

Is it possible to build native node addons written in c++ (that use the v8 api or the newer N-API) to work with nodejs-mobile?

jaimecbernardo commented 7 years ago

Hi @lukaskollmer, thanks for opening the issue.

We've been successful in adding a native Node.js module using NAPI by embedding it in our React-Native and Cordova plugins and it is able to call into C++/Java code. Our technique is registering it as a builtin module and embedding it in the application.

You can check the current version in the React Native plugin repo, for instance. C++ part is here. JS part is here.

With some changes, native modules can be compiled/linked with the application and seen as builtin modules.

We are still designing our solution for using native npm modules on iOS, hopefully it won't take long.

In your specific case, the ffi module seems to expect to be able to load dynamic libraries at runtime as well, so further adaptations will probably have to be made to have it loading native libraries on iOS.

I hope that helped.

lukaskollmer commented 7 years ago

Does this approach only work with the napi, or could I also register modules written using the v8 apis as a builtin module?

jaimecbernardo commented 7 years ago

Hi @lukaskollmer,

You are able to register modules written with the V8 apis as a builtin module, as well, with some caveats:

One of the N-API goals is to provide a stable API despite of version and engine, so we chose to use it for our native bridge.

You do have to use another macro, provided in node.h, to register the native module, which is used for Node's native modules: https://github.com/janeasystems/nodejs-mobile/blob/c1c346086edb48d72ee255a3946c0959ef117d1a/src/node.h#L529-L530

You can also use NODE_MODULE_X with the NM_F_BUILTIN flag, if the module is not context aware: https://github.com/janeasystems/nodejs-mobile/blob/c1c346086edb48d72ee255a3946c0959ef117d1a/src/node.h#L485

https://github.com/janeasystems/nodejs-mobile/blob/c1c346086edb48d72ee255a3946c0959ef117d1a/src/node.h#L440

oleksandr-yefremov commented 7 years ago

Hi @jaimecbernardo! I am trying to understand how to connect the dots between the runtimes. Do I understand it right, that:

  1. communicating between Node.js and Native code (Java/Objc, not C++) is only possible via React Native (ReactBridge is doing that);
  2. communicating between Node.js and C++ is possible without React Native;

Thanks!

jaimecbernardo commented 7 years ago

Hi, @oleksandr-yefremov Thanks for the question.

A way of looking into how the current React-Native bridge acts is like this:

Regarding the questions:

  1. Communicating from Node.js to Native (Java/ObjC++) is possible if you extend the bridge to do that, but it's not implemented in the current version.
  2. It's possible to do a native add-on in C++ and include it in your app, that's the basis for the React-Native bridge we're using. It is being built with the application and registered as a native module.

I hope this was helpful.

oleksandr-yefremov commented 7 years ago

Thanks for detailed answer! I was just exploring the options to run non-UI JS code which would communicate to Native code without React Native and it seems like I should further look into option 1 ("…is possible if you extend the bridge to do that, but it's not implemented in the current version."). If I got it right, I'd need to extend C++(bridge) of Node.js to do at least the type conversion between JS and Native, plus some other stuff.

jaimecbernardo commented 7 years ago

Strings are already there, used in the bridge.

Strings are sent to and received from Node through the Node Runner modules. iOS: https://github.com/janeasystems/nodejs-mobile-react-native/blob/bbf5c46566ab3b1789bfe633453f9d792f51f858/ios/NodeRunner.mm#L47-L58 Android: https://github.com/janeasystems/nodejs-mobile-react-native/blob/bbf5c46566ab3b1789bfe633453f9d792f51f858/android/src/main/java/com/janeasystems/rn_nodejs_mobile/RNNodeJsMobileModule.java#L121-L124 and https://github.com/janeasystems/nodejs-mobile-react-native/blob/bbf5c46566ab3b1789bfe633453f9d792f51f858/android/src/main/java/com/janeasystems/rn_nodejs_mobile/RNNodeJsMobileModule.java#L133-L147

carrotalan commented 6 years ago

Apologies for the simple nature of my question. But I have not yet had much experience compiling my own native modules (beyond just using npm install!).

In basic terms, how do I get a native node module - like leveldown to work with nodejs mobile?

jaimecbernardo commented 6 years ago

Hi @carrotalan, Thanks for your question.

We are currently working on a solution to bring support to native modules from npm to nodejs-mobile. Until then, it depends on what your scenario is and it has different processes according to platform. I'd like to invite you to join our gitter channel, where it's probably a better format to talk about specifics for your case: https://gitter.im/nodejs-mobile/community

bil-ash commented 6 years ago

Now that native node modules can be built on linux & mac osx, do you have any plans for bringing support of building android native node modules on windows? Or at least on bash on ubuntu on windows(that might actually be even more difficult than windows)?

jaimecbernardo commented 6 years ago

Hi @bil-ash , Thank you for the question.

We'd love to bring support for building android native modules on Windows, eventually, but we still need to evaluate the effort required.

It could be that it may work in the "Windows Subsystem for Linux" already. If you're able to install and run the android SDK and build-tools for building Android applications in WSL, it may be possible to build the native modules there already.

If you decide to give it a try, please let us know of any results.

bil-ash commented 6 years ago

Thanks for the clarification. I shall try building on windows subsystem for linux, but may be after a few weeks.

jaimecbernardo commented 6 years ago

We've recently added support for native modules in the cordova and react-native plugins latest update but we still need to validate that it will pass App Store review and we might need to make some tweaks in order to get there.

If anyone has the opportunity to submit an app for review that uses native modules, that would definitely help us expedite the process and would be greatly appreciated. If you are able to help, please get in touch. We are going to work with you at high priority to address any possible issues that arise from the review. Please note that currently the support for native modules is off by default and needs to be switched on.

Instructions on how to turn it on can be found on the commits right before the automatic detection was turned off. Here for Cordova: https://github.com/janeasystems/nodejs-mobile-cordova/tree/c4cd7ec65cf68d3224ae9ddcb3246e988b1cbbc2#native-modules And here for React Native: https://github.com/janeasystems/nodejs-mobile-react-native/tree/99f3400895d0b8626dbea37f8382f13e6aeb7ebb#native-modules

Thank you!

bil-ash commented 6 years ago

@jaimecbernardo Cordova plugin I tried using Windows Subsystem for Linux to build android app containing native modules. Result- 1)When no native module is used,the build process works fine on WSL and apk is generated. 2)If a native module is used,the arm toolchain is generated and then the build process fails. I have tried using two different installation of node-one with the method described in the official site and the other using node installed by nvm. Both lead to failed builds. At first I tried using grpc as native module,after build failure,I uninstalled grpc and used a-native-example native module and again got a failed build. Here is the terminal output-

$ cordova build
ANDROID_HOME=/mnt/d/z/sw/sdk
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
Subproject Path: CordovaLib
Starting a Gradle Daemon, 1 incompatible and 3 stopped Daemons could not be reused, use --status for details
The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
        at build_3sb27rni6qytflww6qguzlw7.run(/mnt/d/z/pp/n2/platforms/android/build.gradle:142)
The JavaCompile.setDependencyCacheDir() method has been deprecated and is scheduled to be removed in Gradle 4.0.
Incremental java compilation is an incubating feature.
The TaskInputs.source(Object) method has been deprecated and is scheduled to be removed in Gradle 4.0. Please use TaskInputs.file(Object).skipWhenEmpty() instead.
:CopyNodeProjectAssetsarmeabi-v7a
:MakeToolchainarmeabi-v7a UP-TO-DATE
:BuildNpmModulesarmeabi-v7anpm info it worked if it ends with ok
npm verb cli [ '/home/uw/.nvm/versions/node/v8.10.0/bin/node',
npm verb cli   '/home/uw/.nvm/versions/node/v8.10.0/bin/npm',
npm verb cli   '--verbose',
npm verb cli   'rebuild',
npm verb cli   '--build-from-source' ]
npm info using npm@5.6.0
npm info using node@v8.10.0
npm info readInstalled object
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project',
npm verb rebuild   'nodejs-mobile-sample-project@0.1.0' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example',
npm verb rebuild   'a-native-example@0.0.1' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/nan',
npm verb rebuild   'nan@2.10.0' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/node-gyp-build',
npm verb rebuild   'node-gyp-build@3.3.0' ]
npm info build /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
npm info lifecycle a-native-example@0.0.1~preinstall: a-native-example@0.0.1
npm info linkStuff a-native-example@0.0.1
npm verb linkBins a-native-example@0.0.1
npm verb linkBins [ { 'tmp-release': './release.js' },
npm verb linkBins   '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/.bin',
npm verb linkBins   false ]
npm verb linkMans a-native-example@0.0.1
npm info lifecycle a-native-example@0.0.1~install: a-native-example@0.0.1

> a-native-example@0.0.1 install /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
> node-gyp-build

/home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin/node-gyp: 5: /home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin/node-gyp: /mnt/d/z/pp/n2/platforms/android/../../plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/bin/node-gyp.js: not found
npm verb lifecycle a-native-example@0.0.1~install: unsafe-perm in lifecycle true
npm verb lifecycle a-native-example@0.0.1~install: PATH: /home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/node_modules/.bin:/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/.bin:/home/uw/bin:/home/uw/.local/bin:/home/uw/.nvm/versions/node/v8.10.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/ProgramData/Oracle/Java/javapath_target_1714010640:/mnt/g/programs/Python35/Scripts:/mnt/g/programs/Python35:/mnt/c/Program Files (x86)/Intel/iCLS Client:/mnt/c/Program Files/Intel/iCLS Client:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/Program Files (x86)/MySQL/MySQL Server 5.1/bin:/mnt/c/ProgramData/chocolatey/bin:/mnt/g/programs/Emscripten:/mnt/g/programs/Emscripten/emscripten/1.35.0:/mnt/c/Program Files/gnuplot/bin:/mnt/c/Program Files/nodejs:/mnt/g/roidSdk/platform-tools:/mnt/g/roidSdk/tools:/mnt/c/Program Files/Inno Setup 5:/mnt/g/programs/Java/jdk1.8.0_112/bin:/mnt/c/Users/bil-ash/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/bil-ash/.gradle/wrapper/dists/gradle-2.4-all/6r4uqcc6ovnq6ac6s0txzcpc0/gradle-2.4/bin:/mnt/c/Users/bil-ash/AppData/Local/GitHub/PortableGit_25d850739bc178b2eb13c3e2a9faafea2f9143c0/cmd:/mnt/c/Users/bil-ash/AppData/Local/GitHubDesktop/bin:/mnt/g/programs/OpenSSL-Win32/bin:/mnt/c/Users/bil-ash/AppData/Roaming/npm:/mnt/c/Users/bil-ash/AppData/Local/Microsoft/WindowsApps:/snap/bin:/mnt/d/z/sw/sdk/tools:/mnt/d/z/sw/sdk/platform-tools:/mnt/d/z/sw/sdk/tools/bin
npm verb lifecycle a-native-example@0.0.1~install: CWD: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
npm info lifecycle a-native-example@0.0.1~install: Failed to exec install script
npm verb stack Error: a-native-example@0.0.1 install: `node-gyp-build`
npm verb stack spawn ENOENT
npm verb stack     at ChildProcess.<anonymous> (/home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:48:18)
npm verb stack     at emitTwo (events.js:126:13)
npm verb stack     at ChildProcess.emit (events.js:214:7)
npm verb stack     at maybeClose (internal/child_process.js:925:16)
npm verb stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
npm verb pkgid a-native-example@0.0.1
npm verb cwd /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project
npm verb Linux 4.4.0-43-Microsoft
npm verb argv "/home/uw/.nvm/versions/node/v8.10.0/bin/node" "/home/uw/.nvm/versions/node/v8.10.0/bin/npm" "--verbose" "rebuild" "--build-from-source"
npm verb node v8.10.0
npm verb npm  v5.6.0
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! a-native-example@0.0.1 install: `node-gyp-build`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the a-native-example@0.0.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm verb exit [ 1, true ]

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/uw/.npm/_logs/2018-03-25T12_23_27_165Z-debug.log
:BuildNpmModulesarmeabi-v7a FAILED

FAILURE: Build failed with an exception.

* What went wrong:

Execution failed for task ':BuildNpmModulesarmeabi-v7a'.
> Process 'command 'npm'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED

Total time: 51.88 secs

What should I do to solve the problem?

jaimecbernardo commented 6 years ago

Hi @bil-ash , Thank you for giving it a try.

In this case, it seems like /mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/bin/node-gyp.js doesn't exist. It's possible that npm installed nodejs-mobile-gyp in /mnt/d/z/pp/n2/node_modules/nodejs-mobile-gyp/ instead.

In the future, we will fix this by looking for nodejs-mobile-gyp in that path too, but, for now, please run npm install inside /mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/ and check if /mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/ is created.

I hope this was helpful.

bil-ash commented 6 years ago

@jaimecbernardo Thanks very much. It was too naive of me to not have noticed that. That solved the node-gyp problem but now there is another problem regarding ndk. The native node module compilation fails due to two errors, as it cannot find fgetpos and fsetpos globally. Although I have next to nothing knowledge about c++, but what I understood is that it is a problem with ndk(issue #480 in ndk) and there seem to be multiple solutions depending on the use case. I tried one but that didn't solve the problem. Hope you can help

jaimecbernardo commented 6 years ago

@bil-ash I'd need to have more info. Would you mind haring the log in gist, if it's too big? https://gist.github.com/ Thank you.

bil-ash commented 6 years ago

@jaimecbernardo Here is the log

uw@hp-2d28tu:/mnt/d/z/pp/n2$ cordova build
ANDROID_HOME=/mnt/d/z/sw/sdk
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
Subproject Path: CordovaLib
Starting a Gradle Daemon, 1 incompatible and 2 stopped Daemons could not be reused, use --status for details
The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
        at build_3sb27rni6qytflww6qguzlw7.run(/mnt/d/z/pp/n2/platforms/android/build.gradle:142)
The JavaCompile.setDependencyCacheDir() method has been deprecated and is scheduled to be removed in Gradle 4.0.
Incremental java compilation is an incubating feature.
The TaskInputs.source(Object) method has been deprecated and is scheduled to be removed in Gradle 4.0. Please use TaskInputs.file(Object).skipWhenEmpty() instead.
:CopyNodeProjectAssetsarmeabi-v7a UP-TO-DATE
:MakeToolchainarmeabi-v7a UP-TO-DATE
:BuildNpmModulesarmeabi-v7anpm info it worked if it ends with ok
npm verb cli [ '/home/uw/.nvm/versions/node/v8.10.0/bin/node',
npm verb cli   '/home/uw/.nvm/versions/node/v8.10.0/bin/npm',
npm verb cli   '--verbose',
npm verb cli   'rebuild',
npm verb cli   '--build-from-source' ]
npm info using npm@5.6.0
npm info using node@v8.10.0
npm info readInstalled object
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project',
npm verb rebuild   'nodejs-mobile-sample-project@0.1.0' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example',
npm verb rebuild   'a-native-example@0.0.1' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/nan',
npm verb rebuild   'nan@2.10.0' ]
npm verb rebuild path, id [ '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/node-gyp-build',
npm verb rebuild   'node-gyp-build@3.3.0' ]
npm info build /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
npm info lifecycle a-native-example@0.0.1~preinstall: a-native-example@0.0.1
npm info linkStuff a-native-example@0.0.1
npm verb linkBins a-native-example@0.0.1
npm verb linkBins [ { 'tmp-release': './release.js' },
npm verb linkBins   '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/.bin',
npm verb linkBins   false ]
npm verb linkMans a-native-example@0.0.1
npm info lifecycle a-native-example@0.0.1~install: a-native-example@0.0.1

> a-native-example@0.0.1 install /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
> node-gyp-build

gyp info it worked if it ends with ok
gyp verb cli [ '/home/uw/.nvm/versions/node/v8.10.0/bin/node',
gyp verb cli   '/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/bin/node-gyp.js',
gyp verb cli   'rebuild' ]
gyp info using node-gyp@0.1.1
gyp info using node@8.10.0 | linux | x64
gyp verb command rebuild []
gyp verb command clean []
gyp verb clean removing "build" directory
gyp verb command configure []
gyp verb check python checking for Python executable "python2" in the PATH
gyp verb `which` succeeded python2 /usr/bin/python2
gyp verb check python version `/usr/bin/python2 -c "import platform; print(platform.python_version());"` returned: "2.7.12\n"
gyp verb get node dir compiling against specified --nodedir dev files: /mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/
gyp verb build dir attempting to create "build" dir: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build
gyp verb build dir "build" dir needed to be created? /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build
gyp verb build/config.gypi creating config file
gyp verb build/config.gypi writing out config file: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build/config.gypi
gyp verb config.gypi checking for gypi file: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/config.gypi
gyp verb common.gypi checking for gypi file: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/common.gypi
gyp verb gyp gyp format was not specified; forcing "make"
gyp info spawn /usr/bin/python2
gyp info spawn args [ '/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make-android',
gyp info spawn args   '-I',
gyp info spawn args   '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/',
gyp info spawn args   '-Dnode_gyp_dir=/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp',
gyp info spawn args   '-Dnode_lib_file=/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/$(Configuration)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.' ]
gyp verb command build []
gyp verb build type Release
gyp verb architecture arm
gyp verb node dev dir /mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/
gyp verb `which` succeeded for `make` /usr/bin/make
gyp info spawn make
gyp info spawn args [ 'V=1', 'BUILDTYPE=Release', '-C', 'build' ]
make: Entering directory '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build'
  /mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/arm-linux-androideabi-clang++ '-DNODE_GYP_MODULE_NAME=a_native_example' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_ENGINE="v8"' '-DNODE_ENGINE_V8' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' '-D_GLIBCXX_USE_C99_MATH' -I/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/include/node -I/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/src -I/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/deps/uv/include -I/mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/deps/v8/include -I../../nan  -Wall -Wextra -Wno-unused-parameter -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++0x -MMD -MF ./Release/.deps/Release/obj.target/a_native_example/a_native_example.o.d.raw   -c -o Release/obj.target/a_native_example/a_native_example.o ../a_native_example.cc
In file included from ../a_native_example.cc:1:
In file included from ../../nan/nan.h:51:
In file included from /mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/include/node/node.h:63:
In file included from /mnt/d/z/pp/n2/platforms/android/src/com/janeasystems/cdvnodejsmobile/jni/libnode/include/node/v8.h:21:
In file included from /mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/memory:600:
In file included from /mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/typeinfo:61:
In file included from /mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/exception:84:
/mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/cstdio:137:9: error: no member named 'fgetpos' in the global namespace
using ::fgetpos;
      ~~^
/mnt/d/z/pp/n2/platforms/android/build/standalone-toolchains/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../include/c++/4.9.x/cstdio:139:9: error: no member named 'fsetpos' in the global namespace
using ::fsetpos;
      ~~^
2 errors generated.
a_native_example.target.mk:95: recipe for target 'Release/obj.target/a_native_example/a_native_example.o' failed
make: Leaving directory '/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/build'
make: *** [Release/obj.target/a_native_example/a_native_example.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/lib/build.js:258:23)
gyp ERR! stack     at emitTwo (events.js:126:13)
gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
gyp ERR! System Linux 4.4.0-43-Microsoft
gyp ERR! command "/home/uw/.nvm/versions/node/v8.10.0/bin/node" "/mnt/d/z/pp/n2/plugins/nodejs-mobile-cordova/node_modules/nodejs-mobile-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
gyp ERR! node -v v8.10.0
gyp ERR! node-gyp -v v0.1.1
gyp ERR! not ok
npm verb lifecycle a-native-example@0.0.1~install: unsafe-perm in lifecycle true
npm verb lifecycle a-native-example@0.0.1~install: PATH: /home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example/node_modules/.bin:/mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/.bin:/home/uw/bin:/home/uw/.local/bin:/home/uw/.nvm/versions/node/v8.10.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/ProgramData/Oracle/Java/javapath_target_1714010640:/mnt/g/programs/Python35/Scripts:/mnt/g/programs/Python35:/mnt/c/Program Files (x86)/Intel/iCLS Client:/mnt/c/Program Files/Intel/iCLS Client:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/mnt/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/mnt/c/Program Files (x86)/MySQL/MySQL Server 5.1/bin:/mnt/c/ProgramData/chocolatey/bin:/mnt/g/programs/Emscripten:/mnt/g/programs/Emscripten/emscripten/1.35.0:/mnt/c/Program Files/gnuplot/bin:/mnt/c/Program Files/nodejs:/mnt/g/roidSdk/platform-tools:/mnt/g/roidSdk/tools:/mnt/c/Program Files/Inno Setup 5:/mnt/g/programs/Java/jdk1.8.0_112/bin:/mnt/c/Users/bil-ash/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/bil-ash/.gradle/wrapper/dists/gradle-2.4-all/6r4uqcc6ovnq6ac6s0txzcpc0/gradle-2.4/bin:/mnt/c/Users/bil-ash/AppData/Local/GitHub/PortableGit_25d850739bc178b2eb13c3e2a9faafea2f9143c0/cmd:/mnt/c/Users/bil-ash/AppData/Local/GitHubDesktop/bin:/mnt/g/programs/OpenSSL-Win32/bin:/mnt/c/Users/bil-ash/AppData/Roaming/npm:/mnt/c/Users/bil-ash/AppData/Local/Microsoft/WindowsApps:/snap/bin:/mnt/d/z/sw/sdk/tools:/mnt/d/z/sw/sdk/platform-tools:/mnt/d/z/sw/sdk/tools/bin
npm verb lifecycle a-native-example@0.0.1~install: CWD: /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project/node_modules/a-native-example
npm info lifecycle a-native-example@0.0.1~install: Failed to exec install script
npm verb stack Error: a-native-example@0.0.1 install: `node-gyp-build`
npm verb stack Exit status 1
npm verb stack     at EventEmitter.<anonymous> (/home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:285:16)
npm verb stack     at emitTwo (events.js:126:13)
npm verb stack     at EventEmitter.emit (events.js:214:7)
npm verb stack     at ChildProcess.<anonymous> (/home/uw/.nvm/versions/node/v8.10.0/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
npm verb stack     at emitTwo (events.js:126:13)
npm verb stack     at ChildProcess.emit (events.js:214:7)
npm verb stack     at maybeClose (internal/child_process.js:925:16)
npm verb stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
npm verb pkgid a-native-example@0.0.1
npm verb cwd /mnt/d/z/pp/n2/platforms/android/build/nodejs-native-assets-temp-build/nodejs-native-assets-armeabi-v7a/nodejs-project
npm verb Linux 4.4.0-43-Microsoft
npm verb argv "/home/uw/.nvm/versions/node/v8.10.0/bin/node" "/home/uw/.nvm/versions/node/v8.10.0/bin/npm" "--verbose" "rebuild" "--build-from-source"
npm verb node v8.10.0
npm verb npm  v5.6.0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! a-native-example@0.0.1 install: `node-gyp-build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the a-native-example@0.0.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm verb exit [ 1, true ]

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/uw/.npm/_logs/2018-03-27T04_01_44_735Z-debug.log
:BuildNpmModulesarmeabi-v7a FAILED

FAILURE: Build failed with an exception.

* What went wrong:

Execution failed for task ':BuildNpmModulesarmeabi-v7a'.
> Process 'command 'npm'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED

Total time: 1 mins 17.796 secs
jaimecbernardo commented 6 years ago

Hi @bil-ash , I've tried building with the a-native-example module as well, and it was successful.

From the contents of the NDK issue, it's possible that it is related to the Android NDK version, since that issue seems to be fixed on later versions. Updating your NDK version to NDK r16 or newer should fix the issue.

bil-ash commented 6 years ago

@jaimecbernardo Yeah updating to ndk r16 did solve the problem. Thanks very much. So windows 10 anniversary update or later users can build native modules using windows subsystem for linux(wsl)

jaimecbernardo commented 6 years ago

@bil-ash Thanks a lot for making it work and letting us know :)

jaimecbernardo commented 6 years ago

Native Modules are now supported and their detection is automatic once again, after the v0.2.0 releases of the Cordova plugin and React Native plugin

The method for iOS is a new one, which is confirmed to go through App Store submission, so if you depend on this feature, give the updated versions a try.

home-grown-engineer commented 6 years ago

Got next error on 0.2.0 version.

The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
    at build_8qs6rvy2avo1px214o4rgre2s.run(/Users/username/Documents/Work/project/platforms/android/build.gradle:144)
    (Run with --stacktrace to get the full stack trace of this deprecation warning.)
publishNonDefault is deprecated and has no effect anymore. All variants are now published.
:CopyNodeProjectAssetsarmeabi-v7a UP-TO-DATE
:MakeToolchainarmeabi-v7a
A problem was found with the configuration of task ':MakeToolchainarmeabi-v7a'. Registering invalid inputs and outputs via TaskInputs and TaskOutputs methods has been deprecated and is scheduled to be removed in Gradle 5.0.
 - Cannot write to file '/Users/username/Documents/Work/project/platforms/android/build/standalone-toolchains/arm-linux-androideabi' specified for property '$1' as it is a directory.
:MakeToolchainarmeabi-v7a UP-TO-DATE
:BuildNpmModulesarmeabi-v7a FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':BuildNpmModulesarmeabi-v7a'.
> A problem occurred starting process 'command 'npm''

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 7s
3 actionable tasks: 1 executed, 2 up-to-date
Error: /Users/username/Documents/Work/project/platforms/android/gradlew: Command failed with exit code 1 Error output:
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':BuildNpmModulesarmeabi-v7a'.
> A problem occurred starting process 'command 'npm''

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 7s

I ran it using next command:

NODEJS_MOBILE_BUILD_NATIVE_MODULES=1 ./node_modules/.bin/cordova run android

On 0.1.5 build it working.

My environment: ndk - 17.1 gradle - 4.9 android studio - 3.1.3

Also I notice that my project don't start if build.gradle contain next setup:

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
    }
}
task wrapper(type: Wrapper) {
    gradleVersion = '4.1.0'
}

If I change it on: classpath 'com.android.tools.build:gradle:3.1.0' gradleVersion = '4.4.0'

It works well.

jaimecbernardo commented 6 years ago

Hi @britishd ,

So, is v0.2.0 working now after changing build.gradle?

Regarding getting more info on why, it's not building correctly, it might be useful to get more information by trying to build it with the flags gradle is suggesting. Here's an example of how to do it, from your Cordova project root path:

cd platforms/android/
./gradlew assembleDebug --stacktrace

Is this a case of a project that was created with v0.1.5 and then upgraded to v0.2.0? If it was the case, how did you update it? It might have some lingering build files. It might be useful to delete platforms/android/build/ and also remove and re-add the plugin, like this:

cordova plugin remove nodejs-mobile-cordova
cordova plugin add nodejs-mobile-cordova@0.2.0

I hope this was helpful. Please let us know if you figure out what's happening.

xeoshow commented 6 years ago

@bil-ash Hello, I am also trying to setup the build env (for native modules) on WSL, since I have already installed the android SDK, NDK, etc on windows, Could I directly use them in the WSL context? Or actually I should install those things start from scratch on WSL?

Any help is highly appreciated!

Best regards, Jason

bil-ash commented 6 years ago

@xeoshow You would have to install everything. wsl is linux without the gui. So you would have to install everything(nodejs,jdk,android sdk,ndk,etc) for linux(from within wsl)

xeoshow commented 6 years ago

@bil-ash Understood and thank you so much!

DuBistKomisch commented 5 years ago

I have native modules working mostly great in a test app using nodejs-mobile-cordova (after downgrading to NDK 18), but I don't want to use cordova or react-native, just a plain app like the native-gradle-node-folder sample.

Is there a good way to do this at the moment? Or do I just have to transplant parts of the build.gradle and hack it until it works?

jaimecbernardo commented 5 years ago

Hi @DuBistKomisch , Indeed, you would have to use the method implemented in build.gradle of the plugins and chose the approppriate binary file at runtime. You could also use your custom method for pre-cross-compiling and use them in the application. The build.gradle contents are a good start to understand how the modules can be built.

DuBistKomisch commented 5 years ago

@jaimecbernardo thanks for confirming, no worries, will hack away at it for now.