我有一个我创建的共享库,它引用了很多C ++模板函数。这些符号作为弱引用输入到共享库的导出表中(例如,当我使用W
查看共享库的符号时,它们显示为nm
类型。这意味着在运行时,这些符号可能会被来自首先加载的不同共享库的副本插入。
对于我的应用程序而言,我的共享库使用库本身包含的这些函数的副本,而不是来自任何其他库,这一点非常重要。有什么方法可以确保吗?听起来,这就等于将所有各种模板实例静态链接到共享库中。
答案 0 :(得分:1)
这意味着在运行时,这些符号可能会插入 来自首先加载的不同共享库的副本。
请注意,无论属性如何,都可以插入它们(请参阅this GCC post,其中说动态链接器会处理类似于强类的弱点,除非设置了LD_DYNAMIC_WEAK
,这通常不会。)
我的应用程序对我的共享库很重要 使用包含的这些函数的副本 在图书馆本身,而不是从任何其他图书馆。 有没有办法确保这个?
你可以做几件事。
通常建议的方法是将fvisibility=hidden
添加到CFLAGS中,以防止从库中导出任何符号,然后用__attribute__((visibility("default")))
标记(希望很少)导出的函数。这也可以在编译时进行更好的优化,并且可以更快地启动,因为rtld需要处理更少的符号。
穷人有限的解决方案是使用-fvisibility-inlines-hidden
这是-fvisility=hidden
的有限形式。它只会隐藏内联函数(例如,由STL模板生成)。
如果您不想弄乱源代码,请链接-Wl,-Bsymbolic
- 这会强制尽可能在库中解析引用。
- 编辑 -
实际上,即使您启用-Bsymbolic
以阻止其他库(或可执行文件本身)动态插入对导出函数的库内引用,您也需要-fvisibility=hidden
。