显示共享库版本的 nm 输出不正确

Posted

技术标签:

【中文标题】显示共享库版本的 nm 输出不正确【英文标题】:nm output of show the shared library's version is incorrect 【发布时间】:2016-01-26 16:18:33 【问题描述】:

我刚刚建立了一个共享库,但是当我使用 nm 命令查看依赖项时,输出如下

$ nm -a libgio-2.0.so.0.2701.0 | grep ZLIB
     U deflateSetHeader@@ZLIB_1.2.2
     U inflateGetHeader@@ZLIB_1.2.2

不知道@@ZLIB_1.2.2的意思,其实构建libgio的命令是

gcc -o libgio-2.0.so.0.2701.0   libfoo.so libbar.so libz.so.1.2.8

其中libz.so.1.2.8是我自己从源码构建的,放到libgio-2.0.so.0.2701.0的同一个目录下。和系统的libz(/usr/lib/libz.so)不是同一个版本

那么,我的问题是为什么@@zlibnm 输出是1.2.2,而不是1.2.8?在 nm 输出中@@ZLIB_1.2.2 的含义是什么?

谢谢

【问题讨论】:

【参考方案1】:

nm 显示版本符号,版本没有错。

那么,我的问题是为什么@@zlib 的 nm 输出是 1.2.2,而不是 1.2.8?

因为这是您链接到的库中符号的版本。符号的版本不必与库的版本相同。

@@ZLIB_1.2.2 在 nm 输出中的含义是什么?

表示deflateSetHeader符号的当前定义是在1.2.2版本中添加的

在 1.2.8 版本中仍然是一样的,因为这些版本的 zlib 库是兼容的。版本 1.2.8 提供与版本 1.2.2 相同的符号并且它们是兼容的。新库还可能提供一些额外的符号,其版本为 ZLIB_1.2.2,但您的库不使用它们,因此您在 nm 输出中看不到对它们的任何引用。

基本上一切都好,没有什么可担心的。您的程序需要 1.2.2 版的符号,而您拥有的库提供了这些符号。

【讨论】:

您可能会澄清ZLIB是开发人员在构建库时选择的,它不一定是库的名称 感谢 Jonathan 和 Thomas 提供详细的 cmets。所以@@version 不是实际链接库的版本,而是符号的版本。在我的情况下,程序仍然会链接 zib 1.2.8,而不是 1.2.2,对吗? 程序将链接到您链接到的任何内容(以及运行时加载程序在运行时找到的内容)。使用nm 无法告诉您程序链接到哪个库,它只能向您显示缺少的符号。 deflateSetHeader@@ZLIB_1.2.2 只是一个符号的名称(装饰有一些额外的信息,使其与例如 deflateSetHeader@@ZLIB_0.1.1 不同)。要查看程序链接到的库,请使用 ldd 而不是 nm

以上是关于显示共享库版本的 nm 输出不正确的主要内容,如果未能解决你的问题,请参考以下文章

如何链接到共享库中定义的 [abi:cxx11] 函数?

如何使共享库符号强大?

共享库符号查找模板实例化

如何测试共享对象/共享库是否已正确编译?

iOS 5.1 - GDB 命令或实用程序列出特定共享库中的函数

nm 符号名称略有不同