-
Notifications
You must be signed in to change notification settings - Fork 199
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
Cross Compilation features #36
Conversation
Two options have been defined for `nodec` in order to properly define --dest-os and --dest-arch whose values are actually the same one can pass down to the node.js configuration. When those values are defined we also define some other needed flags to prevent node.js compilation to execute target binaries on the host. This is needed because binaries are meant for another architecture/os than the current one. Applications for this feature are related to the ability to compile for another device/processor architecture, or even utilize an older linux box to compile for newer kernels. I also managed to compile Mac OS X to Linux but in order to do so one must be able to perform the `mkpeephole` step on the target os directly or using a virtualized machine. I think it would be great to also be able to define at runtime or install time the node.js version and get the tarball at runtime with the source code one wants. Note: in order to perform cross-compilation one must be able to setup a cross-compile toolchain properly (crosstool-ng is advised to greatly simplify this task).
Cross compilation shouldn't apply to windows (other systems are used there that will also emulate the linux env flavor). Also restored wrongly removed vcbuild args.
Sorry for the delay. I'll look into it ASAP. Thanks for the PR. |
d8d4f8b
to
a1e49ed
Compare
With @pmq20 having v1 support C++ based native modules wouldn't this not work in most cases as native modules need to be built on their intended platforms? I'm pretty sure bcrypt compiled on Mac doesn't work on Linux, but maybe I'm wrong? |
@pmq20 Thanks, I'll rebase against the latest changes asap not sure about the windows failing compilation, but I think it might be already broken when I started working on the PR. @firrae By using node.js from source code you basically get the same support you'd get for the node executable itself (node-compiler only wraps it by creating the temporary filesystem before to actually call the entry file). So you can refer to the official support, I guess, for possible issues with native modules. By the way you can find several docs online about node.js specific cross-compilation cases [1] which are pretty well covered. In order to do so successfully of course you need to set up a cross compilation toolchain and properly configure it inside your shell environment. The only issue I got from Mac was about the install process trying to execute some runtime scripts on the host machine – the infamous You can check code comments to see the options needed to avoid common cross compilation issues, I thought to enable them by default when cross compilation is detected
I'm still stuck with the P.S. I also managed to get internally a way to define what node.js version to compile from, but since then the master has been updated with patches on the node code. So now it must be checked that those patches are compatible with v6.x before to be able to downgrade (at this point it might make sense to force the specific min and max versions supported by those patches). @pmq20 If the patches are compatible with the v6.x line we could exploit git to patch the source code automatically (more or less the same way React Native does it [3]). [1] https://github.com/netbeast/docs/wiki/Cross-Compile-NPM-modules |
@lexor90 that's interesting, I've never had to look at cross-compiling before the project I'm currently on so thanks for the links! It's good to know. |
@firrae I just gave a quick look at the node-gyp cross-compilation status which is what native modules do use to compile themselves from sources and it seems there's still some issue with it [1] mainly because all of the libraries built upon it have no concept of cross-compiling, so they do assume that I know for sure there's some way to get bcrypt cross compiled properly (by exporting needed files from the target platform) but I never tried it though. Maybe a quick workaround here would be to be able to run some pre defined script on the first run on your target machine, in order to install those modules and just link the libraries from the outside. Some sort of shared library. But I don't actually know what kind of involvement would it mean on the implementation side and what kind of compatibility support would it retain with plain nodejs. I'd rather search for some solutions that may already be in use out there. |
Semi off topic: Personally speaking, I'm in a bind where the idea of build once and deploy anywhere is almost a necessity so we've built out our own flow for it. The project I'm on has the need to be installed on isolated servers with no internet connection and limited build tools (usually it's a VM they spin up and tell us to install on) so having to build it on startup wouldn't help me, personally, but I bet there are plenty of other use cases where this would be greatly welcome. Once I solve my build issue using this (currently bcrypt doesn't seem to work for me) I'll likely set up a build pipeline that builds on each of our supported platforms. Thanks for the links and info though @lexor90. |
@lexor90 I noticed that you have a binary and a shell script in the bin directory of your PR, are those needed for something or just the results of a test that got included in a push? |
@firrae Yeah, you're right. I somehow missed I've checked them in. I'm going to remove them as they are not related to the project itself, thanks. BTW the |
@pmq20 can we setup a cross-compile toolchain on our CI in order to test this? I think the easiest cross-compilation would be changing the target processor (we do also support changing operating system, but it's quite tricky as the binary format does differ - for example mac uses mach-o, while linux uses elf). If this looks good to you merge it, we're simply exposing the native support (we also need to point out to the official node bugtracker for any issue regarding cross-compilation as long as it's not concerned to one of our nodec-specific dependencies). |
@lexor90 May I share another possible approach on cross-compiling? @ngot has found out that simply attaching a chunk of data to the end of the executable does no harm to the executable itself. By utilizing this technique we could pre-compile a dozen of binaries for each arch and OS, and download them when compiling a user's project. The compiler could just compress the user's folder into a SquashFS image and attach it to the end of the downloaded binary and it is done. In this way, cross-compiling is easily achieved. Still need proof of concept but I think this direction is very promising. |
Hey there, I know that also pkg works with precompiled binaries (according to their readme) and I was at first looking at this possibility, as it would mean to have a much quicker compilation time, but then I could not find a way to make this happen since we need to compile nodec from source. I'm surely going deeper into this approach, as it could be a nice solution also for #40. |
@pmq20 if we are able to precompile |
@lexor90 Yes. It should be easy since |
Such a wanted feature, is there any plans to merge this ? |
Hello there,
and thank you for your awesome work.
Since we're planning to add compilation capabilities to our CI/CD environment we also have the needing to be able to cross-compile from various platforms to others.
I managed to add flags to specify valid node.js compilation platforms (both os and cpu arch):
I managed to get it to also cross-compile between mac and linux (with some limitations due to newer v8 versions, known things out there).
Valid architectures and CPUs are the same of the vanilla node.js (it should be checked with added dependencies, BTW).
In order to properly cross-compile one must use a valid toolchain, since this project always compiles from source it could also be provided inside the repo itself, what do you think about it?
Let me know if it looks good to you and your thoughts.