Search code examples
c++shared-librarieslibtool

Wrapping different versions of static library in dynamic libraries


In my project there is a dependency on a static library (just called libsomething from now on) from a 3rd party. Recently, libsomething has become available in another version. My task is to provide my software with support for the old and the new version. Only one version of libsomething is used at run-time at any given time, but which version this is should be configurable between program runs.

I am using MSVC2005 on WinXP, a secondary objective is to become prepared to switch over to Linux and GCC.

Since both versions of libsomething are using the same symbols, linking them both into my executable is out of the question as the symbols of both versions are going to clash all over at link-time.

While I could create two executables (one linking against the old version, the other one using the new version), I cannot implement a decision on which executable to call in the final deployment environment (legacy reasons).

I came up with the idea of creating a dynamic library wrapper for each version of libsomething and linking them at run-time depending on some config file. With MSCV, this would mean going down the road of using LoadLibrary(), GetProcAddress(), etc., while on Linux I would have to use dlopen() and dlsym().

I understand that using libtool (i.e., libtldl) is wrapping this platform-dependency for using shared libraries. Is this an appropriate path to follow? Are there better (or, at least, different) ways? Do alternatives for libtldl exist as open-source?


Solution

  • It has been few years now but I'd like to mention another solution for completeness. Instead of manual dlopen and dlsym you could generate simple stubs for all necessary functions and on first call (or at program startup) decide which library version is needed, load it and resolve the addresses.

    You could write a script specifically tailored for your project or use Implib.so tool:

    # This will generate mylib.so.init.c and mylib.so.tramp.S
    # which implement stubs. These need to be linked to your
    # executable.
    $ implib-gen.py mylib.so
    

    Implib.so is Linux-only atm but should be easily adaptable to Windows.