6

Here's the situation, I've got a C++ codebase which is using a recent GCC (4.3.3), but I need to link against an older library which was built using GCC 3.2.3. There is no newer version of the library available, I can't go without it, and it's closed source so it can't be rebuilt.

This seems to pose a problem since there are ABI incompatibilities between GCC 4.3.3 and 3.2.3, so I'm trying to see what my options are for resolving this.

A few additional details:

  • I can rebuild everything in my codebase with -fabi-version=1 to get the correct ABI version, but I am dependent on some newer features from libstdc++ version 6.
  • All the C++ library dependencies outside the codebase are open source, so I can rebuild them as needed, except for this one library.
  • Many C library dependencies that cannot be rebuilt or would be difficult to rebuild.
  • The old library seems to be dependent on some libstdc++ version 5 features

I have so far tried:

  • Rebuild all C++ code and dependent libraries with -fabi-version=1 and link against libstdc++ version 6. This fails with a handful of undefined symbol errors for C++ standard library symbols.
  • Same as above but additionally link in the shared library for libstdc++ 5, this resolves the linker issues but appears to result in mixing of the two versions at runtime inside the legacy library, and that causes a crash.

I read this page: http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html which seems to indicate that it can be possible to mix C++ ABI versions in an application to satisfy varying dependencies between libraries. It doesn't seem to work very well here, though, unless I am missing something.

Any ideas?

Paul D.
  • 1,785
  • 2
  • 19
  • 25
  • The linker options `-Bsymbolic` and `--exclude-libs` should help you if you link the old libstdc++ statically into a shared library. – Zan Lynx May 03 '12 at 20:10

1 Answers1

4

Ok, your workaround is to:

  • write a "C" interface to the old C++ library, compile with 3.2.3 so it will work.
  • Now you can use the C interface in the new compiler.

You can write some C++ "wrapper" code around the C library so you will use it as C++ but this code will be built in the new compiler.

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • 1
    Of course, this has the disadvantage of adding a bunch of glue code, but has the advantage of working with ANY pair of C compilers/versions. – kibibu Feb 06 '12 at 15:36
  • That seems like a reasonable approach. If I create a shared library out of it, it will still have a dependency on the older libstdc++ shared library though. Will I not have the same problem? Or should I be statically linking in the older version? – Paul D. Feb 06 '12 at 16:17
  • After doing some more digging, it seems like the right thing to do is to statically link in libstdc++ from the older GCC into this shared library. However just linking against that is, I suspect, not quite enough, since you would effectively have the same issue as before with symbols being shared across the library boundary. I think you can eliminate any chance of that by doing a dlopen inside the application and using RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL. – Paul D. Feb 07 '12 at 20:23
  • It shouldn't really matter that the library itself is using stuff in the old libstdc++ as long as it has a different name (and you can always alias it if necessary so it does, but I'm pretty certain it does anyway) so you don't get LD_LIBRARY_PATH issues (or DLL-hell but on UNIX). You would only be using the C interface anyway from that library. Hopefully a relatively thin interface to just the bits you need. – CashCow Feb 07 '12 at 21:03
  • How will the symbol resolution work if you don't statically link (or if you do and don't do any handwaving when you load the library)? They do have different names, but they will have a lot of identical symbols. Would you be dependent on the load order of the two libraries? You're correct that I'll only be using a lightweight C interface between my application and this library, but I'm not sure if the application will pull libstdc++ symbols from the library or vice versa. – Paul D. Feb 07 '12 at 21:09
  • The linker options `-Bsymbolic` and `--exclude-libs` should help you if you link the old libstdc++ statically into a shared library. – Zan Lynx May 03 '12 at 20:10