Rya*_*yan 7 c++ linux shared-libraries
我使用GCC从源代码编译了英特尔TBB.它生成一个libtbb.so和littbb.so.2.看起来.so.2文件是真正的共享库,libtbb.so只包含一行文本
INPUT (libtbb.so.2)
生成这两个文件而不是一个文件的目的是什么?对于INPUT (libtbb.so.2),什么是语法?我想了解更多相关信息.
通常在构建共享对象(.so)时,您还可以通过添加后缀(例如mylib.so.2.3.1)来处理版本.要确保您的程序可以加载此lib或其他更高版本,请创建带有名称的链接
mylib.so -> mylib.so.2.3.1
mylib.so.2 -> mylib.so.2.3.1
mylib.so.2.3 -> mylib.so.2.3.1
Run Code Online (Sandbox Code Playgroud)
因此,.so之后的所有内容都代表了version.sub-version.build(或者类似).此外,同一个lib的多个版本可能与此方案共存,并且只需将程序切换为使用特定的版本是适当的链接.
动态链接的ELF二进制文件(无论是另一个库还是可执行文件)使用共享对象名称或soname来标识可执行文件在执行时应链接的库。
\n当库创建为 ELF 共享库时,编译时链接编辑器会在可执行文件中插入 DT_SONAME 字段,该库的 SONAME 会插入到库本身中。DT_SONAME 在ELF 标准中定义中定义为:
\n\n\n该元素保存以 null 结尾的字符串的字符串表偏移量,给出共享对象的名称。偏移量是记录在表中的索引
\nDT_STRTAB。有关这些名称的详细信息,请参阅下面的 \xe2\x80\x98\xe2\x80\x98Shared Object\nDependencies\xe2\x80\x99\xe2\x80\x99。
现在,当创建可执行文件时,SONAME 就会嵌入其中。当可执行文件运行时,链接器使用链接器在动态库的预定义位置的文件中查找库。Windows 中的预定义位置将是 DLL 所在的位置。在 Linux 和 Mac OS X 以及其他 System V 兼容系统中,它们将是/lib并且/usr/lib也可能是其他地方,这取决于所使用的链接器,并且可以在链接器自己的配置中定义。
在所有事件中,链接器都会查看 soname 条目中指定的库是否存在于任何这些位置,如果存在,它将使用它。
\n请注意,该标准规定 soname 是一个 STRING,版本控制约定在事后成为事实上的标准,如下所示:
\n将 soname 设置为libmyname.so.A并将库文件名设置为 libmyname.so.AB 或 libmyname.so.ABC(在 MacOSX 下为 libmyname.ABdylib)。libmyname.so.A.B[.C]?创建从到 的软链接libmyname.so.A。
A保持不变,而库的 ABI 保持不变。
B(或者B.C) 成为次要版本。
在 Linux 下,库版本与包版本号相同是很常见的。这有其优点和缺点。
\nGNU libtool 被大量用于构建动态库,并且具有更正式的版本控制系统并且具有强大的逻辑。sonames 的 libtool 版本控制系统运行良好,并被复杂的库采用以保持正常。
\n在 libtool 下,版本控制如下:
\n\n\nlibmylib-当前. 发布。年龄
\n
libtool 的想法是,随着库的发展,它们将添加和删除功能。
\n假设您正在开发一个库。首先使用版本作为0.0.0.
现在假设你修复了一些错误,你只会增加版本号。
\n因此,对于每个仅修复错误但不更改任何 ABI 的版本,新名称将是 libmylib.0.1.0 或 libmylib.0.2.0 等。
\n一路走来你说的。啊! 我可以更好地完成这个子功能,因此您添加了一组新函数来做得更好,但因为其他人仍在使用您的库,所以您仍然将旧的(已弃用的)功能保留在那里。
\n规则如下:
\n\n\n\n
\n- \n
从每个 libtool 库的 \xe2\x80\x980:0:0\xe2\x80\x99 的版本信息开始。
\n- \n
仅在软件公开发布之前更新版本信息。\n 更频繁的更新是不必要的,并且不能保证当前接口数量更快地变大。
\n- \n
如果自上次更新以来库源代码发生了根本变化,\n则增量修订版 (\xe2\x80\x98c:r:a\xe2\x80\x99 变为 \xe2\x80\x98c:r+1:a\xe2 \x80\x99)。
\n- \n
如果自上次更新以来添加、删除或更改了任何接口,请增加当前\n并将修订设置为 0。
\n- \n
如果自上次公开发布以来添加了任何接口,则增加年龄。
\n- \n
如果自上次公开发布以来已删除或更改任何接口\n,请将年龄设置为 0。
\n
您可以在中阅读更多相关信息您可以在libtool 文档
\n下面是评论说我的解释有错误。它不需要比答案评论更详细的信息,因此请参见下文。
\n\n\n这里有一个错误:在 Linux 上,版本的格式为\nlibmylib.(current-age).release.age,其中括号表示要计算的\n表达式。例如,Linux 上\ncurrent:revision:age = 37:1:1 的 GLPK 4.54 将安装库文件\nlibglpk.so.36.1.1。有关详细信息,请参阅\n<autotools.io/libtool/version.html>。
\n
虽然 Flameeyes 是一位了不起的开发人员,并且他是 Gentoo 的维护者之一,但正是他犯了错误,并创建了 libtool 规范的“经验法则”loose\xc2\xa0 解释。虽然 99% 的情况下这不会破坏系统,但如果我们遵循更新当前版本的临时方式:
\n\n\n处理这些值时的经验法则是:
\n始终增加修订值。
\n只要添加、删除或更改接口,\n就增加当前值。
\n仅当对 ABI 所做的更改\n向后兼容时才增加年龄值。
\n
然后他继续说,维护 Gtk 的多个版本最好将库版本附加到库名称中,然后简单地转储版本号。(正如他们在 GTK+ 中所做的那样):
\n\n\n在这种情况下,最好的选择是将库的部分版本信息附加到库的名称中,例如 Glib 的 libglib-2.0.so.0 soname。为此,Makefile.am 中的声明必须如下所示:
\nRun Code Online (Sandbox Code Playgroud)\nlib_LTLIBRARIES = libtest-1.0.la\n\nlibtest_1_0_la_LDFLAGS = -version-info 0:0:0\n
好吧,这只是一种破坏动态链接和符号解析版本控制功能的粗俗方法,完全没有实际意义!他说把它关掉。马鼻屎!难怪即使是经验丰富的开发人员也很难构建和维护开源项目,而且每次安装新版本的库时,我们都会不断遇到二进制文件死亡的情况(因为它们互相破坏)。
\nlibtool 版本控制方法经过深思熟虑。它是一种算法,其步骤是有序的,每次更新动态链接库的代码时都必须遵循指令1至6 。
\n对于新的和当前的开发人员,请仔细阅读它们并想象在您令人惊叹的软件的整个生命周期中库版本号会发生什么。如果您这样做,您会发现之前链接的每个软件都将始终正确使用您令人惊叹的库的最新且准确的版本,并且它们中没有一个会互相破坏或踩踏,并且您永远不必添加大量的数字以您图书馆的名义(除非是为了娱乐或美观)。
\n