星期二, 3月 19, 2013

cross-compile node.js (0.10.0) for mipsel (Asus RT-N16 with tomatousb)

最近入手了一台 RT-N16, 馬上是刷了 tomatousb, 還算蠻滿意的, 看了那精美的記憶體, 開完機還剩下 100+ MB, 家裡的裝置也很少使用 p2p, 這些記憶體不用好像有點浪費,於是便想把一些本來跑在桌電的 node server 來跑在 rt-n16 上。
記錄一下 cross-compile 的步驟:
先從 tomatousb 抓他們的 toolchain:

$ git clone git://repo.or.cz/tomato.git tomato
$ cd tomato
$ git checkout tomatousb-K26-1.28.9054 
$ sudo ln -s tools/brcm /opt/brcm
這邊用的是 linux 2.6 的版本, 其他版本可以參考 git tag。
然後再抓 node.js 的 source: 我這邊用的是最新的 node-v0.10.0
$ mkdir $HOME/node-src && cd $HOME/node-src
$ wget http://nodejs.org/dist/v0.10.0/node-v0.10.0.tar.gz
$ tar xf node-v0.10.0.tar.gz
$ cd node-v0.10.0
設定的部分,因為是 cross-compiling, 所以把 snapshot 關掉, 因為 compile 出來的 mksnapshot 也沒辦法在 host 上跑:

$ ./configure --prefix=/opt --dest-cpu=mipsel --dest-os=linux --without-snapshot
編譯過程中會有些錯,主要是 linux 版本的問題跟 pthread 有些函數(pthread_barrier_init|destroy|wait)在 uclibc 不支援,所以我做了個 patch, 這會讓有用到 ub_barrier_init|destroy|wait 的 module 無把編譯但 node 本身似乎是沒有用到這些函數,所以暫時可以這樣做:
$ wget -O - http://moon.cse.yzu.edu.tw/~s961449/node-mipsel.patch | patch -p0
$ PREFIX=/opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/bin/mipsel-linux-
$ export CC=${PREFIX}gcc
$ export CXX=${PREFIX}g++
$ export AR=${PREFIX}ar
$ export RANLIB=${PREFIX}ranlib
$ export LINK=$CXX
$ make -j4 #4 cores
基本上這樣就可以編出能在 tomato 上跑的 node 了, 編完以後 binary 會在 out/Release/node,但是不知道為什麼 tomato 的 firmware 並沒有把一些必要的 library 包進去,所以還要再附上 librt, libstdc++ 才行(optware 用來編譯的 toolchain 不同,所以也無法使用他們的 librt), 並設定 LD_LIBRARY_PATH 才能跑: node.sh:
#!/bin/sh
LD_LIBRARY_PATH="/lib:/usr/lib:/opt/node/lib" /opt/node/bin/node $@
把檔案傳到 ap 上, 我這邊是用 optware 裝了 sftp, 所以直接用 sftp 上傳:
sftp root@your.ap.address
$ cd /opt
$ mkdir node
$ mkdir node/bin
$ mkdir node/lib
$ put out/Release/node node/bin/
$ put node.sh bin/node
$ put /opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/lib/librt.so node/lib
$ put /opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/lib/libstdc++.so node/lib/libstdc++.so.6
或是你要打包好在上傳也可以, 各人喜好啦,(因為當初是先上傳了才發現缺 lib)。 這樣應該就可以在 tomato 上跑 node 了! 但是馬上會用掉 30+% 的記憶體,也許可以再 tune 一下,但可以跑已經大喜大賀了, haha.