C 基于armv5交叉编译节点的库兼容性
我尝试在我的Ubuntu14.04桌面x64上为我的QNAP armv5te机器交叉编译 QNAP应用程序中心中存在节点QPKG,但其版本较旧(0.8.22)。C 基于armv5交叉编译节点的库兼容性,c,node.js,arm,cross-compiling,C,Node.js,Arm,Cross Compiling,我尝试在我的Ubuntu14.04桌面x64上为我的QNAP armv5te机器交叉编译 QNAP应用程序中心中存在节点QPKG,但其版本较旧(0.8.22)。 以下是有关服务器的信息: Linux SERVERNAME 3.4.6#1 Mon Dec 29 06:00:47 CST 2014 armv5tel未知 处理器名称:Feroceon 88F6281版本1(v5l)@1.2 GHz BogoMIPS:1196.85 功能:swp半拇指快速多路edsp CPU实现者:0x56 CPU架构
以下是有关服务器的信息: Linux SERVERNAME 3.4.6#1 Mon Dec 29 06:00:47 CST 2014 armv5tel未知
处理器名称:Feroceon 88F6281版本1(v5l)@1.2 GHz
BogoMIPS:1196.85
功能:swp半拇指快速多路edsp
CPU实现者:0x56
CPU架构:5TE
CPU变量:0x2
CPU部分:0x131
CPU版本:1
硬件:Feroceon千瓦
手臂修订版: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 -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
和Qnapldd(GNU libc)2.5
libc-dev和libstdc++是由Optware-ipkg在Qnap上处理的包(也是旧版本)
我的问题是,解决这个问题的更好方法是什么?在服务器上强制更新libs?(以及如何做到这一点?)或者在编译过程中使用静态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' }
在我与天真的噪音交谈之后,我明白我有几种方法来修复库依赖性
相关依赖项:
# 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)
- 将ubuntugcc中的库复制到目标机器上,并覆盖默认库:
这可能真的很危险,可能会破坏系统。更重要的是,我的目标是为QNAP社区创建一个QPKG,所以要求人们重写他们的C库并不是一个很好的方法 - 复制库并与原始库共存:
一个不错的方法,只需将
设置为包含应用程序最新libs的dir。但是我发现了一个使用这个方法的错误,再次是用C++ LIB。LD\u LIBRARY\u PATH
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' }
- 创建静态应用程序:
最后,我找到了在编译期间和在目标机器上执行期间不出现任何错误的方法。只需要添加一些标志
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' }
检查动态库链接:
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);
});
我得到了错误:getaddrinfo ENOTFOUND,是否可能是因为节点是静态的一些功能无法工作?最后,我没有尝试更改库,而是决定使用一个更好的交叉编译器,它与我的目标完全匹配
我用了,但我也可以用官方的(我看得太晚了…)
但问题总是在这里,有一个node dependecy(),它使用一个名为的库,该库从4.4.X版开始引入GCC。下面是我为解决这个问题而做的变通方法:
cd /src
wget -q https://ftp.gnu.org/gnu/gcc/gcc-4.6.3/gcc-core-4.6.3.tar.gz
tar -zxf gcc-core-4.6.3.tar.gz
sed -i -e 's/define HIDDEN.*/define HIDDEN/' /src/gcc-4.6.3/gcc/config/arm/linux-atomic.c
export CC=arm-none-linux-gnueabi-gcc
export AR=arm-none-linux-gnueabi-ar
export RANLIB=arm-none-linux-gnueabi-ranlib
cd /src/gcc-4.6.3/gcc/config/arm
libtool --tag=CC --mode=compile $CC -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.c
$AR cru /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a /src/gcc-4.6.3/gcc/config/arm/.libs/linux-atomic.o
$RANLIB /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a
# IMPORTANT: Assign environment variables like I made in my question above.
# Go to node src dir and configure
./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"
# When configuration is done, edit out/node.target.mk
vi out/node.target.mk
# Find LD_INPUTS files list and add your new library as last one:
# -> /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a
# Now you can build node !
make -j4 #-jX where X is the number of available cores
make install DESTDIR=$TEMPDIR # Use DESTDIR to avoid installation directly in $PREFIX_DIR path
通过这种配置,我还可以使用GCC4.1.3为x86处理器编译节点。我为那些不想自己编译的QNAP用户制作了QPKG:@artless noise正如你所说,我认为更换库可能会导致整个系统失败,昨天我尝试了mv/lib/libc-2.5.so/share/Public/libc-2.5.so.backup
以了解我是否可以在没有这个库的情况下使用服务器,并且都失败了,没有任何连接(ftp、http、ssh、telnet…)我不得不重新启动服务器,固件重新安装了库。我的目标是为社区制作一个最新的QPKG,所以使用静态库可能会更有用。没有?应该有链接。例如,目前您有“/lib/libc.so.6->libc-2.5.so”。将此更改为“/lib/libc.so.6->libc-2.19.so”。二进制文件应该引用链接a不是物理的“共享库”。我会在chroot
系统中进行实验,或者你可以用砖块填充你的设备(或者至少你不需要重新刷新)。谢谢你天真的噪音,我把chroot变成了监狱,如果我重写的话,node-v
工作得很好。现在真的重写有风险吗?理论上2.xx版本应该是向后兼容的。我会测试链接到2.5的现有二进制文件(同时复制到chroot
)看看2.19的符号链接是否运行良好。我不确定你这样做是为了你自己还是为了别人?我很确定这很好,但我不能保证。在设备上使用RAM比在内存中使用两个副本有好处。这个问题可能会让你感兴趣?如果你愿意,你可以测试一下,这是答案。我知道ow V8 Snapshot在arm机器上无法正常工作,我已经将我的构建配置为不使用它。我对我的固件有疑问,我认为在服务器重新启动后会清理lib目录,这可能吗?我担心每次重新启动时都会手动更换libs。。。