Reputation: 39085
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:
myexe
links against libfoo.so.23
and libbar.so.1
libbar.so.1
itself also links against libfoo.so.23
Erroneous change:
libbar.so.1
upgrades to libfoo.so.24
without incrementing its major version numberAs 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
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