我有一个问题链接一些共享库与g++。它给我一个警告,如:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
我已经阅读了一些关于特定问题的相关问题,但我想从整体上了解它--这个警告意味着什么,原因是什么:1.什么是DSO?1.什么是隐藏符号?1.如果它是隐藏的,如何引用它?
rjee0c151#
什么是DSO?
int x __attribute__ ((visibility ("hidden")));
如果在一个DSO中定义了x,则动态链接无法从另一个DSO引用它。链接程序可以看到x(它不是static),但它不可用于 * 动态 * 链接。文档here
x
static
如果它是隐藏的,如何引用它?
这是不可能的,这就是你被警告的。例如,链接时间警告:/usr/lib/libc_nonshared.a(stat.oS)中的隐藏符号'stat'被DSO引用是告诉您链接中的DSO引用符号stat,链接器可以在/usr/lib/libc_nonshared.a中找到stat的定义,但(很明显)该定义不在引用它的DSO中,并且不能从该DSO中引用,因为它是隐藏的。如果未正确建立问题DSO以用作DSO,则会出现此问题。请参阅this example并遵循后续操作以获得解决方案。
stat
/usr/lib/libc_nonshared.a
继续OP的随访
如果隐藏符号已经被某个DSO引用,那么为什么DSO会出现问题?链接器说:DSO X包含对符号S的引用。我可以找到符号S的定义是另一个链接模块Y,但该定义将无法 * 动态 *(即 * 在运行时 *)满足X中的引用,因为S在Y中具有隐藏链接。我可以确认这个问题是由一个非共享对象引起的[...][但是]我没有显式地在我的非共享对象中隐藏这些符号。您可能未在非共享对象中显式标记任何隐藏符号。根据生成方式的不同,符号可能默认为隐藏,除非显式标记 * 否则 *。假设非共享对象是libnonshared.a,而所谓的隐藏符号是foo。运行:
X
S
Y
libnonshared.a
foo
objdump -t libnonshared.a
以获取有关libnonshared.a中符号的信息。在输出中,查找foo的条目。它是否包含标记.hidden?-例如。
.hidden
0000000000000000 g F .text 000000000000000b .hidden foo
这个条目说foo是一个全局符号(标记为g-这就是为什么链接器能够看到它)* 但是 * 它对于 * 动态 * 链接是隐藏的。如果事实证明是这样的话,那么你需要去修复libnonshared.a的构建,这样它就不会隐藏foo。
g
tvokkenx2#
这与Mike的精彩回答相差近十年,我想提供一个简短的答案,可能会在未来对其他人有所帮助:
发生此错误时会发生什么情况:
1.您正在链接的动态库包含正在由另一个库解析的符号1.如果解析符号的库是静态的(.a),则会发生此错误1.尝试将解析库重新创建为动态库(.so)
我遇到此问题的一个具体示例:
1.我创建了一个使用一些OpenCV函数的动态库,因此有一些OpenCV符号1.我链接了OpenCV库来解析动态库中的符号,但我的OpenCV库是静态的,这导致了原始帖子中描述的错误。1.我重新编译了OpenCV,这次将库创建为动态的1.我尝试用我的动态库和新创建的OpenCV动态库重新编译我的程序1.轰,错误不再出现。祝你好运!
2条答案
按热度按时间rjee0c151#
什么是DSO?
什么是隐藏符号?
如果在一个DSO中定义了
x
,则动态链接无法从另一个DSO引用它。链接程序可以看到x
(它不是static
),但它不可用于 * 动态 * 链接。文档here如果它是隐藏的,如何引用它?
这是不可能的,这就是你被警告的。例如,链接时间警告:
/usr/lib/libc_nonshared.a(stat.oS)中的隐藏符号'stat'被DSO引用
是告诉您链接中的DSO引用符号
stat
,链接器可以在/usr/lib/libc_nonshared.a
中找到stat
的定义,但(很明显)该定义不在引用它的DSO中,并且不能从该DSO中引用,因为它是隐藏的。如果未正确建立问题DSO以用作DSO,则会出现此问题。请参阅this example并遵循后续操作以获得解决方案。
继续OP的随访
如果隐藏符号已经被某个DSO引用,那么为什么DSO会出现问题?
链接器说:
DSO
X
包含对符号S
的引用。我可以找到符号S
的定义是另一个链接模块Y
,但该定义将无法 * 动态 *(即 * 在运行时 *)满足X
中的引用,因为S
在Y
中具有隐藏链接。我可以确认这个问题是由一个非共享对象引起的[...][但是]我没有显式地在我的非共享对象中隐藏这些符号。
您可能未在非共享对象中显式标记任何隐藏符号。根据生成方式的不同,符号可能默认为隐藏,除非显式标记 * 否则 *。
假设非共享对象是
libnonshared.a
,而所谓的隐藏符号是foo
。运行:以获取有关
libnonshared.a
中符号的信息。在输出中,查找foo
的条目。它是否包含标记.hidden
?-例如。这个条目说
foo
是一个全局符号(标记为g
-这就是为什么链接器能够看到它)* 但是 * 它对于 * 动态 * 链接是隐藏的。如果事实证明是这样的话,那么你需要去修复
libnonshared.a
的构建,这样它就不会隐藏foo
。tvokkenx2#
这与Mike的精彩回答相差近十年,我想提供一个简短的答案,可能会在未来对其他人有所帮助:
发生此错误时会发生什么情况:
1.您正在链接的动态库包含正在由另一个库解析的符号
1.如果解析符号的库是静态的(.a),则会发生此错误
1.尝试将解析库重新创建为动态库(.so)
我遇到此问题的一个具体示例:
1.我创建了一个使用一些OpenCV函数的动态库,因此有一些OpenCV符号
1.我链接了OpenCV库来解析动态库中的符号,但我的OpenCV库是静态的,这导致了原始帖子中描述的错误。
1.我重新编译了OpenCV,这次将库创建为动态的
1.我尝试用我的动态库和新创建的OpenCV动态库重新编译我的程序
1.轰,错误不再出现。
祝你好运!