【发布时间】:2016-01-30 03:58:59
【问题描述】:
我使用 linuxbrew 创建了一个使用独立构建树构建的共享库,由于依赖冲突,它无法加载到父应用程序中。我正在使用一个单独的应用程序,它在使用 Qt5 QLibrary 类启动后动态加载库。
我的图书馆是libv_repExtPluginSkeleton.so。它和父应用程序都依赖于 glibc 和 libstdc++。所有主应用程序的依赖项都在/usr/lib 中,而我所有库的依赖项都在~/.linuxbrew/lib 中。
当父应用程序去加载.so失败时,我用LD_DEBUG=all "$dirname/$appname"调试失败并在输出中发现以下错误报告:
2610: file=/home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]; dynamically loaded by libQt5Core.so.5 [0]
2610: file=/home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]; generating link map
2610: dynamic: 0x00007fd063cff570 base: 0x00007fd063ae7000 size: 0x000000000021a6a8
2610: entry: 0x00007fd063af1150 phdr: 0x00007fd063ae7040 phnum: 5
2610:
2610: checking for version `GCC_3.0' in file /lib/x86_64-linux-gnu/libgcc_s.so.1 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: checking for version `GLIBC_2.14' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: checking for version `GLIBC_2.2.5' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: checking for version `CXXABI_1.3' in file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: checking for version `GLIBCXX_3.4.9' in file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: checking for version `GLIBCXX_3.4.21' in file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] required by file /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]
2610: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: error: version lookup error: version `GLIBCXX_3.4.21' not found (required by /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so) (fatal)
2610:
2610: file=/home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so [0]; destroying link map
如您所见,当我的库加载时,似乎已经加载的glibc版本在/usr/lib,但我的库需要加载~/.linuxbrew/lib中的版本。
QLibrary 用于加载插件如下:
plug=new CPlugin(filename,pluginName);
int loadRes=plug->load();
我在The Inside Story on Shared Libraries and Dynamic Loading 中读到“动态加载的模块与底层应用程序完全解耦”,如果可以正常工作,我想重新配置加载过程来解决问题。
这里是ldd找到的依赖列表,说明了不同位置的依赖重叠:
+ ldd /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/libv_repExtPluginSkeleton.so
linux-vdso.so.1 (0x00007fffc17af000)
libstdc++.so.6 => /home/hbr/.linuxbrew/lib/libstdc++.so.6 (0x00007ff5b9a32000)
libm.so.6 => /home/hbr/.linuxbrew/lib/libm.so.6 (0x00007ff5b9742000)
libgcc_s.so.1 => /home/hbr/.linuxbrew/lib/libgcc_s.so.1 (0x00007ff5b9531000)
libc.so.6 => /home/hbr/.linuxbrew/lib/libc.so.6 (0x00007ff5b91b9000)
/home/hbr/.linuxbrew/Cellar/glibc/2.19/lib64/ld-linux-x86-64.so.2 (0x00007ff5b9f81000)
+ ldd /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/vrep
linux-vdso.so.1 => (0x00007ffc333f9000)
liblua5.1.so (0x00007fc10e763000)
libQt5Core.so.5 (0x00007fc10df28000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc10dd0a000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc10da06000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc10d7f0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc10d42b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc10d125000)
libicui18n.so.54 (0x00007fc10ccb7000)
libicuuc.so.54 (0x00007fc10c909000)
libicudata.so.54 (0x00007fc10aedf000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc10acdb000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007fc10aad9000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc10a8d1000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fc10a5c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc10e66d000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fc10a38b000)
+ LD_DEBUG=all /home/hbr/V-REP_PRO_EDU_V3_2_2_64_Linux/vrep
我的启动脚本将LD_LIBRARY_PATH 中的第一个条目设置为~/.linuxbrew/lib,但应用程序仍然首先获取系统版本。
另外,对于我自己的插件库,RPATH 是正确的:
objdump -x libv_repExtPluginSkeleton.so |grep RPATH
RPATH /home/hbr/.linuxbrew/lib
如何解决此版本冲突,以便我的库正确加载?
另外,这是否可以在不更改父应用程序或我的库的完整工具链的情况下实现?
【问题讨论】:
-
我建议你使用系统库重建你的库。
-
@Anon Mail 我很感激你的建议,如果它工作得很好,我会这样做,但我不能保证给定的平台会支持我需要的依赖版本。
-
你能构建你的库,让它静态链接它的依赖库吗?
-
您是否尝试设置
LIBRARY_PATH?有关说明,请参见此处:stackoverflow.com/a/13292386/4181011
标签: c++ linux dependencies shared-libraries dynamic-loading