【发布时间】:2019-01-22 03:21:50
【问题描述】:
当您使用semantic versioning 时,从libfoo.so.23 切换到libfoo.so.24 意味着libfoo 的API 以向后不兼容的方式更改。
因此,不得同时链接libfoo.so.23 和libfoo.so.24。
例子:
现状:
- 可执行的
myexe链接到libfoo.so.23和libbar.so.1 -
libbar.so.1本身也链接到libfoo.so.23
错误更改:
-
libbar.so.1升级到libfoo.so.24而不增加其主要版本号
因此,当调用 myexe 时,动态链接器现在会加载 libfoo.so.23 和 libfoo.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 中(作为错误)。
【问题讨论】:
标签: linker shared-libraries ld elf