Node.JS News

Everything you should know on NodeJS

Ruby to build Node.js RaspberryPI
Vagrant to cross-compile Node.js

Nodejs since Node 0.8.17 provide an ARM/RaspberryPI Node.js tar.gz, but let’s figure out how fun it could be using Ruby to build Node.js Linux Debian Raspbian .deb and others ARM architectures!

A Node toolchain that just work!


To get Node.js working on ARM processors like the one on RaspberryPI, there’s 2 ways:

  • Native compile on ARM (takes hours)
  • Cross-compilation of NodeJS using so so scripts

Purpose is to provide a toolchain that just work to build Node.js for multiple ARM targets:

  • ARMv5 NAS like Synology, Seagate Dockstar,…
  • ARMv6 like Raspberry PI, PogoPlug,…
  • ARMv7 Cortex A8 like BeagleBone, …

Feel free to download that stuff and fork me on GitHub!

Cross-compile Node.js for Raspberry PI the safe way


To get ride of it, let’s use a bunch of Ruby tools:

  • Vagrant to keep our environment clean and have a portable building toolchain
  • Fpm a ruby tool that let you automaticaly create .deb Linux debianish packages

Why using a Ruby tool like Vagrant to deal with Node.js?


Because Vagrant is awesome, not only, Vagrant Box let you build and rebuild a safe VirtualBox environment to work with, and when you start your Vagrant instance a build script is automaticaly launched!

  1. install VirtualBox on your computer
  2. install Vagrant : gem install vagrant
  3. now you’re able to create a Vagrant Box!

Why using a Ruby tool like fpm to deal with Node?


Because fpm is awesome, Effing Package Managers can build packages for multiple platforms (deb, rpm, etc) with great ease and sanity!

Node.js built using a magic script!


#!/bin/bash

OLDPATH=${PATH}

UpdateBox()
{
   echo "-> Installing apt-get packages"
   aptitude update
   aptitude -y install build-essential ruby-dev
   gem install fpm
}

XtoolsArmv5()
{
   if [ ! -d x-tools ]; then 
         echo "-> Installing Cross Compiler ARMv5"
         echo "-> Downloading Cross Compiler ARMv5"
         wget -q http://archlinuxarm.org/builder/xtools/x-tools.tar.xz;
         echo "-> End of Download Cross Compiler ARMv5"
         tar Jxfv x-tools.tar.xz
      else
         echo "Cross Compiler for ARMv5 already installed ..."
   fi
}

XtoolsArmv6()
{
   if [ ! -d x-tools6h ]; then 
         echo "-> Installing Cross Compiler ARMv6"
         echo "-> Downloading Cross Compiler ARMv6"
         wget -q http://archlinuxarm.org/builder/xtools/x-tools6h.tar.xz;
         echo "-> End of Download Cross Compiler ARMv6"
         tar Jxfv x-tools6h.tar.xz
      else
         echo "Cross Compiler for ARMv6 already installed ..."
   fi
}

XtoolsArmv7()
{
   pwd
   if [ ! -d x-tools7h ]; then 
         echo "-> Installing Cross Compiler ARMv7"
         echo "-> Downloading Cross Compiler ARMv7"
         wget -q http://archlinuxarm.org/builder/xtools/x-tools7h.tar.xz;
         echo "-> End of Download Cross Compiler ARMv7"
         tar Jxfv x-tools7h.tar.xz
      else
         echo "Cross Compiler for ARMv7 already installed ..."
   fi
}

DownloadNodeJS()
{
   echo "-> Getting latest node.js version"
   result=$(wget -qO- http://nodejs.org/dist/latest/ | egrep -o 'node-v[0-9\.]+.tar.gz' | tail -1)
   tmp=$(echo $result | egrep -o 'node-v[0-9\.]+')
   mm=$(echo $result | egrep -o '[0-9\.]+')
   majorminor=${mm:0:${#mm} - 3} # chop 3 last chars
   version=${tmp:0:${#tmp} - 1}
   if [ ! -e $result ]; then
         echo "-> Downloading $result"
         wget -q http://nodejs.org/dist/latest/$result
         echo "-> End of Download $result"
         tar xvzf $result
         ln -s $version node
      else
         echo "You already have the latest node.js version : $version"
   fi
}

BuildNodeJSArmv5()
{
   export PATH=/home/vagrant/x-tools/arm-unknown-linux-gnueabi/bin:$PATH
   export TOOL_PREFIX="arm-unknown-linux-gnueabi"
   export CC="${TOOL_PREFIX}-gcc"
   export CXX="${TOOL_PREFIX}-g++"
   export AR="${TOOL_PREFIX}-ar"
   export RANLIB="${TOOL_PREFIX}-ranlib"
   export LINK="${CXX}"
   export CCFLAGS="-march=armv5t -mfpu=softfp -marm"
   export CXXFLAGS="-march=armv5t -mno-unaligned-access"
   export OPENSSL_armcap=5
   export GYPFLAGS="-Darmeabi=soft -Dv8_can_use_vfp_instructions=false -Dv8_can_use_unaligned_accesses=false -Darmv7=0"
   export VFP3=off
   export VFP2=off
   PREFIX_DIR="/usr"
   sudo chown -R vagrant: /home/vagrant/
   cd /home/vagrant/node
   ./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"
   make -j 2
   sudo chown -R vagrant: /home/vagrant/
   make install DESTDIR=/tmp/installARMv5
   fpm -s dir -t deb -n nodejs -v "$majorminor-1vr~squeeze1" --category web -m "Vincent RABAH <vincent.rabah@gmail.com>" --url http://nodejs.org/ \
   --description "Node.js event-based server-side javascript engine Node.js is similar in design to and influenced by systems like Ruby's Event Machine or Python's Twisted. It takes the event model a bit further - it presents the event loop as a language construct instead of as a library. Node.js is bundled with several useful libraries to handle server tasks : System, Events, Standard I/O, Modules, Timers, Child Processes, POSIX, HTTP, Multipart Parsing, TCP, DNS, Assert, Path, URL, Query Strings." \
   -C /tmp/installARMv5 -a armel  -p ../cross-compiler/nodejs_$majorminor-1vr~squeeze1_armel.deb  usr/bin usr/lib usr/include usr/share/man
   make clean
}

BuildNodeJSArmv6()
{
   export PATH=/home/vagrant/x-tools6h/arm-unknown-linux-gnueabi/bin:$PATH
   export TOOL_PREFIX="arm-unknown-linux-gnueabi"
   export CC="${TOOL_PREFIX}-gcc"
   export CXX="${TOOL_PREFIX}-g++"
   export AR="${TOOL_PREFIX}-ar"
   export RANLIB="${TOOL_PREFIX}-ranlib"
   export LINK="${CXX}"
   export CCFLAGS="-march=armv6j -mfpu=vfp -mfloat-abi=hard -DUSE_EABI_HARDFLOAT"
   export CXXFLAGS="-march=armv6j -mfpu=vfp -mfloat-abi=hard -DUSE_EABI_HARDFLOAT"
   export OPENSSL_armcap=6
   export GYPFLAGS="-Darmeabi=hard -Dv8_use_arm_eabi_hardfloat=true -Dv8_can_use_vfp3_instructions=false -Dv8_can_use_vfp2_instructions=true -Darm7=0 -Darm_vfp=vfp"
   export VFP3=off
   export VFP2=on
   PREFIX_DIR="/usr"
   sudo chown -R vagrant: /home/vagrant/
   cd /home/vagrant/node
   ./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"
   make -j 2
   sudo chown -R vagrant: /home/vagrant/
   make install DESTDIR=/tmp/installARMv6
   fpm -s dir -t deb -n nodejs -v "$majorminor-1vr~wheeze1" --category web -m "Vincent RABAH <vincent.rabah@gmail.com>" --url http://nodejs.org/ \
   --description "Node.js event-based server-side javascript engine Node.js is similar in design to and influenced by systems like Ruby's Event Machine or Python's Twisted. It takes the event model a bit further - it presents the event loop as a language construct instead of as a library. Node.js is bundled with several useful libraries to handle server tasks : System, Events, Standard I/O, Modules, Timers, Child Processes, POSIX, HTTP, Multipart Parsing, TCP, DNS, Assert, Path, URL, Query Strings." \
   -C /tmp/installARMv6 -a armhf  -p ../cross-compiler/nodejs_$majorminor-1vr~wheezy1_armhf.deb  usr/bin usr/lib usr/include usr/share/man
   make clean
}

BuildNodeJSArmv7()
{
   export PATH=/home/vagrant/x-tools7h/arm-unknown-linux-gnueabi/bin:$PATH
   export TOOL_PREFIX="arm-unknown-linux-gnueabi"
   export CC="${TOOL_PREFIX}-gcc"
   export CXX="${TOOL_PREFIX}-g++"
   export AR="${TOOL_PREFIX}-ar"
   export RANLIB="${TOOL_PREFIX}-ranlib"
   export LINK="${CXX}"
   export CCFLAGS="-march=armv7-a -mtune=cortex-a8 -mfpu=vfp -mfloat-abi=hard -DUSE_EABI_HARDFLOAT"
   export CXXFLAGS="-march=armv7-a -mtune=cortex-a8 -mfpu=vfp -mfloat-abi=hard -DUSE_EABI_HARDFLOAT"
   export OPENSSL_armcap=7
   export GYPFLAGS="-Darmeabi=hard -Dv8_use_arm_eabi_hardfloat=true -Dv8_can_use_vfp3_instructions=true -Dv8_can_use_vfp2_instructions=true -Darm7=1"  
   export VFP3=on
   export VFP2=on
   PREFIX_DIR="/usr"
   sudo chown -R vagrant: /home/vagrant/
   cd /home/vagrant/node
   ./configure --without-snapshot --without-ssl --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"
   make -j 2
   sudo chown -R vagrant: /home/vagrant/
   make install DESTDIR=/tmp/installARMv7
   fpm -s dir -t deb -n nodejs -v "$majorminor-1vr~ubuntu1" --category web -m "Vincent RABAH <vincent.rabah@gmail.com>" --url http://nodejs.org/ \
   --description "Node.js event-based server-side javascript engine Node.js is similar in design to and influenced by systems like Ruby's Event Machine or Python's Twisted. It takes the event model a bit further - it presents the event loop as a language construct instead of as a library. Node.js is bundled with several useful libraries to handle server tasks : System, Events, Standard I/O, Modules, Timers, Child Processes, POSIX, HTTP, Multipart Parsing, TCP, DNS, Assert, Path, URL, Query Strings." \
   -C /tmp/installARMv7 -a armhf  -p ../cross-compiler/nodejs_$majorminor-1vr~ubuntu1_armhf.deb  usr/bin usr/lib usr/include usr/share/man
   make clean
}

UpdateBox
DownloadNodeJS
XtoolsArmv5
BuildNodeJSArmv5
cd /home/vagrant/
PATH="$OLDPATH"
XtoolsArmv6
BuildNodeJSArmv6
#cd /home/vagrant/
#PATH="$OLDPATH"
#XtoolsArmv7
#BuildNodeJSArmv7

Node everywhere


I tested this build chain on a Ubuntu laptop, then tested Nodejs ARMv5 debian package on a Seagate DockStar, Node.js ARMv6 Raspbian package on RaspberryPI, but ARMv7 on BeagleBone don’t work yet giving me a strange error…

Feel free to download that stuff and fork me on GitHub!

February 15, 2013



blog comments powered by Disqus