【问题标题】:How do I create .so files with all libraries statically linked into it?如何创建所有静态链接到其中的库的 .so 文件?
【发布时间】:2017-06-27 12:24:59
【问题描述】:

我想创建一个所有库(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?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    静态库不包含 PIC(除非它是专门这样构建的,这在 Linux 上非常罕见;在 Debian 上,我知道的唯一示例是提供给方便构建自定义和扩展libc*so)。

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

    阅读 Drepper 的 How To Write Shared Libraries 了解更多信息,以及 Program Library HowTo

    (在一些理论上奇怪的情况下,你可以链接一个不包含PIC的共享库,但这会使他们的dynamic linking非常慢,因为很多relocations 将被处理,并且它们的code segment 不会在多个进程之间共享-通过ld-linux(8)mmap(2) 的适当调用;这是不推荐 完全没有,很脆,而且经常不能很好地工作;我从来没有这样做过)

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

    不要这样做。我解释了原因。这样做违反了 Linux 上的(社交)规则(因为您的用户不希望拥有无数的 libgmp 变体等......)。

    但是,您可以将共享库与一些以前的其他(更基本的)共享库链接。在你的情况下,我建议这样做。所以要求你的用户已经安装了 GMP 和 PROTOBUF 包。

    考虑同时为您的(或常见的)Linux 发行版提供 packages(例如,为 Ubuntu 或 Debian 提供 .deb 文件)

    或者,将您的库代码发布为free software;然后你可能希望几个用户下载它的源代码,也许(最终)一些发行版会打包它。您可以等待数年才能发生这种情况;或者至少你得到了打包的帮助。

    【讨论】:

    • 谢谢。好的,我知道我不能使用静态文件。我改为尝试这样的运行时搜索路径: gcc -Wall -g -shared -I/usr/local/include -o module.so -fPIC module.c -Wl,-rpath,/usr/local/lib/libprotoc.so .在此之后,module.so 成功创建。但是当加载模块时,它会停止加载并显示“未定义符号:protobuf_c_message_pack”。所以这意味着,图书馆没有在我的 rpath 位置搜索,对吧?注意:我不需要 GMP 来创建这个 .so。它不使用 GMP
    • 我强烈建议您花一天时间阅读 Drepper 的 How To Write Shared Libraries。你需要那里的知识。
    • 好的,我会尽快做的
    猜你喜欢
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多