public
Last active

Node.js for Raspberry Pi

  • Download Gist
README.md
Markdown

Node.js for Raspberry Pi

Pre-built binaries

Recent releases have been pre-built using cross-compilers and this script and are downloadable below.

If you have found these packages useful, give me a shout out on twitter: @adammw

The .tar.gz file is an archive, including npm and man pages, that can be extracted and used directly:

cd ~/node/ # or /usr/local if you're feeling brave
tar xzvf /path/to/binary.tar.gz --strip=1

The .bin file is just the node.js executable.

Raspbian (hard-float)

STABLE: v0.10.24 (joyent/node@v0.10.24-release)

UNSTABLE: v0.11.9 (joyent/node@v0.11.9-release)

MAINTENANCE: v0.8.25 (joyent/node@v0.8.25-release)

Raspberry Pi Soft Float Systems

v0.8.9-pre (TooTallNate/node@???)

Compiling Node.js

This gist is now rather old gist, as such it details a lot of problems which are not present in recent releases and patches required. Patches may not work nor be correct anymore. Use everything at your own risk.

Tips

Cross-compiling on Linux

  1. Install or download a cross-compiler. The pre-compiled cross-compilers from raspberrypi/tools may work for you, however please ensure you get the correct one for your system (e.g. use the hardfp version for Raspbian) and install the compilers in your PATH by editing your .profile file, ensuring to add the /tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin directory.
  2. Download this cross-compile helper script.
  3. Download the version of node.js source code you want or clone the git repository.
  4. If you are compiling Node.js 0.8.10 or lower, apply either this newer set of patches or this patch, but not both.
  5. Run the cross-compiler helper script to get a shell with the correct variables. If compiling for a soft float system or using a different toolchain besides the default (which is arm-bcm2708hardfp-linux-gnueabi), use the HOST envrionmental variable to set the correct HOST prefix, e.g. :
HOST=arm-bcm2708-linux-gnueabi ~/crosscompile.sh

otherwise:

~/crosscompile.sh
  1. It seems that the arm ld doesn't work with the makefile arguments, so set the following export:
export LD="$CXX"
  1. If you are compiling Node.js 0.8.4 or lower, set the following exports:
export GYP_DEFINES="armv7=0"
export CCFLAGS='-march=armv6'
export CXXFLAGS='-march=armv6'
  1. Run configure:
./configure --without-snapshot
  1. Run make
make

Using --jobs=8 to parallelize the build may speed things up if you have a multi-core processor, but is completely untested.

  1. Copy the node executable to the Raspberry Pi using scp
scp node raspbian:~/bin/node

Native Compile

Be warned: this will take forever for little gain.

  1. Download the version of node.js source code you want or clone the git repository.
  2. If you are compiling Node.js 0.8.10 or lower, apply this newer set of patches or this patch, but not both.
  3. Run configure:
./configure --without-snapshot
  1. Run make and make install
make
make install
v0.10.0/node-v0.10.0-linux-arm-armv6j-vfp-hard.bin
v0.10.0/node-v0.10.0-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.1/node-v0.10.1-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.1/node-v0.10.1-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.10/node-v0.10.10-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.10/node-v0.10.10-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.11/node-v0.10.11-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.11/node-v0.10.11-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.12/node-v0.10.12-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.12/node-v0.10.12-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.13/node-v0.10.13-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.13/node-v0.10.13-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.15/node-v0.10.15-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.15/node-v0.10.15-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.16/node-v0.10.16-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.16/node-v0.10.16-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.17/node-v0.10.17-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.17/node-v0.10.17-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.18/node-v0.10.18-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.18/node-v0.10.18-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.2/node-v0.10.2-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.2/node-v0.10.2-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          
v0.10.21/node-v0.10.21-linux-arm-armv6j-vfp-hard.bin

This file has been truncated, view the full file.


          
v0.10.21/node-v0.10.21-linux-arm-armv6j-vfp-hard.tar.gz

This file has been truncated, view the full file.


          

52 other files aren't shown.

Hi, I'm running this script:

export NODE_VER=0.8.6
cd ~
rm -rf ~/work/node-build/node-$NODE_VER;mkdir -p ~/work/node-build && cd ~/work/node-build
rm -rf ~/opt/node-$NODE_VER;mkdir -p ~/opt/node-$NODE_VER

curl -O https://github.com/adammw/node/commit/arm-patches-2.patch

curl http://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER.tar.gz | tar xz
cd node-v$NODE_VER
git apply --stat ../arm-patches-2.patch

./configure --shared-openssl --without-snapshot --prefix=~/opt/node-$NODE_VER

date;time make CFLAGS+=-O2 CXXFLAGS+=-O2 install;date
# real    106m20.999s
# user    103m27.800s
# sys     1m43.870s

./node 
# Illegal instruction

And I still can't run node. Any hints ?

@luismreis: are you native compiling or cross-compiling? I'm guessing by the time taken that it's native.
First thing with any crash would be to run gdb to find out where the illegal instruction is occuring. I've also heard that --shared-openssl can cause problems, I usually try a --without-ssl build first as it should be quicker and also eliminates any bugs that could occur in the ssl libraries. I think the successful build I had above was with static SSL, and it was cross-compiled too - there may be some subtile differences between the compilers.
And on that note, you should obviously check that your compiler generates ARMv6 instructions not ARMv7, and that v8 is set not to generate armv7 as well.

I'll try and see if I can build 0.8.6 or reproduce your error.

You are correct. I just tried 0.8.6 with ./configure --without-snapshot --debug with the cross compiler and it produces Illegal Instructions.

GDB Backtrace:

Program received signal SIGILL, Illegal instruction.
0x5480a060 in ?? ()
(gdb) bt
#0  0x5480a060 in ?? ()
#1  0x004ffae4 in v8::internal::Invoke (is_construct=false, function=..., 
    receiver=..., argc=0, args=0x0, has_pending_exception=0xbefff31b)
    at ../deps/v8/src/execution.cc:118
#2  0x004ffed8 in v8::internal::Execution::Call (callable=..., receiver=..., 
    argc=0, argv=0x0, pending_exception=0xbefff31b, convert_receiver=false)
    at ../deps/v8/src/execution.cc:179
#3  0x0049f06c in v8::internal::Genesis::CompileScriptCached (name=..., 
    source=..., cache=0x0, extension=0x0, top_context=..., 
    use_runtime_context=true) at ../deps/v8/src/bootstrapper.cc:1369
#4  0x0049ece0 in v8::internal::Genesis::CompileNative (name=..., source=...)
    at ../deps/v8/src/bootstrapper.cc:1313
#5  0x0049eb7c in v8::internal::Genesis::CompileBuiltin (isolate=0xacb038, 
    index=3) at ../deps/v8/src/bootstrapper.cc:1282
#6  0x004a0e68 in v8::internal::Genesis::InstallNatives (this=0xbefff5f4)
    at ../deps/v8/src/bootstrapper.cc:1665
#7  0x004a43a8 in v8::internal::Genesis::Genesis (this=0xbefff5f4, 
    isolate=0xacb038, global_object=..., global_template=..., extensions=0x0)
    at ../deps/v8/src/bootstrapper.cc:2327
#8  0x00499ed8 in v8::internal::Bootstrapper::CreateEnvironment (
    this=0xadc860, isolate=0xacb038, global_object=..., global_template=..., 
    extensions=0x0) at ../deps/v8/src/bootstrapper.cc:305
#9  0x00479380 in v8::Context::New (extensions=0x0, global_template=..., 
    global_object=...) at ../deps/v8/src/api.cc:4360
#10 0x00286e88 in node::Start (argc=1, argv=0xad38d0) at ../src/node.cc:2931
#11 0x0029e2d8 in main (argc=1, argv=0xbefff844) at ../src/node_main.cc:65
(gdb) x/i $pc
=> 0x5480a060:  movw    r5, #47748  ; 0xba84

I have a feeling I know what it might be... but I'm not sure.
Basically V8 is still producing invalid instructions.

@luismreis: Um...
git apply --stat != git apply --stat --apply
http://www.kernel.org/pub/software/scm/git/docs/git-apply.html

Still checking though - there may be more problems but not actually applying the patch is a pretty big one.

Ok, I've found another bug, but that's more that the patch doesn't patch enough.
It adds symbols for VFP2 as well as renaming VFP to VFP3, but does no auto-detection of VFP2 so the gyp build files must explicitly define CAN_USE_VFP2_INSTRUCTIONS.
I'll see what I can do.

It looks like there's a better patch in later versions of V8. http://codereview.chromium.org/10818026/ commited in r12194, went into v8 trunk r12207 (Version 3.12.17). I'm trying to see if compiling node.js with that version of V8 produces a working binary, if so I'll update the instructions...

Hi @adammw, I'm sorry, I lost track of this gist. Thank you for all this work!

  1. Yes, the build is native.
  2. I wasn't so lucky with gdb, I had to resort to core dumps (https://github.com/joyent/node/issues/3755)
  3. Erm... that apply stuff is really strange, I picked it from https://github.com/gflarity/node_pi. I'm going to recheck it.
  4. Thanks !!

Yes, the git command was wrong indeed.

Also, v0.8.7 just came out, but the changelog doesn't mention any V8 changes.

Hi, I've changed the script to:

export NODE_VER=0.8.6
cd ~
rm -rf ~/work/node-build/node-$NODE_VER;mkdir -p ~/work/node-build && cd ~/work/node-build
rm -rf ~/opt/node-$NODE_VER;mkdir -p ~/opt/node-$NODE_VER

curl -O https://github.com/adammw/node/commit/arm-patches-2.patch

curl http://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER.tar.gz | tar xz
cd node-v$NODE_VER
git apply --stat --apply ../arm-patches-2.patch

./configure --without-ssl --without-snapshot --prefix=~/opt/node-$NODE_VER

date;time make CFLAGS+=-O2 CXXFLAGS+=-O2 install;date
real    98m46.584s
user    96m19.950s
sys     1m27.740s

It works! I don't need SSL for my stuff, so this may be enough for now. Note that no SSL only shaves of 8~10 minutes.

Now to replace that 0.8.6 with 0.8.7...

Ok, 0.8.7 seems to bee working too.

Sorry to spam your gist, here's my final script:

export NODE_VER=0.8.7
cd ~
rm -rf ~/work/node-build/node-$NODE_VER;mkdir -p ~/work/node-build && cd ~/work/node-build
rm -rf ~/opt/node-$NODE_VER;mkdir -p ~/opt/node-$NODE_VER

curl -O https://github.com/adammw/node/commit/arm-patches-2.patch

curl http://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER.tar.gz | tar xz
cd node-v$NODE_VER
git apply --stat --apply ../arm-patches-2.patch

./configure --shared-openssl --without-snapshot --prefix=~/opt/node-$NODE_VER

date;time make CFLAGS+=-O2 CXXFLAGS+=-O2 install;date

Does not work on my Pi : I have an "Instruction non permise" (sorry for the french - I believe it is Illegal Instruction in English) when running
npm install express actually when running npm install "anything"...

Any clue ?

my mistake it was the wrong npm running. Everything looks working for now. Thanks a lot for all this !

It seems that node 0.8.10 compiles out of the box. No more patching necessary!! Yay!!

Hi @luismreis, do you mind telling me what cross-compiler you used (if any) or how you did it. I'm following my own instructions and still not getting anything that works. From what I've heard 0.8.10 and higher includes a lot more patches designed to get it working on the Raspberry Pi, but I'm still not having too much luck.

Hi @adammw, I'm not cross compiling... I'm compiling directly on the thing. Node 0.8.14 takes ~82 minutes to build with static openssl and snapshots (no external dependencies).

I recently had a memory issue and found out that node pre-allocates 10MB just for TLS and this messes with memory usage (my final target has a 128/128 split). So, my current script is:

export NODE_VER=0.8.14
export BUILD=node-$NODE_VER-static_ssl-snapshots-sB512
export PREFIX=~/opt/$BUILD
cd ~
rm -rf ~/work/node-build/$BUILD-src;mkdir -p ~/work/node-build && cd ~/work/node-build
rm -rf $PREFIX;mkdir -p $PREFIX

[[ -f node-v$NODE_VER.tar.gz ]] || \
curl -O http://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER.tar.gz

tar zxf node-v$NODE_VER.tar.gz
mv node-v$NODE_VER $BUILD-src
cd $BUILD-src
perl -pi -e 's/10 \* 1024 \* 1024/512 \* 1024/' lib/tls.js
./configure --gdb --prefix=$PREFIX

date;time make install;date

Note: It's extremely convenient to run this on a tmux/screen session.

No need for tmux/screen; just run this:

nohup bash -c "date; time make install; date" & sleep 1; tail -f nohup.out

That node-v0.10.5-linux-arm-armv6j-vfp-hard.tar.gz is actually v0.10.4
sudo -i
cd /tmp
wget https://gist.github.com/raw/3245130/v0.10.5/node-v0.10.5-linux-arm-armv6j-vfp-hard.tar.gz
cd /usr/local
tar xzvf /tmp/node-v0.10.5-linux-arm-armv6j-vfp-hard.tar.gz --strip=1
...
root@raspberrypi:/usr/local# node -v
v0.10.4

I know this is a super old thread but I'm having no luck with any of the pre-built binaries. I keep getting "No such file or directory" whenever I try to run node, even though it shows up in my path.

I finally followed this post to just dump it into /usr/local because nothing else seemed to work. I've tried putting it in /opt and just ~/node. All previous times I've updated my PATH so that which node spits out the correct result. Still, when I try to actually run it I get "No such file or directory"

Here's a screenshot of me sucking at life:
http://cl.ly/image/3G3i0z2k0S41

I got the same error and also tried copying the pre-built binaries to usr/local/bin, but it still doesn't work.

    pi@raspberrypi ~ $ node
    -bash: /usr/local/bin/node: No such file or directory
    pi@raspberrypi ~ $ which node
    /usr/local/bin/node
    pi@raspberrypi ~ $ l /usr/local/bin
    node*  node-waf*  npm@

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.