I want to use gcc 4.8.1 for my application (requires libstdc++.so.6.0.18), however customers only have libstdc++.so.6.0.13. I have been using -static-libgcc -static-stdlibc++
for a while now, but my application consists of several dynamically linked libraries and one main application. This means that when compiling each dynamic library, they must statically compile the standard library, which is redundant and wasteful. I want to just ship the standard library of my choice with my product, however every time I run my application in an environment like theirs, it always loads the wrong standard library. It prefers the /usr/lib64/
version no matter what I seem to do (it seems to take precedence over LD_LIBRARY_PATH
).
Constraints:
I'm not allowed to force them to upgrade to a new standard library.
I don't want to make the dynamic libraries static. (I'd be able to statically compile everything into the main app once, but there are some logistical barriers that prevent me from recompiling some libraries into static ones).
-Wl,-rpath=$(path_to_directory)
is a bit dangerous, however it is legal because the customers do source some settings that allow me to set path variables. However, setting the rpath of my new stdlibc++ doesn't seem to be overriding the default /usr/lib64
version. I still get GLIBCXX
errors because it won't use the right library.
Surely there is an elegant solution for this?
Perhaps there is just an error in my procedure. Here's an example (sorry about the censor, but it's just username stuff):
~/example$ pwd
/home/username/example
~/example$ echo $LD_LIBRARY_PATH
~/example$ ls
Makefile libstdc++.so.6.0.18 test.cpp
~/example$ make
g++ -std=c++11 -Wall -Werror test.cpp -o test
~/example$ ldd test
./test: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test)
linux-vdso.so.1 => (0x00007fffe5919000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000390b800000)
libm.so.6 => /lib64/libm.so.6 (0x0000003904800000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000390b400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003904400000)
/lib64/ld-linux-x86-64.so.2 (0x0000003904000000)
~/example$ setenv LD_LIBRARY_PATH /home/username/example
~/example$ echo $LD_LIBRARY_PATH
/home/username/example
~/example$ ldd test
./test: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test)
linux-vdso.so.1 => (0x00007fff2d3ff000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000390b800000)
libm.so.6 => /lib64/libm.so.6 (0x0000003904800000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000390b400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003904400000)
/lib64/ld-linux-x86-64.so.2 (0x0000003904000000)
Sorry guys, I made a rather dumb mistake...
~/example$ file libstdc++.so.6.0.18
libstdc++.so.6.0.18: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
Some dweeb built the wrong version of the library, and another dweeb (namely myself) tried using it on a 64-bit machine. Using LD_LIBRARY_PATH
was working all along...
Your problem is that the executable is linked to the soname libstdc++.so.6
not to the full library filename libstdc++.so.6.0.16
. The dynamic linker will look for libstdc++.so.6
in the usual places (i.e. LD_LIBRARY_PATH, DT_RPATH, ldconfig dirs etc.) so to ensure the 6.0.18 version is found you need a symlink called libstdc++.so.6
pointing to it.
Instead of using LD_LIBRARY_PATH (which is fragile on machines you don't control, because users might alter their environment) I prefer linking with '-Wl,-rpath,$ORIGIN'
(N.B. the quotes are necessary to stop the shell expanding $ORIGIN
)
An RPATH of $ORIGIN
tells the dynamic linker to start looking for shared libraries in the same directory as the executable, so if you ship libstdc++.so alongside your executable it will be found. If you want to ship the executable in a bin
directory and have the library in a lib
directory you can use '-Wl,-rpath,$ORIGIN/../lib'
or other paths relative to the location of the executable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With