如何创建静态链接到所有库的.so文件?

时间:2017-06-27 12:24:59

标签: c linker shared-libraries static-linking protobuf-c

我想创建一个.so文件,其中所有库(GMP和PROTOBUF)都静态链接到它,以便它可以在其他系统中使用,而无需安装这些库。

这就是我为MAC所做的:

gcc -I /usr/local/include -shared -o xyz.so -g xyz.c /usr/local/lib/libprotobuf-c.a /usr/local/lib/libgmp.a

但它不适用于Linux。我怎样才能使它适用于Linux?

1 个答案:

答案 0 :(得分:2)

共享library应该(在Linux上)实际上包含position-independent code(PIC)。因此,从单个源文件libxyz.so构建共享库xyz.c的正确方法是

gcc -Wall -g -shared -I/usr/local/include -o libxyz.so -fPIC xyz.c

(您可以 - 并且可能想要添加rpath相关选项)

静态库不包含PIC(除非它是特别构建的,这在Linux上非常罕见;在Debian上我知道的唯一例子是特殊的{{1}提供的包用于促进自定义和扩展libc6-pic)的构建。

您需要链接这些库的PIC变体;所以你应该从他们的源代码构建它们。

阅读Drepper' How To Write Shared Libraries了解更多内容,以及Program Library HowTo

(在一些理论奇怪的案例中,您可以链接一个不包含PIC的共享库,但这将使他们的{{ 3}}非常慢,因为很多dynamic linking会被处理,并且relocations不会在多个进程之间共享 - 通过code segmentmmap(2)进行适当的调用3}};这是根本不推荐,非常脆弱,经常不能很好地工作;我从来没有这样做过)

  

我想创建一个.so文件,其中所有库(GMP和PROTOBUF)静态链接到其中

不要这样做。我解释了原因。这样做违反了Linux上的(社交)规则(因为你的用户不想拥有数以万计的libgmp等等......)。

但是,您可以将共享库与之前的其他(更基本的)共享库链接起来。在你的情况下,我建议这样做。因此,要求您的用户安装GMP和PROTOBUF软件包。

考虑为您的(或常见的)Linux发行版提供ld-linux(8)(例如,Ubuntu或Debian的packages文件)

或者,将您的库代码发布为.deb;你可能会希望有几个用户下载它的源代码,也许(最终)某些发行版会打包它。你可以等待数年才能实现;或至少你得到帮助打包它。