To take advantage of C ++ 11 and C ++ 14, I have an application compiled using a newer version of gcc (4.9.1) and therefore a newer version of libstdC ++. The application consists of many small programs, so I link to libstdC ++ as a shared library, and not to a static one (i.e. I don't want to use -static-libstdC ++)
I want to send a new version of libstdC ++ using an application in / opt // lib 64 (note that this is specifically allowed for exclusion from the GPL)
The new version of libstdC ++, therefore, differs from the version on the target platform only in a minor version. libstdC ++ is intended for forwarding so that existing programs can use the new version of the library. However, I observed subtle differences in behavior (i.e., Errors) when some programs use the new version rather than the older one. I want to prevent this.
I also found that ld will try to link my application with the system version of libstdC ++, if only I put / opt // lib 64 earlier on LD_LIBRARY_PATH. Presumably, you can force the specific version to be bound with -l:<library>.<version> , however this does not work. I suspect this will be for a user-created library, but not for a language runtime such as libstd ++, because gcc itself creates a script linker. Also on one of my target platforms (RHEL5) this is not even clear to gcc / ld. I assume this is possible with -nostdlib and binding in everything that is required (e.g. -lgcc) in my build system and not leave it on gcc, which I would prefer. I have not tried this yet.
A simple way to work around the solution is to have LD_LIBRARY_PATH contain / opt // lib 64 when the application starts, and not otherwise or equally, I could use LD_PRELOAD with the correct version of the library. The problem with this is if someone decides to ignore my advice and runs
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/<vendor>/lib64
this can lead to subtle and difficult to diagnose problems. So I was looking for a better way.
I wondered if I could somehow rename libstdC ++ as lib_stdC ++ and associate it with this sonata. Renaming libstdc ++ is not enough, since you need to change the username in the file as indicated by readelf. i.e
0x000000000000000e (SONAME) Library soname: [libstdc++.so.6]
If you do this with a regular gcc related program, even using -l:stdc++.so.6.0.20 , say that you notice this gives the main version, not the specific minor version. i.e.
readelf -d <myapp> 0x0000000e (SONAME) Library soname: [libstdc++.so.6]
but not:
0x0000000e (SONAME) Library soname: [libstdc++.so.6.0.20]
So, instead, I created a dummy shared library with the sound I want to depend on in order to add the dependency as follows:
gcc dummy.o -Wl,-soname,lib<vendor>_stdc++.so.6.0.20 -nostdlib -shared -o lib<vender>_dummycpp.so
(where dummy.o is an empty object file made from an empty source file to stop -nostdlib leading to complaints)
then
gcc <myapp> -l<vendor>_dummycpp
optionally I now get:
readelf -d <myapp> 0x0000000000000001 (NEEDED) Shared library: [lib<vendor>_stdc++.so.6.0.20]
instead
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
The dummycpp library contains all the characters in libstdc ++ because it is libstd ++, so gcc does not need to bind to soname libstdc ++ at all. I seem to have completely solved the problem.
This strikes me as a slightly hacky solution, so the questions I want to ask here are as follows:
Note: if you pack libstd ++ with a different name (for example, lib_std ++. So.6.0.20) in RPM, you will get the missing dependency on it and must be installed using --nodeps. This is because RPM scans connection time dependencies. A workaround for this is also to install a dummy library. The RPM then picks up the sonamer from the dummy library and does not claim to be missing.