[NodeJS] Cross compile with node modules to ARM

這篇是筆記文章,由於有人問起了關於模組的問題,所以就實驗性的測試了一下,順便也翻了 node-gypnpm 這兩個東西,小小的比對了一下原始碼。

然後我發現,預設值挺討厭的。


重現錯誤

請先看一下我之前的文章,然後準備一下 Cross Compile 的環境。然後我們把 crosscompile.sh 的東西拿出來用,

export HOST=arm-bcm2708hardfp-linux-gnueabi
export CPP="${HOST}-gcc -E"
export STRIP="${HOST}-strip"
export OBJCOPY="${HOST}-objcopy"
export AR="${HOST}-ar"
export RANLIB="${HOST}-ranlib"
export LD="${HOST}-ld"
export OBJDUMP="${HOST}-objdump"
export CC="${HOST}-gcc"
export CXX="${HOST}-g++"
export NM="${HOST}-nm"
export AS="${HOST}-as"

上面這些請先執行,然後底下這些以防萬一也跑一下,

export LD="$CXX"
export LINK="$CXX"
export GYP_DEFINES="armv7=0"
export CCFLAGS='-march=armv6'
export CXXFLAGS='-march=armv6'

使用 npm install 來安裝 Native modules 會有個問題,arch 的目標是錯誤的,以我的系統來說,他會定義成 x64,在使用 npm install 的時候就會出現這樣的錯誤,

$ npm install buffertools
npm http GET https://registry.npmjs.org/buffertools
npm http 304 https://registry.npmjs.org/buffertools

> [email protected] install /home/hinablue/workspace/works/test/node_modules/buffertools
> node-gyp rebuild

make: Entering directory `/home/hinablue/workspace/works/test/node_modules/buffertools/build'
  CXX(target) Release/obj.target/buffertools/buffertools.o
  arm-bcm2708hardfp-linux-gnueabi-g++: error: unrecognized command line option '-m64'
  make: *** [Release/obj.target/buffertools/buffertools.o] Error 1
  make: Leaving directory `/home/hinablue/workspace/works/test/node_modules/buffertools/build'
  gyp ERR! build error 
  gyp ERR! stack Error: `make` failed with exit code: 2
  gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/node-gyp/lib/build.js:255:23)
  gyp ERR! stack     at ChildProcess.EventEmitter.emit (events.js:99:17)
  gyp ERR! stack     at Process._handle.onexit (child_process.js:678:10)
  gyp ERR! System Linux 3.5.0-18-generic
  gyp ERR! command "node" "/usr/local/bin/node-gyp" "rebuild"
  gyp ERR! cwd /home/hinablue/workspace/works/test/node_modules/buffertools
  gyp ERR! node -v v0.8.16
  gyp ERR! node-gyp -v v0.8.2
  gyp ERR! not ok 
  npm ERR! [email protected] install: `node-gyp rebuild`
  npm ERR! `sh "-c" "node-gyp rebuild"` failed with 1
  npm ERR! 
  npm ERR! Failed at the [email protected] install script.
  npm ERR! This is most likely a problem with the buffertools package,
  npm ERR! not with npm itself.
  npm ERR! Tell the author that this fails on your system:
  npm ERR!     node-gyp rebuild
  npm ERR! You can get their info via:
  npm ERR!     npm owner ls buffertools
  npm ERR! There is likely additional logging output above.

  npm ERR! System Linux 3.5.0-18-generic
  npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "buffertools"
  npm ERR! cwd /home/hinablue/workspace/works/test
  npm ERR! node -v v0.8.16
  npm ERR! npm -v 1.1.69
  npm ERR! code ELIFECYCLE
  npm ERR! 
  npm ERR! Additional logging details can be found in:
  npm ERR!     /home/hinablue/workspace/works/test/npm-debug.log
  npm ERR! not ok code 0

使用 node-gyp

是的,ARM 的 GCC 看不懂 -m64 的設定,所以會噴錯誤出來。那,我用 node-gyp 來做總可以吧?可以,以上面的 buffertools 為例子,請先去 github 上面把他拉下來,

git clone git://github.com/bnoordhuis/node-buffertools.git

一樣使用剛剛的環境來作 node-gyp 的動作,只是需要加上 --arch 的設定,

cd node-buffertools
node-gyp --arch arm configure build

跑完之後,請把整個 node-buffertools 搬去樹莓派上面,把他 require 進來就可以使用。什麼?沒有 node-gyp 的指令?那就安裝吧,

[sudo] npm install node-gyp [-g]

使用 NPM

到頭來還是使用 NPM 要來得方便些,首先,你需要這個步驟,

export node_config_arch=arm
export node_config_nodedir=/usr/local/node-v0.8.16

上面的 nodedir 請勿照抄!那個是你的 NodeJS 的原始碼放置位置,由於是 Native Modules 所以可能會需要,你要自己去抓下來喔!

然後,

npm install buffertools

$ npm install buffertools
npm http GET https://registry.npmjs.org/buffertools
npm http 304 https://registry.npmjs.org/buffertools

> [email protected] install /home/hinablue/workspace/works/test/node_modules/buffertools
> node-gyp rebuild

make: Entering directory `/home/hinablue/workspace/works/test/node_modules/buffertools/build'
  CXX(target) Release/obj.target/buffertools/buffertools.o

[中間省略一萬行 warning]

SOLINK_MODULE(target) Release/obj.target/buffertools.node
  COPY Release/buffertools.node
  make: Leaving directory `/home/hinablue/workspace/works/test/node_modules/buffertools/build'
  [email protected] node_modules/buffertools

打完收工!

樹莓派測試

直接附圖吧,

Test in RaspBerryPi

其中 node_modulesnode-buffertools 都是從我的 NB 做完之後,直接上傳上去的,兩種方式都可以,端看你要使用哪一種。

另外,我也測試了網友說的 node-proxy 的 NPM 安裝,

hinablue at arm-bcm2708hardfp-linux-gnueabi in ~/workspace/works/test 
$ npm install node-proxy
npm http GET https://registry.npmjs.org/node-proxy
npm http 200 https://registry.npmjs.org/node-proxy
npm http GET https://registry.npmjs.org/node-proxy/-/node-proxy-0.6.0.tgz
npm http 200 https://registry.npmjs.org/node-proxy/-/node-proxy-0.6.0.tgz

> [email protected] install /home/hinablue/workspace/works/test/node_modules/node-proxy
> node-gyp configure build

make: Entering directory `/home/hinablue/workspace/works/test/node_modules/node-proxy/build'
  CXX(target) Release/obj.target/nodeproxy/src/node-proxy.o
  ../src/node-proxy.cc: In static member function 'static v8::Handle<v8::Value> v8::NodeProxy::GetNamedProperty(v8::Local<v8::String>, const v8::AccessorInfo&)':
  ../src/node-proxy.cc:816:1: warning: control reaches end of non-void function [-Wreturn-type]
  SOLINK_MODULE(target) Release/obj.target/nodeproxy.node
  COPY Release/nodeproxy.node
  make: Leaving directory `/home/hinablue/workspace/works/test/node_modules/node-proxy/build'
  [email protected] node_modules/node-proxy

因為我不知道該怎麼測試 node-proxy,所以就讓有使用的人去測試一下吧,或者是留言告訴我怎麼做也可以。

結語

環境設定很重要(沒有誤

預設就是矯情

Hina Chen
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。
Taipei