Skip to content

Instantly share code, notes, and snippets.

@adammw
Created August 3, 2012 06:30
Show Gist options
  • Save adammw/3245130 to your computer and use it in GitHub Desktop.
Save adammw/3245130 to your computer and use it in GitHub Desktop.
Node.js for Raspberry Pi

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/[email protected])

UNSTABLE: v0.11.9 (joyent/[email protected])

MAINTENANCE: v0.8.25 (joyent/[email protected])

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
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

@eendeego
Copy link

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 ?

@adammw
Copy link
Author

adammw commented Aug 13, 2012

@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.

@adammw
Copy link
Author

adammw commented Aug 13, 2012

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.

@adammw
Copy link
Author

adammw commented Aug 13, 2012

@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.

@adammw
Copy link
Author

adammw commented Aug 13, 2012

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.

@adammw
Copy link
Author

adammw commented Aug 13, 2012

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...

@eendeego
Copy link

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 (nodejs/node-v0.x-archive#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 !!

@eendeego
Copy link

Yes, the git command was wrong indeed.

@eendeego
Copy link

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

@eendeego
Copy link

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...

@eendeego
Copy link

Ok, 0.8.7 seems to bee working too.

@eendeego
Copy link

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

@npenin
Copy link

npenin commented Aug 20, 2012

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 ?

@npenin
Copy link

npenin commented Aug 20, 2012

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

@eendeego
Copy link

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

@adammw
Copy link
Author

adammw commented Oct 21, 2012

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.

@eendeego
Copy link

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.

@herzi
Copy link

herzi commented Dec 20, 2012

No need for tmux/screen; just run this:

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

@pekko666
Copy link

pekko666 commented May 1, 2013

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

@robdodson
Copy link

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

@langersteff
Copy link

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@

@SunboX
Copy link

SunboX commented Jul 23, 2014

How to fix this issue?

$ tar xzvf node-v0.10.24-linux-arm-armv6j-vfp-hard.tar.gz --strip=1
$ sudo cp bin/node /usr/local/bin/
$ sudo cp bin/npm /usr/local/bin/
$ node -v
v0.10.24
$ sudo npm install forever -g

module.js:340
    throw err;
          ^
Error: Cannot find module 'npmlog'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at /usr/local/bin/npm:19:11
    at Object.<anonymous> (/usr/local/bin/npm:87:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

@SunboX
Copy link

SunboX commented Jul 23, 2014

@robdodson and @langersteff

If you changed /etc/profile and point PATH to /opt/node/bin the sudoers (sudo) can't find it! Sudo resets PATH for security reasons. It doesn't matter what is set in /etc/profile unless you run sudo -i.

@hertzg
Copy link

hertzg commented Aug 13, 2014

I've searched all over how to cross compile node js for armv6hf (raspberry pi) and as a result ended up with this script which works great with my jenkins setup.

https://gist.github.com/hertzg/12c2d7fc40f68ff6deeb

Assuming you have saved the file as ./cc-node-armv6hf.sh and gave +x permission

# to build the latest stable version
./cc-node-armv6hf.sh

# to build specific source archive
_PARAMS_NODEJS_SOURCE_ARCHIVE_URL="http://nodejs.org/dist/v0.10.28/node-v0.10.28.tar.gz" ./cc-node-armv6hf.sh

Current latest stable version (v0.10.30) will fail cross compiling no matter what. More info here: nodejs/node-v0.x-archive#8062

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment