maxschlepzig
maxschlepzig

Reputation: 39085

Protect against linking multiple versions of a shared library

When you use semantic versioning, a switch from libfoo.so.23 to libfoo.so.24 means that libfoo's API changed in an backwards-incompatible way.

Thus, one must not link against both libfoo.so.23 and libfoo.so.24.

Example:

Status quo:

Erroneous change:

As a result, when myexe is invoked the dynamic linker now loads libfoo.so.23 and libfoo.so.24 (cf. ldd output) leading to one set of functions using backwards-incompatible symbols from libfoo.

How to protect against such an error?

That means: how do I tell the linker to error out in such a situation (at build-time and runtime)?

On Linux, the linker just warns about this at build time:

/usr/bin/ld: warning: libfoo.so.24, needed by libbar.so.1, 
    may conflict with libfoo.so.23

Is it possible to turn this into an link error?

(This warning doesn't show up at runtime.)

Other linkers on other Unices don't even warn about this at build-time.

It's possible to detect such a library version mismatch at runtime with a constructor function that is executed during library loading. For example:

#include <stdio.h>
#include <stdlib.h>

#define FOO_VERSION 23    
int foo_version() { return FOO_VERSION; }

static void cons() __attribute__((constructor));
static void cons()
{
  fprintf(stderr, "constructing foo (%d)\n", foo_version());
  if (foo_version() != FOO_VERSION) {
    fprintf(stderr, "foo.c: FOO_VERSION %d != foo_version() %d\n",
        FOO_VERSION, foo_version());
    exit(1);
  }
}

But I would prefer a linker error at build-time/runtime. Ideally something that also shows up in ldd (as an error).

Upvotes: 2

Views: 174

Answers (1)

Employed Russian
Employed Russian

Reputation: 213646

Is it possible to turn this into an link error?

GNU ld and Gold have:

   --fatal-warnings
   --no-fatal-warnings
       Treat all warnings as errors.  The default behaviour can be
       restored with the option --no-fatal-warnings.

Upvotes: 1

Related Questions