我想创建一个所有库(GMP 和 PROTOBUF)静态链接到其中的 .so 文件,以便它可以在其他系统中使用而无需安装这些库。
这就是我为 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?
我想创建一个所有库(GMP 和 PROTOBUF)静态链接到其中的 .so 文件,以便它可以在其他系统中使用而无需安装这些库。
这就是我为 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?
共享库应该(在 Linux 上)实际上包含与位置无关的代码(PIC)。libxyz.so
因此,从单个源文件构建共享库的正确方法xyz.c
是
gcc -Wall -g -shared -I/usr/local/include -o libxyz.so -fPIC xyz.c
(你可以 - 并且可能想要 - 添加rpath相关选项)
静态库不包含 PIC(除非它是专门构建的,这在 Linux 上非常少见;在 Debian 上,我知道的唯一示例是libc6-pic
为便于构建自定义和扩展而提供的特殊包libc*so
)。
您需要链接这些库的 PIC 变体;所以你应该从他们的源代码构建它们。
阅读 Drepper 的How To Write Shared Libraries了解更多信息,以及Program Library HowTo。
(在一些理论上奇怪的情况下,您可以链接一个不包含 PIC 的共享库,但这会使它们的动态链接非常慢,因为会处理大量重定位并且它们的代码段不会被共享 - 之间几个进程——通过ld-linux(8)对mmap(2)的适当调用;这根本不推荐,非常脆弱,而且通常不能很好地工作;我从来没有这样做过)
我想创建一个 .so 文件,其中所有库(GMP 和 PROTOBUF)都静态链接到其中
不要那样做。我解释了原因。这样做违反了 Linux 上的(社交)规则(因为您的用户不希望拥有无数的 libgmp 变体等......)。
但是,您可以将共享库与一些以前的其他(更基本的)共享库链接。在你的情况下,我建议这样做。所以要求你的用户已经安装了 GMP 和 PROTOBUF 包。
还考虑为您的(或常见的)Linux 发行版提供软件包(例如.deb
Ubuntu 或 Debian 的文件)
或者,将您的库代码发布为免费软件;然后你可能希望几个用户下载它的源代码,也许(最终)一些发行版会打包它。您可以等待数年才能发生这种情况;或者至少你会得到帮助来打包它。