【问题标题】:How do you link a static library to a shared library如何将静态库链接到共享库
【发布时间】:2015-01-28 07:51:28
【问题描述】:

我正在尝试通过类似的命令将静态库链接到共享库

g++ -shared obj.o archive.a -o libLib.so

但在运行时,我不断得到未解析的系统,该系统应该在编译时从 archive.a 链接。我试过了

 g++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib.so

g++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so

没有成功。我觉得我在这里缺少一些基本的东西......

【问题讨论】:

  • 您的第二次尝试看起来像是 this 的修改版本,它实际上是用于从静态和共享对象的输入生成可执行文件。但是,您正在尝试输出一个共享对象,因此这不相关。

标签: c++ linker ld


【解决方案1】:

您实际上不能(即应该从不)这样做。 Shared libraries 应该是 position independent code,但静态库不是。

如果您想将libaa 链接到libfoo.so 构建或获取共享 (PIC) 库libaa.so,而不是静态(非PIC)库libaa.a

因此,进入共享库libfoo.so 的文件foo1.cc 应编译为

g++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o

库将链接为

g++ -shared foo1.pic.o foo2.pic.o -o libfoo.so 

您可以将另一个共享库libsmiling.so 链接到libfoo.so,例如通过将-lsmiling 附加到上述命令。但是你不能将库链接到静态库中,只需复制它们的成员即可。

但是进入 staticlibfoo.a 的文件只是编译为

g++ -Wall -O foo1.cc -o foo1.o

所以当你从libfoo.a 中提取foo1.o 成员时,它不是 PIC(效率非常低)

原则上,您可以将非 PIC 目标代码放入共享库中。在实践中,您永远不应该这样做,因为relocation 的数量如此之大以至于它违背了共享 库的目的。如果您这样做了,文本内存将无法共享,并且动态链接器将进行大量重定位工作。

.so 共享对象中的代码应该是 PIC,以允许 ld.sommap 它在不同进程的不同地址段。

因此,您可以找到一系列命令将静态库链接到共享库,例如使用ar x 提取libbar.a 的所有成员,然后将所有这些提取的bar*.ofoo*.pic.o 链接,但这将是一个错误。不要将静态非 PIC 库或对象文件链接到 PIC 共享库。

有关详细信息(重点关注 Linux),请阅读 ld.so(8)ld(1)ELF wikipage、Levine's book: Linkers and loadersDrepper's paper: How To Write Shared Libraries

PS。一些极少数静态库包含 PIC 代码,因为它们可用于制作共享库。例如,我的 Debian 提供了 libc6-pic 包,特别是提供了 /usr/lib/x86_64-linux-gnu/libc_pic.a 静态 PIC 库 - 可用于构建 libc.so 的某些变体 -e.g.如果我想将自己的malloc 放入libc.so! - 无需重新编译每个 glibc 源文件。

【讨论】:

  • 哇!这可能是我在这个主题上看到的最完整的答案——谢谢!虽然,当我将用于存档的对象编译为 PIC 代码时,它会链接——但存档使用 -fPIC 编译的情况并不常见
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
相关资源
最近更新 更多