Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I link different versions of the same library in g++?

I'm trying to figure out how to load two different versions of libstdc++.so on a SLES10 machine. My client has a process Foo, which is built with GCC 4.1.2, and thus uses the 6.0.8 version of libstdc++.so. We are also building shared library called libBar.so. This library will be dynamically loaded by Foo at runtime. libBar.so is compiled using GCC 4.3.6, and libstdc++ version 6.0.10.

Currently, when I try to have Foo load libBar.so, I get the following error.

error: unable to load shared object '/usr/lib64/libBar.so': /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/libBar.so)

At the moment, the only way that I can get this to work is to change my library load order (via ld.so.conf) so that Foo and libbar.so both load the same (6.0.10) libstdc++.so. However, this isn't a vialbe solution, since it requires that I modify the client's system.

What I'd like to do is have Foo load it's verions of libstdc++.so and libBar.so link to it's own version of libstdc++.so, but I can't figure out how to write my Makefile to make that happen. Here's what I have so far, for my LIBADD line in Makefile.am...

libBar_la_LIBADD = ../../vendor/SLES10/lib/libstdc++.so.6.0.10

Which I would assume would like to that SPECIFIC version of libstdc++.so. However, when I run ldd against the fully compiled and linked libBar.so, this is the line I see...

libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002aaaaeac5000)

Why isn't it linking specifically to libstdc++.so.6.0.10? What should I be doing instead?

like image 577
jmartenstein Avatar asked Feb 14 '14 15:02

jmartenstein


People also ask

Can you have multiple versions of glibc?

It's possible to have installations of multiple versions of the same shared libraries on a Linux machine. The linker, during program compilation, looks for a soft link that links to a specific version of a library.

How do I link a static library?

Static libraries are created by copying all necessary library modules used in a program into the final executable image. The linker links static libraries as a last step in the compilation process. An executable is created by resolving external references, combining the library routines with program code.

How dynamic linking works?

In computing, a dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable when it is executed (at "run time"), by copying the content of libraries from persistent storage to RAM, filling jump tables and relocating pointers.

Which GCC option is used to link the library?

The -l option tells GCC to link in the specified library.


1 Answers

I had a similar issue with a 3rd-party library that used an obsolete version of libstdc++.

I solved it by pre-linking the 3rd-party library statically with that old version of libstdc++. The end result was another shared library that did not have unresolved libstdc++ symbols. The command line was something like this:

ld --relocatable -o lib3rd-party-prelinked.so lib3rd-party.so /usr/lib64/libstdc++.a.6

And then I used lib3rd-party-prelinked.so instead of lib3rd-party.so. (Lookup --relocatable in man ld).

It was possible in my case because the 3rd-party library exposed a C API, no C++ standard library components were used in its interface.

If your 3rd-party library exposes C++ standard library classes in its interface whose ABIs are different between these libstdc++ versions, that is not going to work. E.g. your application passes a std::list<> with the new ABI to the 3rd-party library that expects a std::list<> with the old ABI version. Even if it links, that will cause undefined behaviour at run-time.

like image 121
Maxim Egorushkin Avatar answered Sep 20 '22 11:09

Maxim Egorushkin