从静态库创建共享对象,其目标文件与-fPIC链接

时间:2012-09-26 12:01:20

标签: gcc linker shared-libraries ld

对于项目,我们尝试创建一个共享对象文件,该文件导出libname.exports中指定的一组函数。当然,我们知道必须使用.so创建-fPIC文件所链接的目标文件,因此已经处理好了。然后,我们将目标文件合并到名为libname.a的存档中。现在这应该是创建.so文件的基础 - 或者是这样的想法。

我们正在将libname.exports传递给--retain-symbols-file,因此预期的行为是链接器会引入与这些符号相关的任何.a成员。

但是,nm libname.so的输出为空。另一方面,在nm libname.a中进行点击会显示libname.exports成员中存在.a中指定的相关符号。

现在我偶然发现了--whole-archive,从而调整了命令行:

gcc -o libname.so -shared -Wl,-z,defs,--retain-symbols-file,libname.exports,-L. libname.a -lc

为:

gcc -o libname.so -shared -Wl,-z,defs,--retain-symbols-file,libname.exports,-L.,--whole-archive,libname.a,--no-whole-archive -lc

似乎具有包含所有来自.a的目标文件的预期效果(尽管大小差异很奇怪)。但是,nm libname.so仍然没有输出。

如何使用存档文件创建只包含libname.exports中可见的符号的共享对象?

不幸的是How to create a shared object file from static library并没有完全回答我的问题。

注意:在你问之前。使用.a文件作为输入背后的想法是因为它可以很容易地在GNUmakefile中使用模式规则,因为无论如何都需要带有.a的{​​{1}}文件。链接单个目标文件与存档文件之间应该没有任何区别。

1 个答案:

答案 0 :(得分:1)

您可以使用-u SYMBOL选项强制从档案中读取对象。

% cc -c -fPIC a.c
% nm a.o
00000000 T a
% ar rv liba.a a.o
ar: creating liba.a
a - a.o
% gcc -o liba.so -shared -u a liba.a
% nm liba.so | awk '$3 == "a" { print }'
0000042c T a

要检查的一件事是用--retain-symbols-file指定的符号的拼写。例如,从C ++代码编译的对象中的符号名称可能会被破坏:

% g++ -c -fPIC a.c
% nm a.o | awk '$2 == "T" { print }'
00000000 T _Z1av