Skip to content

How to build libnode.so

Eric Lange edited this page Mar 30, 2020 · 3 revisions

(30 March 2020) This document is out of date

Building the node libraries is a giant pain and it takes a lot of patience. I recommend you just stick with the prebuilts included in the release. If, however, you are interested in how to build the libraries from scratch, the instructions are included here. Remember, you asked.

There is some manual intervention required to get this to all work. This is because we are using a non-standard build of node. By default, the Android version of node does not include V8 snapshots. However, we want to use them. Snapshots dramatically increase the speed of starting up, and we want to take further advantage of them in the future. The major issue is that you cannot produce the default snapshots with cross-compilation. You must produce them on the targets themselves. Since Android is cross-compiled, this creates a problem. So we must produce the snapshot creator with the cross-compiler, then run the snapshot creator on the emulator in order to produce the snapshot, and then finally copy back the snapshot from the emulator and complete cross-compilation. So here we go:

Step 1: Build node for your host machine

.../LiquidCore/deps/node-8.9.3% ./configure
.../LiquidCore/deps/node-8.9.3% make

Go make a sandwich and come back in about 30 minutes or so. Hopefully it all completed correctly. Next, move the entire out directory someplace else. This contains a snapshot creator (./out/Release/mksnapshot) that will work on the host, but will generate garbage snapshots for the target. But we still need it. So ...

.../LiquidCore/deps/node-8.9.3% mv out ~/out.host

Step 2: Build up to snapshot creation for a target

.../LiquidCore/deps/node-8.9.3% ./android-configure /path/to/android/ndk arm

You will eventually need to do this for each architecture you want to support. It works for arm, x86, arm64-v8a and x86_64.

Now, edit out/deps/v8/src/mksnapshot.target.mk in your favorite text editor and find the line:

LDFLAGS_Release := \

Add -pie \ in the line immediately after and save the file. Then,

.../LiquidCore/deps/node-8.9.3% make

This will build for a while and then eventually fail with a message saying that it can't execute mksnapshot. This is because it is trying to run the target (arm, in this case) version of mksnapshot instead of the host (say, your Mac) version. So we have to replace it with the host version, but don't delete it, because we still need to produce the correct snapshot. Although your host version will allow compilation to complete, it will create a snapshot that is only valid on your host architecture and will thus crash when you try to use the library later. So, copy the created mksnapshot someplace else and replace it with the host one so we can keep going:

.../LiquidCore/deps/node-8.9.3% mv out/Release/mksnapshot ~/
.../LiquidCore/deps/node-8.9.3% cp ~/out.host/Release/mksnapshot out/Release/
.../LiquidCore/deps/node-8.9.3% make

The build process should run to completion, but with a bogus snapshot. At this point, while compilation is going on, we can create the correct snapshot.

Step 3: Create the target snapshot

Now you need to fire off an Android emulator running with an image based on your target architecture. Once it is started:

.../LiquidCore/deps/node-8.9.3% adb root
.../LiquidCore/deps/node-8.9.3% adb push ~/mksnapshot /data
.../LiquidCore/deps/node-8.9.3% adb shell
root@generic_arm:/ # cd /data
root@generic_arm:/ # ./mksnapshot --startup_src=snapshot.cc
root@generic_arm:/ # exit
.../LiquidCore/deps/node-8.9.3% adb pull /data/snapshot.cc out/Release/obj.target/v8_snapshot/geni/
.../LiquidCore/deps/node-8.9.3% touch out/Release/obj.target/v8_snapshot/geni/snapshot.cc

What we're doing here is copying the correct snapshot creator to the emulator, producing the correct snapshot.cc required by V8 and copying it back into the build.

Step 4: Finish it

You can either wait until compilation has completed, or you can cancel it if it is still going. Simply run make again to compile the correct snapshot and finish the build.

.../LiquidCore/deps/node-8.9.3% make

Now you will have a working libnode.so in out/Release/lib.target/libnode.so. You will have to repeat steps 2-4 for each ABI.