多版本库,如何使用GCC/g++;删去版本号

多版本库,如何使用GCC/g++;删去版本号,gcc,g++,rpm,deb,Gcc,G++,Rpm,Deb,我正在用C编写一个库,让我们称之为忍者。 忍者依赖于一些地下图书馆(我们也提供这些图书馆)(例如巨子、小悟空、bla)。 这些都放在共享库文件夹中,比如说/usr/lib/secret/。 使用该项目的客户希望能够将忍者版本1和2并排放置,这并不难。问题是当忍者1依赖于例如jutsu 1和忍者2依赖于jutsu 3时。这是怎么回事。。。我们/我这样做是为了在从我们的软件包存储库安装ninja时。它知道jutsu的正确版本。当然,rpm/deb包应该取决于jutsu包的正确版本 所以我们想要的是,

我正在用C编写一个库,让我们称之为忍者。 忍者依赖于一些地下图书馆(我们也提供这些图书馆)(例如巨子、小悟空、bla)。 这些都放在共享库文件夹中,比如说/usr/lib/secret/。 使用该项目的客户希望能够将忍者版本1和2并排放置,这并不难。问题是当忍者1依赖于例如jutsu 1和忍者2依赖于jutsu 3时。这是怎么回事。。。我们/我这样做是为了在从我们的软件包存储库安装ninja时。它知道jutsu的正确版本。当然,rpm/deb包应该取决于jutsu包的正确版本

所以我们想要的是,我们在什么时候执行,比如《忍者》中的zypper。它在系统上安装和编译,它知道在没有给出版本号的情况下取出哪个jutsu库

因此,我们在make文件中不必这样做:

gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu_2
但只是

gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu

注意:我知道使用忍者等等是随机的,但我不允许发布真正的库名

你想使用SONAME。描述所有必要的步骤对于一个好的StackOverflow答案来说可能范围太大,但是我可以给出一个概述并指出一些文档

SONAME是共享库中的一个特殊数据字段。它通常用于表示与同一库的其他版本的兼容性;如果共享库的两个不同版本具有相同的SONAME,那么链接器将知道其中任何一个都可以填充对该库的依赖关系。如果他们有不同的奏鸣曲,他们就不能

示例:我在Debian喘息系统上安装了
libdns88
libbind dev
版本
1:9.8.4.dfsg.P1-6+nmu2+deb7u1
。我用
-ldns
构建了一个名为
samurai
的二进制文件。GNU链接器在我的库搜索路径中找到“
libdns.so
”,并与之动态链接
samurai
。它从
libdns.so
读取SONAME字段(这是指向
libdns.so.88.1.1
)的符号链接)。那里的SONAME是“
libdns.so.88

libdns开发人员(或者可能是打包人员)选择该SONAME来表示libdns的任何版本88.*都应该与任何其他版本88.*二进制兼容。他们对所有具有兼容ABI的版本使用相同的SONAME。当ABI发生变化时,他们将SONAME更改为
libdns.so.89
,依此类推。(大多数管理良好的库不会经常更改其ABI。)

因此,写入
samurai
二进制文件的库依赖项就是
libdns.So.88
。当我稍后运行
samurai
时,动态链接器/加载程序将查找名为“
libdns.so.88
”的文件,而不仅仅是“
libdns.so

按照惯例,当库的SONAME包含更改时,rpm或deb包的名称也应该更改。这就是为什么有一个
libdns88
包与
libdns100
包分开,它们可以并排安装,而不会相互干扰。我的
samurai
包将依赖于“
libdns88
”,我可以预期任何名为
libdns88
的包都将具有与我构建它所依据的ABI兼容的ABI。当使用SONAMEs和版本化符号时,像
dpkg shlibdeps
这样的工具使创建正确的共享库包依赖项变得简单

$ objdump -p /usr/lib/libdns.so | grep SONAME
  SONAME               libdns.so.88