我试图了解Linux中的库版本控制以及如何将其全部应用到工作中。以下是相关内容:
- 我有两个动态库版本,它们公开相同的接口,称为`libsome1.so`和`libsome2.so`。 - 应用程序链接到`libsome1.so`。 - 此应用程序使用`libdl.so`动态加载另一个模块,称为`libmagic.so`。 - 现在,`libmagic.so`链接到`libsome2.so`。显然,在运行时,所有对`libsome2.so`接口的调用都将被解析为`libsome1.so`,除非使用链接器脚本来隐藏`libmagic.so`中的符号。可以通过检查`libVersion()`返回的值与宏`LIB_VERSION`的值进行确认。 - 因此,我尝试使用链接器脚本编译和链接`libmagic.so`,该脚本隐藏所有符号,仅公开其中定义的3个符号,并由其导出。这有效...或者至少`libVersion()`和`LIB_VERSION`的值匹配(并且报告版本2而不是1)。 - 但是,当某些数据结构序列化到磁盘时,我注意到一些损坏。如果在应用程序目录中删除`libsome1.so`并创建软链接以指向`libsome2.so`,则一切正常,不会发生相同的损坏。
我不禁认为这可能是由于运行时链接器解析符号时的某些冲突造成的。我尝试了许多方法,例如尝试链接`libsome2.so`,以便将所有符号别名为`symbol@@VER_2`(对此仍感到困惑,因为命令`nm -CD libsome2.so`仍会将符号列出为`symbol`而不是`symbol@@VER_2`)...没有任何方法可行!求助!!!!!
编辑:我应该早些提到,但所涉及的应用程序是Firefox,而`libsome1.so`是其中附带的`libsqlite3.so`。我不能重新编译它们。此外,使用版本脚本来隐藏符号似乎是目前唯一的解决方案。那么隐藏符号时真正发生了什么?它们是否变成SO的“本地”符号?rtld是否不知道它们的存在?当导出函数引用隐藏符号时会发生什么?
- 我有两个动态库版本,它们公开相同的接口,称为`libsome1.so`和`libsome2.so`。 - 应用程序链接到`libsome1.so`。 - 此应用程序使用`libdl.so`动态加载另一个模块,称为`libmagic.so`。 - 现在,`libmagic.so`链接到`libsome2.so`。显然,在运行时,所有对`libsome2.so`接口的调用都将被解析为`libsome1.so`,除非使用链接器脚本来隐藏`libmagic.so`中的符号。可以通过检查`libVersion()`返回的值与宏`LIB_VERSION`的值进行确认。 - 因此,我尝试使用链接器脚本编译和链接`libmagic.so`,该脚本隐藏所有符号,仅公开其中定义的3个符号,并由其导出。这有效...或者至少`libVersion()`和`LIB_VERSION`的值匹配(并且报告版本2而不是1)。 - 但是,当某些数据结构序列化到磁盘时,我注意到一些损坏。如果在应用程序目录中删除`libsome1.so`并创建软链接以指向`libsome2.so`,则一切正常,不会发生相同的损坏。
我不禁认为这可能是由于运行时链接器解析符号时的某些冲突造成的。我尝试了许多方法,例如尝试链接`libsome2.so`,以便将所有符号别名为`symbol@@VER_2`(对此仍感到困惑,因为命令`nm -CD libsome2.so`仍会将符号列出为`symbol`而不是`symbol@@VER_2`)...没有任何方法可行!求助!!!!!
编辑:我应该早些提到,但所涉及的应用程序是Firefox,而`libsome1.so`是其中附带的`libsqlite3.so`。我不能重新编译它们。此外,使用版本脚本来隐藏符号似乎是目前唯一的解决方案。那么隐藏符号时真正发生了什么?它们是否变成SO的“本地”符号?rtld是否不知道它们的存在?当导出函数引用隐藏符号时会发生什么?