防止链接共享库的多个版本

时间:2018-08-15 08:38:03

标签: linker shared-libraries ld elf

使用semantic versioning时,从libfoo.so.23libfoo.so.24的切换意味着libfoo的API以向后不兼容的方式更改了。

因此,一个人不得同时链接到libfoo.so.23libfoo.so.24

示例:

现状:

  • 针对myexelibfoo.so.23的可执行libbar.so.1链接
  • libbar.so.1本身也链接到libfoo.so.23

错误更改:

  • libbar.so.1升级到libfoo.so.24而不增加其主要版本号

结果是,当调用myexe时,动态链接器现在将装入libfoo.so.23libfoo.so.24(参见ldd输出),从而使用向后的一组功能-来自libfoo的不兼容符号。

如何防止此类错误?

这意味着:在这种情况下(在构建时和运行时),如何告诉链接器出错?

在Linux上,链接器只是在构建时发出警告:

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

是否有可能将其变成链接错误?

(此警告不会在运行时显示。)

其他Unices上的其他链接程序甚至在构建时都不会对此发出警告。

可以通过在库加载期间执行的构造函数在运行时检测到这样的库版本不匹配。例如:

#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);
  }
}

但是我更喜欢在构建时/运行时出现链接器错误。理想情况下,某些东西也会显示在ldd中(作为错误)。

1 个答案:

答案 0 :(得分:1)

  

是否有可能将其变成链接错误?

GNU ld和Gold have

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