【问题标题】:Compile a shared library statically静态编译共享库
【发布时间】:2010-05-11 15:39:55
【问题描述】:

我有一个包含一些自制函数的共享库,我将其编译到我的其他程序中,但我必须将最终程序与我用来编译静态库的所有库链接起来。这是一个例子:

我在库中有函数 foo,它需要来自另一个库 libbar.so 的函数。

在我的主程序中使用函数foo 我必须用-lbar 标志编译它。有没有一种方法可以静态编译 my 库,使其包含来自其他库的所有必需代码,并且我可以在不需要 -lbar 标志的情况下编译我的最终程序?

【问题讨论】:

  • 您能否明确说明正在使用的平台?理想情况下,它们会在标签中。
  • 旁注;您不仅不必使用 -lbar,而且一旦开始,您的链接器将删除所有 your 代码未引用的符号(直接或间接通过您的调用链)。这将缩小您的可执行文件并帮助您的应用更快地启动!

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


【解决方案1】:

共享对象 (.so) 不是库,它们是对象。您不能提取其中的一部分并将其插入到其他库中。

如果构建一个引用另一个的共享对象,你可以做什么——但在运行时需要另一个。只需在链接 libfoo 时添加 -lbar。

如果你能够构建 libbar,你显然可以创建一个 libfoo 和 libbar 组合的库。 IIRC,您还可以通过将 .a 与要进入 libbar 的 .o 链接,使链接器构建一个 libfoo 和 libbar 所需部分的库。示例:

gcc -fPIC -c lib1.c     # define foofn(), reference barfn1()
gcc -fPIC -c lib2a.c    # define barfn1(), reference barfn2()
gcc -fPIC -c lib2b.c    # define barfn2()
gcc -fPIC -c lib2c.c    # define barfn3()
gcc -c main.c           # reference foofn()
ar -cru libbar.a lib2*.o
gcc -shared -o libfoo.so lib1.o -L. -lbar
nm libfoo.so | grep barfn2()    # ok, not here
gcc -o prog main.o -L. -lfoo
env LD_LIBRARY_PATH=. ./prog    # works, so foofn(), barfn1() and barfn2() are found

【讨论】:

    【解决方案2】:

    第 1 步(创建目标文件):

    gcc -c your.c -o your.o
    

    第 2 步(创建静态库):

    ar rcs libyour.a your.o
    

    第 3 步(链接到静态库):

    gcc -static main.c -L. -lyour -o statically_linked
    

    【讨论】:

      【解决方案3】:

      您可以使用libtool 来实现这种功能,请参阅libtool manual on Inter library dependencies 了解其工作原理的示例

      【讨论】:

        【解决方案4】:

        基本上,如果您拥有静态库所依赖的系统库的静态链接库,则可以静态链接其中的所有代码。

        不过,我不确定为什么。 *NIX 平台对共享库的处理是一项天才的工作,并且大大减少了编译程序的大小。如果您担心由于缺少库而无法在另一台计算机上运行代码,那么您始终可以采用大多数为 Linux 库编译的闭源程序的路径:只需使用 GCC 的-Wl,--rpath -Wl,. 选项编译它们,然后将库与二进制文件一起分发。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-03-06
          • 2023-03-11
          • 1970-01-01
          • 2010-10-03
          • 2017-08-03
          • 2011-12-09
          • 1970-01-01
          相关资源
          最近更新 更多