2

我有一个可以在我的 linux 机器(Ubuntu Karmic)上完美运行的 c++ 代码。当我尝试在另一个版本上运行它时,我缺少各种共享库。

有没有办法将所有共享库合并到单个可执行文件中?

编辑:我想我问错了问题。我应该要求一种方法在我的可执行文件已经构建时对其进行静态链接。我在ermine & statifier中找到了答案

4

6 回答 6

6

缺少共享库的可能原因有 3 个:

  • 您正在使用默认情况下在其他发行版上不存在的共享库,或者您已将它们安装在您的主机上,但没有安装在另一个发行版上,例如 libDBI.so
  • 您在链接时过度指定了版本,例如libz.so.1.2.3,另一台机器具有 API 兼容(主要版本1)但不同的次要版本2.3,如果只有它会链接,它可能会与您的程序一起使用
  • 库的主要版本已更改,这意味着它libc.so.2libc.so.1.

修复是:

  • 不要链接您不需要的库,这些库可能不在不同的发行版上,或者,在其他机器上安装其他库,手动或使它们成为安装程序包的依赖项(例如使用 RPM)
  • 不要在命令行上如此严格地指定版本 - 链接libz.so.1而不是libz.so.1.2.3.
  • 针对不同的 libc 版本编译多个版本。
于 2010-01-26T17:19:48.553 回答
4

您所描述的是使用静态库而不是共享库。

于 2010-01-26T17:13:31.733 回答
2

这里提到的原始问题有几种技术解决方案,例如

针对不同的 libc 版本编译多个版本。

或者

在其他机器上安装附加库

但是,如果您处于 ISV 的位置,那么实际上只有一个明智的解决方案:

获得一个旧系统的全新安装(例如,如果您以桌面为目标,则为 Ubuntu 6.x,如果您以服务器为目标,则可能可以追溯到 Red Hat 9)并在此基础上构建您的软件。通常库(当然还有 libc)是向后兼容的,因此在较新的系统上运行不会有问题。

当然,如果您有非标准或最新版本的 lib 依赖项,这并不能完全解决问题。在这种情况下,正如其他人所建议的那样,如果您想变得健壮,最好使用 dlopen() 并报告问题(或以减少的功能运行)。

于 2010-01-26T19:15:27.680 回答
1

我不太确定,但您可能希望通过静态链接所有库来创建可执行文件。

于 2010-01-26T17:13:52.133 回答
1

一种替代方法是使用动态加载共享库dlopen(),如果加载失败,则优雅地退出并显示可执行文件需要依赖库才能工作的消息。
然后用户可以安装适当的库。

于 2010-01-26T18:52:44.060 回答
1

另一种可能的解决方案是使用 statifier (http://statifier.sf.net) 或 Ermine (http://magicErmine.com) 它们都能够将动态可执行文件和所有需要的库打包到一个自包含的可执行文件中

于 2010-12-13T05:26:03.933 回答