如你所见,流行的脚本语言如 Python, Lua 都被各路大神移植到了 Kindle 上, 为什么 JavaScript/Node.js 不可以呢?经过一番搜索后我发现,这方面的研究鲜有人进行过,只找到了寥寥几篇老外写的文章,而且年代都十分久远,几乎没有参考价值. Node.js 主页虽然提供了 ARM 架构的预编译二进制包下载,但都只适用于支持硬浮点的设备,不能用于 Kindle. 好吧,那就自己动手,丰衣足食.
我的设备是 Kindle 8 (中亚 558 那款).本文提到的方法应该也适用于其他型号.
首先你应该将你的 Kindle 越狱,并安装 KUAL 和 kterm, 后者是 Kindle 上的虚拟终端.这部分内容本文不作介绍.
接下来是交叉编译.如果你嫌麻烦,可以下载我提供的编译好的二进制包: https://mega.nz/#!VggDTbAI!YSG4-Bwo0tMUmT4txCfxyNZOoqxgvjuoUH7KfigDkTA. 阉割了一些特性(后文会提到).不过我还是推荐你自己编译.
安装好评如潮的 CodeSourcery 交叉编译工具链.去官网下太麻烦,这里有一份百度网盘的链接, GCC 版本为 4.8.3. 下载后解压,假定你把它放在了 /opt/mentor/arm-2014.05
目录中.
然后从 Node.js 主页下载源代码,推荐 7.0 以上版本,因为可以在编译时显式指定为交叉编译.我用的是 v7.9.0. 解压备用.
此时我建议你新建一个 screen 会话.然后需要设置大量的环境变量,将以下内容保存为 Shell 脚本并执行:
#!/bin/sh -e #Define our target device export TARGET_ARCH="-march=armv7-a" export TARGET_TUNE="-mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -mthumb-interwork" #Define the cross compilators on your system export AR_target="arm-none-linux-gnueabi-ar" export CC_target="arm-none-linux-gnueabi-gcc" export CXX_target="arm-none-linux-gnueabi-g++" export LINK_target="arm-none-linux-gnueabi-g++" export CPP="arm-none-linux-gnueabi-gcc -E" export LD="arm-none-linux-gnueabi-ld" export AS="arm-none-linux-gnueabi-as" export CCLD="arm-none-linux-gnueabi-gcc ${TARGET_ARCH} ${TARGET_TUNE}" export NM="arm-none-linux-gnueabi-nm" export STRIP="arm-none-linux-gnueabi-strip" export OBJCOPY="arm-none-linux-gnueabi-objcopy" export RANLIB="arm-none-linux-gnueabi-ranlib" export F77="arm-none-linux-gnueabi-g77 ${TARGET_ARCH} ${TARGET_TUNE}" unset LIBC #Define flags export CXXFLAGS="-march=armv7-a" export LDFLAGS="-L${CSTOOLS_LIB} -Wl,-rpath-link,${CSTOOLS_LIB} -Wl,-O1 -Wl,--hash-style=gnu" export CFLAGS="-isystem${CSTOOLS_INC} -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3" export CPPFLAGS="-isystem${CSTOOLS_INC}" export CCFLAGS="-march=armv7-a" #Tools export CSTOOLS=/opt/mentor/arm-2014.05 export CSTOOLS_INC=${CSTOOLS}/include export CSTOOLS_LIB=${CSTOOLS}/lib export ARM_TARGET_LIB=$CSTOOLS_LIB export GYP_DEFINES="armv7=1" #Define other things, those are not 'must' to have defined but we added export SHELL="/bin/bash" export TERM="screen" export LANG="en_US.UTF-8" export MAKE="make" #Export the path for your system export HOME="/root" #Change this one with the name of your user directory export PATH="${CSTOOLS}/bin:/opt/mentor/arm-2014.05:${HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" bash --norc
(某些路径请根据你的实际情况修改)
顺便一提. Kindle 8 使用的 CPU(SoC) 是 Freescale i.MX6 SoloLite. 这颗处理器使用 ARMv7 指令集, Cortex-A9 架构,不支持硬浮点.可以在 Kindle 上执行 cat /proc/cpuinfo
查看它的详细信息.
上述 Shell 脚本执行后会进入一个新的 Bash 会话中.把工作目录切换到 Node.js 源代码所在目录,准备编译.
执行:
./configure --without-snapshot --without-inspector --without-intl --dest-cpu=arm --dest-os=linux --cross-compiling --with-arm-float-abi=soft --with-arm-fpu=neon
(推荐加上 --prefix
选项.我当时没加,结果编译好的可执行文件跟其他文件杂糅在一起,得手动去删,幸好我的 /usr/local
还算干净.另外,如果不想复制一大堆东西,也可以加上 --fully-static
选项)
以上命令会使得编译好后的 Node.js 没有 Snapshot, Inspector 和 Intl 三个特性,因为这三个特性会造成编译失败.给强迫症的特别提示:这三个特性用得并不多.
然后执行:
make
好了,没你的事了,慢慢等吧. 使用 make -j2
,在我的 VPS 上花了十多分钟.编译出来的可执行文件是这个样子:
然后 make install
,去你指定的目录把生成的那堆东西复制出来,传到 Kindle 里.假定你把它放到了 /mnt/us/node
下.将 /mnt/us/node/bin
添加到 $PATH
中(或者,你也可以把 node
和 npm
两个可执行文件链接到 /usr/local/bin
目录下),然后执行:
node
看到 Node.js 的提示符没? That's fucking cool!
另外,NPM 有点小问题,勉强能用.
说下 Kindle 怎么改 $PATH
.方法比较蛋疼(因为 kterm 终端不会自动载入一些 Bash 配置文件).安装 USBNetwork 越狱插件并 SSH 连接到 Kindle,然后执行 mntroot rw
挂载读写.修改 /etc/profile
,把第 5 行改为
export PATH=/usr/local/bin:/bin:/usr/bin:/usr/sbin:/sbin:/mnt/us/node/bin
以后,每次在 Kindle 上运行 Node.js 前,先执行 source /etc/profile
,再执行 node
.
就是这样,奇妙的玩具语言 JavaScript 又攻占了一种设备.毕竟,
JavaScript is the new C.
实话实说,这是我第一次成功的交叉编译,实在是太不容易了.昨晚熬到很晚,今天又几乎花了整整一天时间,超级累.这里面的坑实在是不计其数.关于 ARM 平台上的 Node.js 的文章倒不少,但基本上都是关于 RPi 和 Android 两大平台的,很多时候只能参考为 Android 编译 Node.js 的资料,很蛋疼.所以,希望这篇文章能够帮到你(不过,应该没人像我一样在非主流的 Kindle 上玩 Node 吧)
对了,我为什么要如此蛋疼地把 Node.js 移植到 Kindle 上呢?一是因为我最近正在 Kindle 上读一些 Node.js 方面的书,如果能够直接在 Kindle 上写代码当然是最棒的;至于二呢,我最近准备搞个大新闻,敬请期待哦~
以上.
Update:
这就是我搞的大新闻: Kindle 竟也可以播放 Bad Apple?!
One thought on “在 Kindle 电子书上部署 Node.js 运行环境”