我正在使用C中的库,我们称之为忍者。 Ninja取决于一些铺设不足的库(我们也提供)(例如jutsu,goku,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
注意:我知道使用忍者等是随机的,但我不允许发布真正的库名称
答案 0 :(得分:1)
您想要使用SONAME。描述所有必要的步骤可能是一个很好的StackOverflow答案的范围,但我可以给出一个概述并指出一些文档。
SONAME是共享库中的特殊数据字段。它通常用于表示与同一库的其他版本的兼容性;如果共享库的两个不同版本具有相同的SONAME,则链接器将知道任一个可以填充该库的依赖关系。如果他们有不同的SONAME,他们就不能。
示例:我在Debian wheezy系统上安装了libdns88
和libbind-dev
版本1:9.8.4.dfsg.P1-6+nmu2+deb7u1
。我用samurai
构建了一个名为-ldns
的二进制文件。 GNU链接器在我的库搜索路径中找到“libdns.so
”并动态链接samurai
。它从libdns.so
(这是libdns.so.88.1.1
的符号链接)读取SONAME字段。 SONAME有“libdns.so.88
”。
$ objdump -p /usr/lib/libdns.so | grep SONAME
SONAME libdns.so.88
libdns开发人员(或者可能是打包者)选择SONAME来指示任何版本的88. * libdns都应该与任何其他版本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。像dpkg-shlibdeps
这样的工具可以在使用SONAME和版本化符号时轻松创建正确的共享库包依赖项。
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html