341*_*008 5 c linux gcc shared-libraries
我创建了一个.c文件,该.o文件与大约 300 个其他.c文件一起转换为一个文件,并包含在一个.a静态库中。该库与许多其他库一起用于创建.so动态库。在使用 分析.a和.so文件时nm,我发现由于某种原因,.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 ...
Run Code Online (Sandbox Code Playgroud)
我在此处指定隐藏的可见性的原因是我只想公开几个选定的符号。为了公开符号,foo.c我指定了可见性属性,以便标题中的函数签名foo.h如下所示:
extern int _____attribute_____ ((visibility ("default"))) func();
编辑:命令nm libbar.a | grep Ctx给出:
000023c5 T CtxAcquireBitmap
000026e9 T CtxAcquireArray
00001e77 T CtxCallMethod
Run Code Online (Sandbox Code Playgroud)
但是,nm libfinal.so | grep Ctx不显示任何内容。
更新:找到另一篇讨论该选项用途的帖子--whole-archive。此外,偶然发现了一个--export-dynamic选项,该选项显然告诉链接器保留未引用的符号。进一步调查。
--whole-archive链接时尝试使用链接器选项将所有对象包含到共享库中
gcc -o libfinal.so -Wl,--whole-archive libbar.a x.o y.a -Wl,--no-whole-archive
Run Code Online (Sandbox Code Playgroud)
来自man ld:
--whole-archive
对于命令行中在 --whole-archive 选项之后提到的每个存档,在链接中包含存档中的每个目标文件,而不是在存档中搜索所需的目标文件。这通常用于将存档文件转换为共享库,强制将每个对象都包含在生成的共享库中。此选项可以多次使用。从 gcc 使用此选项时有两个注意事项:首先,gcc 不知道此选项,因此您必须使用 -Wl,-whole-archive。其次,不要忘记在您的档案列表之后使用 -Wl,-no-whole-archive,因为 gcc 会将其自己的档案列表添加到您的链接中,您可能不希望此标志也影响这些。
341*_*008 -1
在我的主文件中为所需符号创建虚拟引用并没有解决问题。引用的符号出现在带有(=未定义)标记的二进制转储(使用 获得nm)中U。我设法通过在创建.so文件时直接链接目标文件而不是.a首先将其包含在库中来解决该问题。由于这些函数被标记,因此extern它们被包含在 中.so,即使它们没有在库中被引用。如果它们没有被标记extern,就不会像 sylvainulg 所说的那样被包含在内。
感谢德米特里指出了这个--whole-archive选项。我不知道存在这样的选择。