背景
我继承并维护了一个与特定硬件紧密耦合的Linux共享库;我们称之为libfoo.so.0.0.0
。这个图书馆已经存在了一段时间并且“正常工作”。该库现在已成为几个高层应用程序的依赖项。
现在,不幸的是,新的硬件设计迫使我创建更宽类型的符号,从而产生libfoo.so.0.1.0
。只有新增内容;没有删除或其他API更改。更新符号的原始窄版本仍以原始形式存在。
此外,我有一个依赖于myapp
的应用程序(例如,libfoo
)。它最初是为了支持库的0.0.0
版本而编写的,但现在已经过重新设计以支持新的0.1.0
API。
出于向后兼容性的原因,我希望能够通过编译标志为旧库或新库构建myapp
。将加载给定版本的myapp
的内核将始终只有一个版本的库,在编译时已知。
问题
将来libfoo
很可能会再次更新。
在构建myapp
时,是否可以根据构建标志指定要链接的最小版本的libfoo
?
我知道可以直接在构建CLI上指定库名。这会导致myapp
要求完全该版本,还是具有相同主要版本的lib的更高版本仍然可以链接到它(例如libfoo.so.0.2.0
)?我真的希望每次发布新的次要版本时都不必更新每个依赖应用程序的构建。
是否有更智能的方式以与应用程序无关的方式实现此目的?
参考
How do you link to a specific version of a shared library in GCC
答案 0 :(得分:2)
您正在描述外部库版本控制,其中应用是针对libfoo.so.0
,libfoo.so.1
等构建的。文档here。
使用外部库版本控制要求运行时完全相同版本的libfoo.so.x
。
这通常是不 Linux上的正确技术,它通过symbol versioning的魔力允许单个libfoo.so.Y
提供相同符号的多个不兼容定义,因此允许单个库同时为旧应用程序和新应用程序提供服务。
此外,如果您只是总是添加新符号,并且不以不兼容的方式修改现有符号,那么无理由可以增加外部版本。将libfoo.so
保留在版本0
,在其中提供int foo_version_X_Y;
全局变量(以及所有先前版本:foo_version_1_0
,foo_version_1_1
等),以及让应用程序二进制文件读取它所需的变量。如果应用程序需要新符号foo_version_1_2
并且使用仅提供foo_version_1_1
的旧库运行,则应用程序将无法以明显错误启动。