【问题标题】:Creating shared object from static library whose object files were linked with -fPIC从对象文件与 -fPIC 链接的静态库创建共享对象
【发布时间】:2012-09-26 12:01:20
【问题描述】:

对于一个项目,我们正在尝试创建一个共享对象文件,该文件导出一组在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 中使用模式规则,并且因为无论如何都需要带有-fPIC.a 文件。链接单个目标文件与归档文件之间应该没有任何区别。

【问题讨论】:

  • 尝试过提取和链接单独的目标文件吗?
  • @Joachim Pileborg:是的。只要libname.exports 包含要导出的符号名称并且libname.a 包含相应的成员,它就可以工作。我作为测试所做的是将ar x libname.a 放入子文件夹armembers,然后在命令行上传递armembers/*.o 而不是libname.a

标签: gcc linker shared-libraries ld


【解决方案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

【讨论】:

  • 谢谢。它是 C 文件,我知道这种修改。让我看看-u 是否能胜任这项工作。因为据我所知,我想引入一些 API 函数(在所述文件中命名)并且可以简单地使用该文件来创建命令行。我检查了符号的拼写,顺便说一句。不幸的是,这不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-29
相关资源
最近更新 更多