Mar*_*tin 3 c c++ gcc arm cross-compiling
在我的程序中,我需要动态加载共享库dlopen().程序和共享库都成功交叉编译,用于ARM我的安装交叉编译器的体系结构x86.但是,每当程序尝试在运行时加载库时ARM,它都会失败,并显示以下错误:
未定义的符号:_dl_hwcap
我找不到这个错误的罪魁祸首.
让我详细说明如何libmyplugin.so构建共享库()x86.我使用g++交叉编译器如下:
/home/me/arm/gcc-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -march=armv7-a -mfloat-abi=hard -c -s -fPIC -o build/module1.o module1.cpp
/home/me/arm/gcc-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -march=armv7-a -mfloat-abi=hard -c -s -fPIC -o build/module2.o module2.cpp
/home/me/arm/gcc-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -o dist/libmyplugin.so build/module1.o build/module2.o --sysroot /home/me/arm/sysroot/ -Wl,--no-as-needed -ldl -lX11 -lXext /home/me/arm/libstatic.a -shared -s -fPIC
Run Code Online (Sandbox Code Playgroud)
请注意以下注意事项:
module1.cpp并且module2.cpp是我的源代码文件.libstatic.a是一个大型的目标.o文件存档,它实现了由module1.cppand 直接调用/引用的东西module2.cpp.这些目标文件已由其他人编译为与我相同的ARM体系结构,具有相同的编译器标志,但使用稍微更新的g++编译器(v4.9而不是我的v4.8.3).不幸的是,我无法控制这些物体的构建.--sysroot /home/me/arm/sysroot/表示我的远程文件系统,ARM OS本地g++交叉编译器在链接时可以从中获取本机库.-Wl,--no-as-needed -ldl -lX11 -lXext:X11当程序加载我的共享库时,需要这些标志来强制动态加载程序加载系统中存在的库.特别是,这--no-as-needed是必需的,因为X11库不是由module1.o和直接引用的module2.o; 相反,X11库仅由静态库引用.请注意,以上所有设置都可以使用x86.只是我不明白_dl_hwcap程序试图加载库时符号未解决的原因是什么ARM.
你知道如何调查这个问题吗?
有无数的事情可能会有问题,但这里有四条探索途径.我专注于链接行中的-shared,但最后一项也解决了这个问题.(关于共享库的一个不错的HOWTO在这里:http: //tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
a)检查环境变量LD_LIBRARY_PATH.由于您没有将RPATH用于链接器(RPATH嵌入.so的完整路径以便您可以在运行时找到它),因此链接器可以找到代码的唯一方法是搜索LD_LIBRARY_PATH.确保您想要的.so或.0在路径中.
b)使用UNIX实用程序"nm"搜索该符号的.so(共享对象)和.a文件.例如,'nm -D /usr/lib64/libpython2.6.so'将显示libpython.so中的所有动态符号,您可以查找感兴趣的符号:例如,在libpython中定义或使用'initgc' ?
% nm -D /usr/lib64/libpython2.6.so | grep initgc
000003404300cf0 T initgc
Run Code Online (Sandbox Code Playgroud)
'T'表示TEXT,或者是,它在那里定义.看看你是否可以使用grep和nm在感兴趣的模块中找到符号.('U'表示未定义,这意味着它在另一个模块中定义).
c)另一个有用的工具是'ldd'.它显示了您正在查找的库所依赖的所有动态库.例如:
% ldd /usr/lib64/libpython2.6.so
linux-vdso.so.1 => (0x00007fffa49ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00000033f0200000)
libdl.so.2 => /lib64/libdl.so.2 (0x00000033f0600000)
libutil.so.1 => /lib64/libutil.so.1 (0x00000033fea00000)
libm.so.6 => /lib64/libm.so.6 (0x00000033f0a00000)
libc.so.6 => /lib64/libc.so.6 (0x00000033efe00000)
/lib64/ld-linux-x86-64.so.2 (0x00000033efa00000)
Run Code Online (Sandbox Code Playgroud)
如果它找不到库(因为它不在LD_LIBRARY_PATH上或未在RPATH中指定),则库将变为空.
d)我看到带有-shared选项的'.a'文件的链接线有点担心.某些编译器/链接器不能使用".a"(存档)文件来创建".so"文件.'.so'文件通常必须使用-fPIC编译的其他'.so'文件或'.o'文件.
我建议(如果可以的话),重新编译/home/me/arm/libstatic.a以便它是一个.so.如果你做不到,你可能还必须将最终输出作为'.a'文件.(换句话说,摆脱-shared命令行选项).
总结:检查你的LD_LIBRARY_PATH,使用nm和ldd来查看你的.a和.so文件,但我认为最终的结果是你可能无法组合.so和.a文件.
我希望这有帮助.
| 归档时间: |
|
| 查看次数: |
11796 次 |
| 最近记录: |