来自.a的目标文件不包含在.so中

时间:2010-08-11 15:09:03

标签: c linux gcc shared-libraries

我创建了一个.c文件,该文件与大约300个其他.o文件一起转换为.c文件,并包含在.a静态库中。该库以及许多其他库用于创建.so动态库。在使用.a分析.sonm文件时,我发现由于某种原因,.c文件中定义的符号出现在.a中文件但不在.so文件中。我认为没有理由这应该发生。有人可以帮帮我吗?用于创建两个二进制文件的步骤是:

gcc -fvisibility=hidden -c foo.c -o foo.c.o
ar cr libbar.a foo.c.o ...
gcc -fvisibility=hidden -fPIC -o libfinal.so libbar.a x.o y.a ... 

我在此处指定隐藏可见性的原因是我只想暴露几个选定的符号。要公开来自foo.c的符号,我已指定了visibility属性,以便标题foo.h中的函数签名如下所示:

extern int _____attribute _____((visibility(“default”)))func();

编辑:命令nm libbar.a | grep Ctx给出:

000023c5 T CtxAcquireBitmap
000026e9 T CtxAcquireArray
00001e77 T CtxCallMethod

但是,nm libfinal.so | grep Ctx没有显示任何内容。

更新:找到了另一个post,其中讨论了--whole-archive选项的用法。此外,偶然发现--export-dynamic选项,显然告诉链接器保留未引用的符号。进一步调查。

3 个答案:

答案 0 :(得分:4)

尝试使用--whole-archive链接器选项在链接

时将所有对象包含到共享库中
gcc -o libfinal.so -Wl,--whole-archive libbar.a x.o y.a -Wl,--no-whole-archive

来自man ld

  

<强> - 全 - 归档
  对于--whole-archive选项后命令行中提到的每个存档,包括存档中的每个目标文件              链接,而不是在存档中搜索所需的目标文件。这通常用于将存档文件转换为共享文件              库,强制每个对象都包含在生成的共享库中。此选项可能会被多次使用。

     

从gcc使用此选项时的两个注意事项:首先,gcc不知道此选项,因此您必须使用-Wl,-whole-archive。              其次,不要忘记在档案列表之后使用-Wl,-no-whole-archive ,因为gcc会将自己的档案列表添加到您的档案中              链接,你可能不希望这个标志也影响那些。

答案 1 :(得分:1)

据我所知,在编译.a时,gcc只会拉出其他模块引用的对象。如果你的意图是将.a的全部内容包含在.so中,那么使用libbar.a中的内容进行简单的“编译/链接x.c到libfinal.so”就不是你想要的了。

答案 2 :(得分:-1)

在我的主文件中为所需符号创建虚拟引用并没有解决问题。引用的符号出现在二进制转储(使用nm获得)中,并带有U(=未定义)标记。我设法通过在创建.so文件时直接链接目标文件而不是首先将其包含在.a库中来解决问题。由于这些函数已标记为extern,因此它们包含在.so中,即使它们未在库中引用。如果他们没有被标记为extern,他们就不会像sylvainulg那样被包括在内。

感谢Dmitry指出--whole-archive选项。我不知道存在这样的选择。