【问题标题】:Can I build a shared library by linking static libraries?我可以通过链接静态库来构建共享库吗?
【发布时间】:2012-02-07 04:25:32
【问题描述】:

我有一堆静态库 (*.a),我想构建一个共享库 (*.so) 来链接这些静态库 (*.a)。如何在 gcc/g++ 中这样做?

【问题讨论】:

  • .a 不是共享库。你能举个例子说明你正在尝试做什么吗?

标签: c++ c gcc shared-libraries static-libraries


【解决方案1】:

您可以(只需提取所有.o 文件并将它们与-shared 链接以制作.so),但它是否有效,以及它的效果如何,取决于平台以及静态库是否编译为与位置无关的代码 (PIC)。在某些平台上(例如 x86_64),非 PIC 代码在共享库中无效并且无法工作(实际上我认为链接器会拒绝生成 .so)。在其他平台上,非 PIC 代码可以在共享库中工作,但该库的内存副本不能在使用它的不同程序甚至同一程序的不同实例之间共享,因此会导致巨大的内存膨胀。

【讨论】:

  • 感谢这个非常有用的答案!我想这是在 x86_64 上执行此操作时此错误的最佳解释:创建共享对象时无法使用针对 `g_gGlobalVariable' 的 'relocation R_X86_64_32S';使用 -fPIC' 重新编译
  • 我必须支持这不适用于 Linux 上的 x86_64 代码的评论。但是,在 macOS 上,您可以在构建动态库时简单地包含静态库。但我还没有设法在 Linux 上完成它。
  • 我在遥远的过去也曾在 Win32 上这样做过。 Iirr,您必须覆盖 IDE 中的许多默认设置,但它是可行的并且确实有效。构建插件时会出现问题。有时您希望避免共享库中的冲突,并且对运行时部署没有太多控制。
【解决方案2】:

我不明白为什么您不能将动态库的文件构建为 .o 文件并与之链接;

gcc -shared *.o -lstaticlib1 -lstaticlib2 -o mylib.so

【讨论】:

  • 问题是你可以省略*.o,如果你没有它们
  • 静态库只有在实际被引用的情况下才会拉入它们的代码,但是,你不能忽略所有.o
  • 还要注意,如果同一个静态库的多个实例存在于同一个可执行文件中(通过包含静态库的共享库间接加载),可能会发生奇怪的事情
  • @nos,PIC 与可重定位不同。所有静态库都是可重定位的,但可能是也可能不是 PIC。请注意,在 x86 Linux(但不是 x86-64)上,非 PIC 共享库 do 工作,它们只需要在库加载时完成重定位,这很慢,增加了内存使用量,并且具有一定的安全问题(因为它要求在重定位过程中将代码页标记为 r/w)
猜你喜欢
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 2021-09-30
  • 2011-01-09
  • 1970-01-01
相关资源
最近更新 更多