1

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

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

但是, 的输出nm libname.so为空。另一方面 grepping innm 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可见符号的共享对象?

不幸的是,如何从静态库创建共享对象文件并不能完全回答我的问题。

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

4

1 回答 1

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
于 2012-09-27T01:48:32.983 回答