我使用GCC从源代码编译了英特尔TBB。它生成一个libtbb.so和littbb.so.2。看起来.so.2文件是真正的共享库,libtbb.so只包含一行文本
INPUT (libtbb.so.2)
生成这两个文件而不是一个文件的目的是什么?对于INPUT (libtbb.so.2)
,语法是什么?我想了解更多信息。
答案 0 :(得分:5)
通常在构建共享对象(.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
所以,.so之后的所有内容都代表了version.sub-version.build(或者类似的) 此外,同一个lib的多个版本可以与此方案共存,并且将程序切换为使用特定版本所需的全部内容就是拥有适当的链接。
答案 1 :(得分:3)
动态链接ELF二进制文件(无论是另一个库还是可执行文件)使用shared-object name or soname来标识可执行文件应在执行时链接的库。
当一个库作为ELF共享库创建时,编译时链接编辑器会在可执行文件中插入一个DT_SONAME字段,该库将SONAME放入库本身。 DT_SONAME在ELF standard中定义为:
此元素保存以null结尾的字符串表偏移量 string,给出共享对象的名称。偏移量是一个指数 进入
DT_STRTAB
条目中记录的表格。请参阅''共享对象 下面的依赖关系''有关这些名称的更多信息。
现在,当创建可执行文件时,SONAME嵌入其中。当连接器使用可执行文件时,在动态库的预定义位置的文件中查找库。 Windows中的预定义位置将是DLL所在的位置。在Linux和Mac OS X以及其他System V兼容系统中,它们可能是/lib
和/usr/lib
,可能还有其他位置,它取决于所使用的链接器,并且可以在链接器自己的配置中定义。
在所有事件中,链接器会查看soname条目中指定的库是否存在于任何位置,如果是,它将使用它。
请注意,该标准说soname是一个STRING,并且版本控制约定在事后变成了事实标准,并且是这样的:
使soname为libmyname.so.A
并使库文件名为libmyname.so.A.B或libmyname.so.A.B.C(在MacOSX下为libmyname.A.B.dylib)。创建从libmyname.so.A.B[.C]?
到libmyname.so.A
的软链接。
A
保持不变。
B
(或B.C
)成为次要版本。
在Linux下,库版本与软件包版本号相同是很常见的。这有其优点和缺点。
GNU libtool用于构建动态库,并且具有更正式的版本控制系统,并且具有强大的逻辑性。用于sonames的libtool版本控制系统运行良好,并且被复杂的库采用以保持正确。
在libtool下,版本控制如下:
libmylib-的 电流的即可。的 释放 即可。的 年龄 强>
在libtool下,我们的想法是随着库的发展,它们将添加和删除功能。
假设您正在开发一个库。首先使用0.0.0
版本。
现在让我们说你修复了一些错误,你只会增加发布号码。
所以新名称将来自libmylib.0.1.0或libmylib.0.2.0等..每个版本只修复错误但不会改变任何ABI。
一路上你说。啊!我可以更好地完成这个子功能,所以你添加了一组新功能来做更好的事情,但是因为其他人仍在使用你的库,所以你仍然保留旧的(已弃用的)功能。
规则如下:
中详细了解相关信息
从每个libtool库的版本信息'0:0:0开始。
仅在公开之前立即更新版本信息 发布您的软件。更频繁的更新是不必要的,并且 只能保证当前接口号变得更快。
如果自上次更新以来库源代码已完全更改, 然后增加修订版('c:r:a'变为'c:r + 1:a')。
如果自上次添加,删除或更改了任何接口 更新,增加当前值,并将修订版设置为0.
如果自上次公开发布以来添加了任何接口,则增加年龄。
- 醇>
如果自上次公开后删除或更改了任何接口 释放,然后将年龄设置为0。