为什么gcc不支持将动态库链接到静态二进制文件中

3
背景如下:有第三方提供程序库veryfancylib.so,为32位。使用该库的软件有许多其他Linux库依赖项(如QT),但它们是开源的,因此静态链接没有问题。目标平台是64位并运行Debian 7。
我们可以通过二进制文件和动态库来提供程序,没有问题,但我更想看到没有依赖关系的单个静态二进制文件。
那么我的问题是:为什么我不能将动态库链接到静态二进制文件中?我的意思是缺少哪部分信息,或者它只是很少需要的功能->未实现。

1
虽然可能性存在,但GCC可能不支持它,因为涉及许可问题。在法律术语上,链接动态库和链接静态库是两回事。所以我猜,如果你是所有者,通过编译源代码可以轻松创建任何库。但只有动态库可能意味着你将要做一些不太合法的事情。这只是一个猜测... - GreenScape
能否将so文件与可执行文件打包,并使用dlopen或类似的方式动态加载它?只是在思考... - Łukasz Daniluk
是的,对库进行dlopen包装应该可以解决问题--并且可以自动化为生成wrapper.c的Python脚本,但正如问题尝试的那样,为什么不一开始就在编译器中做这个呢? - susundberg
你不能向第三方请求一个静态库吗? - Christoph
3个回答

1
我们可以使用二进制文件和动态库来发送程序,没有问题,但我宁愿看到单个静态二进制文件而没有依赖项。
你试图解决的问题是什么?
您可以按照Linux上大多数商业应用程序的模式进行操作:将可执行文件、共享库和其他资源放在一个目录中(可能带有子目录)。在将可执行文件链接到这些共享库时,向链接器传递 -Wl,-rpath,'$ ORIGIN'(在make中使用-Wl,-rpath,'$$ ORIGIN'),以便在启动应用程序时运行时链接器在与可执行文件相同的目录中查找所需的共享库。
然后归档该目录并将其提供给用户。

当然,你是正确的,你提出的建议比我们现在使用的更好,但它并没有回答我尝试提出的问题:“为什么gcc不将动态库链接到静态可执行文件中” - 是像建议的那样因为许可证问题,还是开发人员对这种功能缺乏兴趣,或者甚至存在技术上的“不能做到”(我想不是这个原因)。 - susundberg

0

这是因为动态库和静态库是两个不同的东西。静态库只是一个对象文件的存档(就像 zip 存档一样)。动态库更像一个可执行程序。

所以你不能真正地将任何东西“链接”到静态库中,你只能添加更多的对象文件。


是的,它们具有不同的性质,但既然字节码和符号表都在那里,真的有什么阻止我从动态库生成静态二进制文件(可执行文件)的吗?我的意思是,我可以做一个dlopen包装器,这应该可以正常工作,对吧? - susundberg
动态库更像是一个可执行文件,具有数据和代码段等。静态库是一个存档文件,再次类似于 zip 或 tar 存档。静态库不包含数据或代码段,它没有 ELF(例如 Linux)头,没有任何重定位信息,也没有符号列表,只有存档内部的目标文件列表。 - Some programmer dude
@JoachimPileborg:如果动态链接器有足够的信息来连接所有内容,那么创建等效目标文件的静态工具也应该有这些信息;仅仅因为我们无法重新创建原始的目标文件(如果有足够的调试信息,我们可能可以这样做),并不意味着我们不能得到一些在操作上同样好的东西... - Christoph

0

有一些适用于 MS Windows 的程序能够实现这样的功能,例如 DLL to LibDLL to Static Lib

在开源领域中,并不存在太多的动力来开发这样的工具,因为您总是可以从源代码重新编译(但当然也可能某个地方有人已经这样做了)。


澄清一下:你的意思是我的问题的答案是“gcc不支持这种功能,因为这种功能是不需要的”。 - susundberg
1
@susundberg: 没错,这对于开源软件来说不是问题,商业供应商可能会反对有人搞乱他们的二进制数据块,而自由软件运动也希望阻止使用封闭源代码软件。 - Christoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接