我在使用g++连接某些共享库时遇到了问题。它会给出警告:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
我已经阅读了一些关于特定问题的相关问题,但我希望全面了解 - 这个警告意味着什么,以及它的原因是什么:
- DSO是什么?
- 什么是隐藏符号?
- 如果它是隐藏的,如何引用它?
我在使用g++连接某些共享库时遇到了问题。它会给出警告:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
我已经阅读了一些关于特定问题的相关问题,但我希望全面了解 - 这个警告意味着什么,以及它的原因是什么:
什么是DSO?
DSO是动态共享对象,或者更不正式地说是共享库。
什么是隐藏符号?
隐藏符号是已编译为隐藏链接的符号(即函数或数据对象名称),例如按照(GCC特定的)声明:
int x __attribute__ ((visibility ("hidden")));
如果一个动态共享目标库(DSO)中定义了变量x
,则从另一个DSO中无法动态引用它。链接器可以看到x
(它不是静态的),但无法在动态链接时使用。文档here。
如果它被隐藏了,如何引用它?
无法引用它,这就是您收到警告的原因。例如,链接时的警告:
在/usr/lib/libc_nonshared.a(stat.oS)中,隐藏的符号`stat'被DSO引用
告诉您链接中的DSO引用了符号stat
,链接器可以在/usr/lib/libc_nonshared.a
中找到stat
的定义,
但很显然,该定义不在引用它的DSO中并且无法从该DSO中引用,因为它被隐藏了。
如果问题DSO没有正确构建为DSO,则会出现此问题。请参见此示例并按照后续操作进行解决。
继续为OP的后续操作
如果隐藏符号已被某个DSO引用,那么为什么问题出在DSO上?
链接器说:
DSO X
包含对符号 S
的引用。我可以在另一个链接模块 Y
中找到符号 S
的定义,
但该定义将无法动态(即在运行时)满足 X
中的引用,因为 S
在 Y
中具有隐藏链接。
你可能没有明确标记任何隐藏在非共享对象中的符号。根据其构建方式,除非明确标记为“否”,否则符号可能默认情况下会被隐藏。我可以确认问题出现在非共享对象上[...][但]我没有明确隐藏我的非共享对象中的这些符号。
libnonshared.a
,而所谓的隐藏符号是foo
。那么运行以下命令:objdump -t libnonshared.a
获取有关libnonshared.a
中符号的信息。在输出中,查找foo
的条目。它是否包含标记.hidden
? - 例如。
0000000000000000 g F .text 000000000000000b .hidden foo
foo
是一个全局符号(标记为g
- 这就是链接器能够看到它的原因),但对于动态链接来说,它被隐藏了。
如果情况确实如此,那么您需要去修复libnonshared.a
的构建过程,以便它不再隐藏foo
。
否则,我就束手无策了。
距离Mike的出色回答已经过去了将近十年,我想提供一个更简短的答案,希望能帮助未来的读者:
当出现此错误时会发生什么:
我遇到此问题的一个具体示例:
祝你好运!