将静态库转换为共享库?

Posted

技术标签:

【中文标题】将静态库转换为共享库?【英文标题】:Convert a Static Library to a Shared Library? 【发布时间】:2010-10-13 21:35:39 【问题描述】:

我有一个第三方库,主要由大量静态 (.a) 库文件组成。我可以将它编译成单个 .a 库文件,但我确实需要它成为单个 .so 共享库文件。

有没有办法将静态.a 文件转换为共享.so 文件?或者更一般地说,有没有一种好方法可以将大量静态 .a 文件与几个 .o 目标文件组合成一个 .so 文件?

【问题讨论】:

【参考方案1】:

这样做(当然是适当的 -L)

gcc -shared -o megalib.so foo.o bar.o -la_static_lib -lb_static_lib

不做吗?

【讨论】:

使用 gcc -shared 可以解决问题,但只有在我使用 -fPIC 重新编译之后。感谢您为我指明正确的方向! 我知道这是一个旧的答案,但它......不起作用?对于我尝试过的每个静态库,生成的共享对象不再导出任何原始符号。 我遇到了同样的问题@Peter【参考方案2】:

如果静态库中的对象是在没有 -fPIC 或类似的情况下编译的,则无法执行此操作。

【讨论】:

在支持良好的目标上,PIC 对于共享库代码不是必需的。它只会以牺牲一些性能为代价,从而更有效地使用内存(可以共享大部分而不是少数页面)。 在某些情况下缺少 -fPIC 等会导致 SegFault【参考方案3】:
g++ -shared -o megalib.so foo.o bar.o -Wl,--whole-archive -la_static_lib -lb_static_lib -Wl,--no-whole-archive -lc_static_lib -lother_shared_object

我不确定 gcc,但对于 g++,我必须添加 --whole-archive 链接器选项以将静态库中的对象包含在共享对象中。 如果您想链接到 libc_static_lib.a 和 libother_shared_object.so,但不将它们作为一个整体包含在 megalib.so 中,则 --no-whole-archive 选项是必需的。

【讨论】:

-Wl--no-whole-archive 在命令行末尾是必需的。见the question edit, here。【参考方案4】:

如果您想关注.as 中的特定对象并且不想自己添加任何内容,ar -x 也很有用。

例子:

ar -x lib***.a
gcc -shared *.o -o lib***.so

【讨论】:

ar -x 不支持解压缩档案列表,因此ar -x lib1.a lib2.a ... 将打印no entry lib2.a in archive。解决方案是:mk extracted; parallel ar --output extracted -x ::: *.a,然后在extracted中运行gcc【参考方案5】:
ar -x lib***.a
gcc -shared *.o -o lib***.so

【讨论】:

这不是取自另一个较早的答案,并且发布的上下文/解释较少吗? 不,那时还没有这样的答案。查看历史。 我可以在网络浏览器中发誓,它显示另一个的日期更早,但在手机应用程序中它显示这个是第一个。抱歉!

以上是关于将静态库转换为共享库?的主要内容,如果未能解决你的问题,请参考以下文章

将静态 windows 库转换为 dll

将静态库转换为DLL会导致在main之前发生访问冲突

将静态库转换为 DLL 在 main 之前导致访问冲突

静态库和共享库

将静态库链接到共享库(例如openmp)是一个好主意

静态与动态库文件