我引用了 Michael Kerrisk 所著的流行书籍《Linux 编程接口》中与符号版本控制相关的内容:
“该技术提供了一种替代传统库版本控制方法的方法,即在共享库实名中使用主要版本号和次要版本号。”
我想了解一些经常处理 Linux 共享库的 Linux 库人员的意见。
我的问题是符号版本控制技术是否只是 Linux 共享库中一种罕见且不常用的技术。
它通常用于发行版上的共享库,主要是那些多个版本最终可能链接到同一个二进制文件的库,例如 OpenSSL 和 libpng。
以 Git 为例。 Git 可以原生使用 OpenSSL 构建,它也可以链接到 libcurl,后者可能使用 OpenSSL 本身。 (实际上,发行版被禁止以这种方式分发与 OpenSSL 链接的 Git,但这只是一个示例。)如果 Git 是针对 OpenSSL 1.1 构建的,并且 libcurl 获得更新以使用 OpenSSL 3.0,那么在没有符号版本控制的情况下,哪个版本在运行时调用某个函数是一个错误,程序可能会崩溃。
如果您使用符号版本控制,则由于版本控制,OpenSSL 1.1 符号与 OpenSSL 3.0 符号不同,因此一切正常。这使得逐步升级软件变得更加容易,而不必立即重建所有内容。
另一个值得注意的例子是 glibc,它实际上总是版本化的。
memcpy
函数要求其参数不重叠。 glibc 在某些架构上实现了高度优化的版本,向下复制而不是向上复制,这是标准允许的。然而,某些软件(尤其是当时的 Flash Player)由于误用了 memcpy
,而采取了不同的做法,因此崩溃了。
解决方案是保留旧版本并保留旧符号名称,并使用新符号版本创建
memcpy
。新软件将使用新行为并获得性能提升,而旧软件将使用旧版本并获得复制代码。
同样,Glibc 2.34 添加了新的 POSIX 信号量函数,新编译的软件可以链接它们并获得新功能,而旧软件将继续运行而无需更改。