对于项目,我们尝试创建一个共享对象文件,该文件导出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}}文件。链接单个目标文件与存档文件之间应该没有任何区别。
答案 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