JaneaSystems / node-mobile-react-demo

A React Native application that runs PouchDB on Node.js (ChakraCore)
http://www.janeasystems.com/blog/node-js-meets-ios
115 stars 12 forks source link

Compiling a native node library to iOS #1

Open staltz opened 7 years ago

staltz commented 7 years ago

Hi! This is an amazing proof of concept that gave me good chances to explore this same technique in a React Native project I'm working on.

The nodeproj can run many node modules, except those that have native bindings. For example, node-sodium. I installed that package in nodeproj, and tried to get it working. Initially it didn't work at all because node-sodium's binding.gyp doesn't build for iOS, only for Mac, Linux, Win. So then I (1) recompiled libsodium for iOS (arm64), and then (2) modified binding.gyp to include build config for iOS. After a lot of effort, I managed to make node-sodium/build/Release with the file sodium.node targeted for iOS. So far so good.

My main challenge now is to get that sodium.node working when I build the iOS project in Xcode. I hit the following runtime error on an iOS device:

/private/var/containers/Bundle/Application/B2DE3106-0E5F-4B61-BBD2-73E919993B07/MyApp.app/nodeproj/node_modules/sodium/build/Release/sodium.node: 
required code signature missing for '/private/var/containers/Bundle/Application/B2DE3106-0E5F-4B61-BBD2-73E919993B07/MyApp.app/nodeproj/node_modules/sodium/build/Release/sodium.node'

It seems (I'm not so familiar with iOS development) that I need to code sign that file, in a similar way that nodeLib.framework is. And here is where I got stuck.

Do you have any ideas how to go forward here? Solving this would enable other node packages with native bindings to work with this proof of concept. For instance, leveldown could be used instead of memdown.

jaimecbernardo commented 7 years ago

This demo is still a proof of concept and we haven't addressed the native modules feature of Node.js yet. .node files created by native modules encapsulate a dynamic library, and dynamic libraries have limitations on iOS. There are ways to solve this issue, by embedding the native module in nodeLib or changing the module to be a static lib compiled with the application, but those approaches require changes to the nodeLib.framework. We haven't yet explored solutions that don't require changes to the nodeLib.framework, but it might be possible.

staltz commented 7 years ago

Okay, I understand. As a temporary solution it would be okay to embed sodium and others into nodeLib, but indeed this is not an ideal solution. Maybe some solution that generates nodeLib on (pre)compile time based on what packages are used in nodeproj?

By the way, how was nodeLib.framework built? The important file is nodelibs/ios/nodeLib.framework/nodeLib (9MB) and it's a binary. I couldn't understand from the source code how to build that myself.

jaimecbernardo commented 7 years ago

The changes to node that allow it to be built for iOS are not public yet, so there's currently no way to build it until the source code is released. This repository is only a showcase of node working on iOS.

staltz commented 7 years ago

That's very disappointing, not a consistent open source attitude when Node.js itself is open source, as is ChakraCore, React Native and others.

orangemocha commented 7 years ago

@staltz I know it's been a while since your last comment, but I just saw your comment on Twitter and wanted to clear any misunderstandings. The intention is not to keep iOS port proprietary. The intention is to release it once it's mature enough to not turn people away. As soon as we can do that, we'll also publish the source, of course.

staltz commented 7 years ago

Hi @orangemocha, good to hear. I'd be glad to collaborate on this effort, as you can see from this issue I'm willing to get my hands dirty and do something. Keeping it closed blocks me from doing that.

orangemocha commented 7 years ago

Great, I am looking forward to your participation and also that of the community at large. It won't be long. Thank you for your patience.

staltz commented 7 years ago

Bringing this to your knowledge: https://github.com/node-on-mobile

logikaljay commented 7 years ago

Hi @orangemocha, @jaimecbernardo

Firstly, love your work.

Is there any update you can give us regarding when the build steps to generate a nodeLib.framework will become public?

I am looking at using this for a prototype of my own, however testing only on the device is kind of annoying.

I would settle for a x86_64 archetecture being included in the framework in the meantime!

orangemocha commented 7 years ago

@logikaljay , thank you for your words of appreciation!

We are working to publish the iOS build and sources by the end of September. I apologize for the wait.

It's going to come to this repo: https://github.com/janeasystems/nodejs-mobile. Android builds are already available there.

logikaljay commented 7 years ago

Amazing, thank you so much for the hard work you guys are putting in!

If anyone else was in my boat, a simple work around for now is just to call node::Start when you are targeting a real device, else just install node on your Mac and run posix_spawn to start node in the simulator

orangemocha commented 7 years ago

Today we published our work for bringing Node.js to Android and iOS, including React Native and Cordova plugins, and all the source code.

Announcement: http://www.janeasystems.com/blog/announcing-node-js-mobile-apps-true-node-js-runtime-android-ios/ Project website: https://code.janeasystems.com/nodejs-mobile Main GitHub repo: https://github.com/janeasystems/nodejs-mobile

:champagne: