I've created a shared library built with a standalone build tree using linuxbrew, which fails to load in the parent application due to dependency conflict. I'm using a separate application which dynamically loads the library after startup with the Qt5 QLibrary class.
My library is libv_repExtPluginSkeleton.so
. Both it and the parent app depend on glibc and libstdc++. All of the main app's dependencies are in /usr/lib
, while all my library's dependencies are in ~/.linuxbrew/lib
.
When the parent application goes to load the .so
failed I debugged the failure with LD_DEBUG=all "$dirname/$appname"
and found the following error report in the output:
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
As you can see, it seems that the glibc version already loaded is in /usr/lib
when my library loads, but my library needs to be loading the version in ~/.linuxbrew/lib
.
QLibrary is used to load the plugin as follows:
plug=new CPlugin(filename,pluginName);
int loadRes=plug->load();
I read in The Inside Story on Shared Libraries and Dynamic Loading that "dynamically loaded modules are completely decoupled from the underlying application", and if that can be made to work correctly I'd like to reconfigure the loading process to solve the problem.
Here are the dependency lists found by ldd, which illustrates the dependency overlaps in different locations:
+ 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
My launch script sets the first entry in LD_LIBRARY_PATH
to be ~/.linuxbrew/lib
but the application still picks up the system version first.
Also, for my own plugin library the RPATH is correct:
objdump -x libv_repExtPluginSkeleton.so |grep RPATH
RPATH /home/hbr/.linuxbrew/lib
How can I resolve this version conflict so that my library loads correctly?
Also, is this possible without changing the complete toolchain of either the parent application or my libary?