版本号、副版本号和发行号的区别
Difference between version number, minor number and release number
我正在看http://www.tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html,我有一些问题。
版本号、次要版本号和发行号有什么区别?当接口发生变化时,"版本号"增加是什么意思?
名称有前缀
lib
,库的名称,短语.so
,后面跟着句号和版本号,版本号在接口改变时递增。实名添加句点、副号、另一个句点和发行号。
每次发布库时,它应该有一个不同的版本号。但是,有些版本只对库的内部工作进行更改,除了修复错误外,对用户没有任何影响。其他版本也可能向库中添加新函数,但所有现有函数的接口细节与以前相同,因此使用旧版本库编写的软件将继续与新版本一起工作。其他更改可能会破坏向后兼容性;一个函数接口改变了,一个结构改变了大小,或者一个函数被删除了(或者一个全局变量——放弃这个想法——改变了,等等)。
"仅修复错误"的版本可能不会为库重新编号而烦恼,但如果您以前有liberror.so.1.0.2
,则新版本可能是liberror.so.1.0.3
,这是发行号的变化。
"附加功能"版本应该被赋予一个新的次要编号,所以liberror.so.1.0.2
之后的新版本可能是liberror.so.1.1.0
。
如果你破坏了兼容性,那么你使用一个新的版本号,所以liberror.so.1.0.2
之后的新版本可能是liberror.so.2.0.0
。
使用liberror.so.1.0.2
构建的代码可以并且将毫无问题地使用liberror.so.1.0.3
或liberror-1.1.0
,但不会尝试使用liberror.so.2.0.0
或更高版本。
哪些代码(例如在GNU binutils堆栈中)控制将被链接到哪些版本,这种行为是固定的还是可重写的?
好问题。这是我的理解,但我可能有一些细节错误(在这种情况下,有人可能会指出我的错误方式)。上面的理论很好也很简单;
你可能已经注意到库有"开发"包以及库的"标准"版本。它们之间的差异是部分原因。
如果您是一个普通的最终用户,不使用库编写程序,而只是运行别人编写的程序,那么您通常会在安装目录中使用一个文件和一个符号链接。继续使用假设的liberror.so.1.0.2
示例(安装在/usr/local/lib
中),您会在基本版本中发现:
liberror.so.1.0.2 — the real shared object
liberror.so.1 — symlink to the the real shared object
如果您安装了开发版本,您可能会在/usr/local/include
中找到一些头文件,一些手册页(可能在/usr/local/man
中,也可能在/usr/share
中)和一个额外的符号链接:
liberror.so — another symlink, either to liberror.so.1 or to liberror.so.1.0.2
当编译使用它的程序时,您可以指定:
gcc -I/usr/local/include usererror.c -o usererror -L/usr/local/lib -lerror
这将与名称liberror.so
链接,但是从liberror.so.1.0.2
文件中读取元数据,它将知道要使用的版本是liberror.so.1.0.2
或更高版本(而不是liberror.so.2.0.0
或更高版本)。
现在让我们假设您将安装升级到liberror.so.2.0.0
。现在有了以下文件:
liberror.so.1.0.2 — the real shared object
liberror.so.1 — symlink to the the real shared object
liberror.so.2.0.0 — the real shared object
liberror.so.2 — symlink to the the real shared object
liberror.so — another symlink, either to liberror.so.2 or to liberror.so.2.0.0
使用liberror.so.1
构建的旧代码仍然使用该库运行。使用liberror.so.2
构建的新代码也可以使用新库运行。在链接时,新程序通过符号链接liberror.so
获取liberror.so.2.0.0
。
您可以通过调整liberror.so
符号链接以指向liberror.so.1.0.2
来控制它,以便系统上的默认值仍然是liberror.so.1
。唯一棘手的部分是确保正确版本的头文件可用于编译。使用liberror.so.2
的头构建并链接liberror.so.1
是一个坏主意,因为您可以肯定的一件事是接口是不同的!
来自Red Hat Enterprise Linux 5 (RHEL5) x86_64机器的一些原始数据。
$ cd /lib64
$ ls libc*
-rwxr-xr-x 1 root root 1713088 2009-01-05 16:32 libc-2.5.so
lrwxrwxrwx 1 root root 11 2012-02-22 15:05 libcap.so -> libcap.so.1
lrwxrwxrwx 1 root root 14 2012-02-22 15:05 libcap.so.1 -> libcap.so.1.10
-rwxr-xr-x 1 root root 17384 2006-11-14 01:36 libcap.so.1.10
-rwxr-xr-x 1 root root 197744 2009-01-05 16:32 libcidn-2.5.so
lrwxrwxrwx 1 root root 14 2012-02-22 15:05 libcidn.so.1 -> libcidn-2.5.so
lrwxrwxrwx 1 root root 17 2012-02-22 15:05 libcom_err.so.2 -> libcom_err.so.2.1
-rwxr-xr-x 1 root root 10000 2008-09-30 13:27 libcom_err.so.2.1
-rwxr-xr-x 1 root root 48600 2009-01-05 16:32 libcrypt-2.5.so
-rwxr-xr-x 1 root root 1048728 2005-10-31 06:47 libcrypto.so.0.9.6b
-rwxr-xr-x 1 root root 1365504 2008-12-16 08:09 libcrypto.so.0.9.8e
lrwxrwxrwx 1 root root 19 2012-02-22 15:05 libcrypto.so.2 -> libcrypto.so.0.9.6b
lrwxrwxrwx 1 root root 19 2012-02-22 15:05 libcrypto.so.4 -> libcrypto.so.0.9.8e
lrwxrwxrwx 1 root root 19 2012-02-22 15:05 libcrypto.so.6 -> libcrypto.so.0.9.8e
lrwxrwxrwx 1 root root 15 2012-02-22 15:05 libcrypt.so.1 -> libcrypt-2.5.so
lrwxrwxrwx 1 root root 11 2012-02-22 15:05 libc.so.6 -> libc-2.5.so
$
可以看到libc.so.6
是指向libc-2.5.so
的符号链接。您还可以使用多个版本的libcrypto
,但不包括链接时库libcrypto.so
。您还可以看到版本号只有两个部分的库,等等。libc
, libcap
, libcidn
, libcom_err
, libcrypt
和libcrypto
.
- 成功完成TLS握手后,服务器关闭时出现错误的SSL例程:SSL3_GET_RECORD:错误的版本号
- 如何从二进制文件中获取应用程序的版本号?
- 从 qmake 运行脚本以获取内部版本号
- 比较版本号字符串
- 使用以 10.0.0 形式定义版本号的宏
- 使用 c++ API 更改 qpid 协议版本号
- Visual Studio 2017,Boost和Cmake的版本号
- 如何将版本号从git标签传输到CPACK生成的源软件包
- 使用 C、C++ 或 Java 以编程方式获取 Java 和 Flash 的版本号
- 将内部版本号传递给 msbuild(c++ 项目)
- 如何检查特征C 模板库的版本号
- 如何解决LDCONFIG创建带有版本号的链接
- 使用Jenkins、内部版本号和svn修订版管理程序版本
- 在Visual Studio 2005中自动更新版本号(C++/C#)
- 使用 #define 和 clang 为 info.plist 创建版本号变体
- 以具有多个点(版本号)的格式将数字强制转换(转换)为字符串
- Visual Studio 详细版本号
- 快速排序中使用的两个分区版本的区别
- COM 对象版本号以及如何通过 Win 注册表处理它
- 版本号、副版本号和发行号的区别