我试图在我的Ubuntu 14.04桌面x64上为我的QNAP armv5te机器交叉编译Node。
QNAP应用中心存在一个Node QPKG,但其版本已经过时(0.8.22)。
下面是有关服务器的信息:
Linux SERVERNAME 3.4.6 #1 Mon Dec 29 06:00:47 CST 2014 armv5tel unknown
处理器名称:Feroceon 88F6281 rev 1 (v5l) @ 1.2 GHz
BogoMIPS:1196.85
特征:swp half thumb fastmult edsp
CPU实现者:0x56
CPU架构:5TE
CPU变体:0x2
CPU部件:0x131
CPU修订版本:1
硬件:Feroceon-KW
ARM修订版本:0000
串行号:0000000000000000
这是我在桌面上使用的命令:
apt-get update
apt-get upgrade
apt-get install emdebian-archive-keyring
apt-get install libc6-armel-cross libc6-dev-armel-cross
apt-get install binutils-arm-linux-gnueabi
apt-get install gcc-4.7-arm-linux-gnueabi
apt-get install g++-4.7-arm-linux-gnueabi
apt-get install u-boot-tools
apt-get install libncurses5-dev
ln -s /user/bin/arm-linux-gnueabi-gcc-4.7 /usr/bin/arm-linux-gnueabi-gcc
ln -s /user/bin/arm-linux-gnueabi-g++-4.7 /usr/bin/arm-linux-gnueabi-g++
wget http://nodejs.org/dist/node-v0.10.35/node-v0.10.35.tar.gz
tar -zxf node-v0.10.35.tar.gz
cd node-v0.10.35
export TOOL_PREFIX="arm-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=armv5te -mfpu=softfp -marm"
export CXXFLAGS="-march=armv5te -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
./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="/root/.nvm/v0.10.35"
make -j 4
make install
tar -zcf node-v0.10.35-linux-armv5.tar.gz v0.10.35
编译过程没有显示任何失败信息,所以我把tarball发送到我的QNAP服务器:
scp /root/.nvm/node-v0.10.35-linux-armv5.tar.gz admin@SERVERNAME:/share/HDA_DATA/.qpkg/nodejs
ssh SERVERNAME -l admin
cd /share/HDA_DATA/.qpkg/nodejs
tar -zxf node-v0.10.35-linux-armv5.tar.gz
ln -s v0.10.35 node
我的服务器上已经设置好了所有的环境变量。现在我可以测试node二进制文件...
# node -v
node: /usr/lib/libstdc++.so.6: version `CXXABI_ARM_1.3.3' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.15' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.11' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.7' not found (required by node)
最后我遇到了一个错误,因为Ubuntu和Qnap上的C库不同,对于Ubuntu桌面,我有
ldd (Ubuntu EGLIBC 2.19-0ubuntu6.5) 2.19
,而在QNAP上是ldd (GNU libc) 2.5
。
libc-dev和libstdc++是由Optware ipkg处理的软件包,也是旧版本。
我的问题是,修复这个问题的更好方法是什么?强制更新服务器上的库?(如何操作?)还是在编译时使用静态库?(如何操作?)还是其他选项?
编辑:
和artless-noise的交谈后,我明白了解决库依赖性的几种方法...
涉及到的依赖项:
# ldd /opt/bin/node
/opt/node/bin/node: /usr/lib/libstdc++.so.6: version `CXXABI_ARM_1.3.3' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.15' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.11' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.7' not found (required by /opt/node/bin/node)
libdl.so.2 => /lib/libdl.so.2 (0xb6ed2000)
librt.so.1 => /lib/librt.so.1 (0xb6ec3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb6de2000)
libm.so.6 => /lib/libm.so.6 (0xb6d32000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb6d1e000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb6cfe000)
libc.so.6 => /lib/libc.so.6 (0xb6bca000)
/lib/ld-linux.so.3 (0xb6ee4000)
将Ubuntu GCC的库复制到目标机器,并覆盖默认库:
这可能非常危险,可能会使系统砖化。而且,我的目标是为QNAP社区创建一个QPKG,所以要求人们覆盖他们的C libs并不是一种很好的方法。复制库并与原始库共存:
这是一种不错的方法,只需要将LD_LIBRARY_PATH
设置为包含应用程序最新库的目录即可。但是我发现使用此方法时出现了一个错误,再次涉及c++ lib。
错误信息:
node: symbol lookup error: /opt/node/lib/c/libstdc++.so.6: undefined symbol: _ZNSt11__timepunctIcE2idE, version GLIBCXX_3.4
- 创建静态应用程序:
最终,我找到了一种方法,在编译过程中和在目标机器上执行时都没有出现任何错误。只需要添加一些标志即可。
新的标志:
export CCFLAGS="-march=armv5te -mfpu=softfp -marm -static-libgcc"
export CXXFLAGS="-march=armv5te -mno-unaligned-access -static-libstdc++"
export LDFLAGS="-static"
检查动态库链接:
# ldd /opt/bin/node
not a dynamic executable
# npm version
{ test: '1.0.0',
npm: '2.3.0',
ares: '1.9.0-DEV',
http_parser: '1.0',
modules: '11',
node: '0.10.35',
openssl: '1.0.1j',
uv: '0.10.30',
v8: '3.14.5.9',
zlib: '1.2.8' }
编辑:最终又出现了一个问题,大部分节点函数可以正常工作,但是http
不能...
我测试了一个简单的脚本(来自NodeJS API),用于获取有关网页的信息:
http.get("http://www.google.com/index.html", function(res) {
console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
我收到了Got error: getaddrinfo ENOTFOUND
的错误信息,这是因为node是静态的,有些功能可能无法正常工作吗?
mv /lib/libc-2.5.so /share/Public/libc-2.5.so.backup
来知道是否可以在没有此库的情况下使用服务器,但是所有连接都失败了(ftp、http、ssh、telnet...)我不得不重新启动服务器,并重新安装了库。我的目标是为社区创建一个更新的QPKG,因此使用静态库可能会更有用,不是吗? - jbltxnode -v
可以完美地工作。现在真正覆盖是否存在任何风险? - jbltx