Linux 从多个对象链接到自定义.a
在我们的构建系统中,我们生成多个.so文件(foo.so,bar.so,…),这些文件在运行时由主可执行文件(biz)加载。因此.So文件是单独链接的 我们也有自己的util.a静态库,它有一些实用函数和全局数据 当一些.so想要使用util.a数据/函数,但我们无法将每个.so链接到util.a时,就会出现问题。这是因为数据部分:全局数据在程序地址空间中必须是唯一的。如果不止一个.so链接到util.a并具有数据的副本,则程序行为将非常令人惊讶,但很难调试 我们也不能将可执行文件(biz)链接到util.a。链接器不会将所有内容都放到目标中,因为biz不会代表引用函数。所以Linux 从多个对象链接到自定义.a,linux,linker,ld,Linux,Linker,Ld,在我们的构建系统中,我们生成多个.so文件(foo.so,bar.so,…),这些文件在运行时由主可执行文件(biz)加载。因此.So文件是单独链接的 我们也有自己的util.a静态库,它有一些实用函数和全局数据 当一些.so想要使用util.a数据/函数,但我们无法将每个.so链接到util.a时,就会出现问题。这是因为数据部分:全局数据在程序地址空间中必须是唯一的。如果不止一个.so链接到util.a并具有数据的副本,则程序行为将非常令人惊讶,但很难调试 我们也不能将可执行文件(biz)链接
当然,除非将util.a链接到-Wl,-整个归档文件。但是有更好的方法吗?< /P> < P>解决方案1:考虑制作UTIL。一个动态库UTIL。所以, 解决方案2:不要让链接器导出util.a导出的任何符号。当使用gcc时,您可以通过使用
\uuuuuu属性((可见性(“隐藏”))
实现这一点:
您可以使用
objdump
检查导出了哪些符号。回答我的问题,最终的解决方案如下:
TL;DR:使用
nm(1)
搜索.so对象中所有感兴趣的符号(您希望从存档中提取的符号),并使用-Wl,-u,$SYMBOL
注入编译命令行。请注意,-Wl,-u,$SYMBOL
参数需要在命令行中位于存档名称之前,以便链接器知道它需要链接它们。可以是整个存档,也可以使所有全局数据保持静态,因此,每个使用它的人都将拥有唯一的数据集。当您将.a
静态链接到您的.so
时,这种令人惊讶的行为是什么?为什么调试很困难?@HAL在.a中定义的两个全局数据副本,使用相同的符号,将改变程序的行为并混淆调试器。@keltar-Wl,-整个存档的可移植性如何?如何断言所有全局数据都是静态的,并且在将来不会错误地引入?@FamZheng整个归档的行为都有很好的定义,但我不确定每个可能的链接器都支持这一点。更好地将此库直接集成到程序源代码中,但如果使用-fvisibility=hidden
进行编译,则可能会出现问题。
int __attribute__((visibility("hidden"))) helperfunc(void *p);