【问题标题】:Portable shared objects?便携式共享对象?
【发布时间】:2010-10-23 01:11:51
【问题描述】:

是否可以像 Windows 中的 DLL 一样以可移植的方式使用共享对象文件?

我想知道是否有一种方法可以为 Linux 提供一个已编译的库,可以立即使用。就像您可以在 Windows 中编译 DLL 一样,它可以在任何其他 Windows 上使用(好吧,不是任何其他的,但在大多数 Windows 上都可以)。

这在 Linux 中可能吗?

编辑:
我刚刚醒来,阅读了答案。有一些非常好的。
我不是想隐藏源代码。我只是想提供一个已经编译好的可以使用的库,所以没有编译经验的用户不需要自己做。
因此,我们的想法是提供一个可以在尽可能多的不同 Linux 上运行的 .so 文件。
该库是用 C++ 编写的,使用 STL 和 Boost 库。

【问题讨论】:

  • 您是否也愿意发布您的库的源代码?编译后的库是否只是你发布的源代码之外的额外便利?
  • 代码不需要。 OP 只需要 de-linter,请参阅我的回答。

标签: c++ linux portability shared-objects shared-libraries


【解决方案1】:

高度 高度建议使用 LSB 应用程序/库检查器。如果您:

  • 正在使用某些发行版上不可用的扩展程序
  • 在安装脚本中引入 bash-isms
  • 使用并非在所有最新内核中都可用的系统调用
  • 依赖非标准库(它会告诉你哪些发行版缺少它们)
  • 还有很多,经过很多其他非常好的检查

您可以获取more information here 以及下载该工具。它易于运行.. 只需解压它,运行 perl 脚本并将浏览器指向 localhost.. 其余部分由浏览器驱动。

使用该工具,您可以轻松获得库/应用 LSB 认证(适用于两个版本),并使发行版打包器的工作更加轻松。

除此之外,只需使用 libtool(或类似工具)之类的工具来确保您的库安装正确,为不想链接 DSO 的人提供一个静态对象(您的库需要一些时间才能出现在大多数发行版中,因此编写一个可移植的程序,我不能指望它存在)并很好地评论您的公共界面。

对于图书馆,我发现Doxygen 效果最好。文档非常重要,它肯定会影响我选择用于任何给定任务的库。

真的,再次检查一下应用检查器,它会为您提供可移植性问题报告,而这些报告可能需要一年的时间才能让图书馆在野外获得。

最后,尽量让您的库易于“放入树中”,这样我就不必静态链接它了。正如我所说,它可能需要几年时间才能在大多数发行版中变得普遍。我更容易抓住你的代码,把它放到 src/lib 中并使用它,直到你的库是通用的。拜托,拜托..给我单元测试,TAP(测试任何协议)是一种很好的便携方式。如果我破解了你的库,我需要(快速)知道我是否破坏了它,尤其是在树或 en situ 中修改它时(如果 DSO 存在)。

【讨论】:

【解决方案2】:

我知道你在问什么。对于 Windows,MSFT 仔细地使 DLL 兼容,因此您的 DLL 通常兼容几乎每个版本的 Windows,这就是为什么您称其为“便携”。

不幸的是,在 Linux 上,有太多的变化(每个人都在想“与众不同”来赚钱),因此你无法获得与 Windows 相同的好处,这就是为什么我们为不同的发行版编译了许多相同的包,发行版,CPU 类型,...

有人说问题是由(CPU)架构引起的,但事实并非如此。即使在同一个拱门上,分布之间仍然存在差异。一旦你真正尝试过发布一个二进制包,你就会知道它有多难——即使是 C 运行时库依赖也很难维护。 Linux 操作系统缺少太多东西,所以几乎每个服务都涉及依赖问题。

通常你只能构建一些与某些发行版兼容的二进制文件(或者,如果你幸运的话,可以构建几个发行版)。这就是为什么以二进制形式发布 Linux 程序总是搞砸的原因,除非绑定到 Ubuntu、Debian 或 RH 等发行版。

【讨论】:

  • 这有点失败主义的态度。 Linux 支持比 Windows 更广泛的体系结构,你无法绕过它。但在单一架构中,发行版几乎完全兼容二进制,前提是您不依赖系统上的其他库或可执行文件等。
  • 显然您还没有看到现实世界,也没有了解他们为什么以及如何这样做。如果你曾经在 Linux 软件公司工作过,你就会知道。
【解决方案3】:

Tinkertim 的回答很到位。我要补充一点,了解和计划对gcc's ABI 的更改很重要。最近情况相当稳定,我猜所有主要发行版都在 gcc 4.3.2 左右。然而,每隔几年,一些change to the ABI(尤其是与 C++ 相关的位)似乎会造成混乱,至少对于那些想要发布跨发行版二进制文件的人和习惯于从其他发行版获取包而不是实际运行的用户来说并发现它们有效。当其中一个过渡正在进行时(所有发行版都按照自己的节奏升级),您最好发布带有 ABI 的库,以支持您的用户使用的所有 gcc 版本。

【讨论】:

    【解决方案4】:

    理想情况下,您需要使用 GNU autoconfautomakelibtool 创建配置和制作脚本,然后将库作为源代码与生成的配置和 Makefile.in 文件一起分发。

    这是关于他们的online book

    ./configure; make; make install 在 Linux 中是相当标准的。

    问题的根源在于 Linux 在许多不同的处理器上运行。您不能像 Windows 那样仅仅依赖支持 x86 指令的处理器(对于大多数版本:Itanium(XP 和更新版本)和 Alpha(NT 4.0)是例外)。

    【讨论】:

      【解决方案5】:

      如果您想通过给他们编译代码来帮助您的用户,我知道的最好的方法是给他们一个静态链接的二进制文件 + 说明他们如何运行二进制文件。 (这可能是除了向他们提供源代码之外。)大多数静态链接的二进制文件适用于相同架构的大多数 Linux 发行版(+ 32 位(x86)静态链接的二进制文件适用于 64 位(amd64))。难怪 Skype 提供静态链接的 Linux 下载。

      回到你的图书馆问题。即使您是在 Linux 上编写共享库的专家,并且您花时间最小化依赖关系,以便您的共享库可以在不同的 Linux 发行版(包括旧版本和新版本)上工作,但也无法确保它能够正常工作在未来(比如说,2 年)。您很可能最终会维护 .so 文件,即一遍又一遍地进行小修改,以便 .so 文件与较新版本的 Linux 发行版兼容。这在很长一段时间内都不是一件有趣的事情,并且会大大降低您的工作效率:您花在维护库兼容性上的时间会更好地花在例如提高软件的功能、效率、安全性等。

      还请注意,提供 .so 格式的库很容易让您的用户感到不安,这在他们的系统上不起作用。 (而且你没有超能力让它在所有 Linux 系统上运行,所以这种情况是不可避免的。)你是否也提供 32 位和 64 位,包括 x86、PowerPC、 ARM等?如果 .so 文件仅适用于 Debian、Ubuntu 和 Red Hat(因为您没有时间将该文件移植到更多发行版),那么您很可能会让您的 SUSE 和 Gentoo 用户(以及更多)感到不安。

      【讨论】:

      • 对不起,我还没有完全理解这个静态和动态链接的东西。是否可以在运行时(即动态)链接/加载静态库(.a 文件)?或者只是 .so 文件可以动态链接/加载?
      • 您可以在编译时将 .a 文件的内容添加到可执行文件中(这称为静态链接)。您可以告诉您的可执行文件在开始运行时从 .so 文件中获取一些代码(符号)(这称为动态链接)。无法动态加载 .a 文件。无法在编译/链接时将 .so 文件的内容添加到可执行文件。可以将一些库静态链接(如果您有 .a 文件)和一些库动态链接(如果您有 .so 文件)到同一个可执行文件。没有动态库的可执行文件是静态可执行文件。
      【解决方案6】:

      那么,问题来了,如何为 Linux 开发共享库?您可以查看this tutorialthe Pogram Library Howto

      【讨论】:

      • 不,他不是。他在问如何删除/避免 SO 中的静态版本依赖。
      【解决方案7】:

      只需将 .so 文件放入 /usr/lib可能 工作,但您可能会弄乱您的发行版用于管理库的方案。

      看看 linux 标准库 - 这是您会发现的最接近 linux 发行版中的通用平台的东西。

      http://www.linuxfoundation.org/collaborate/workgroups/lsb

      你想完成什么?

      【讨论】:

      • 嗯,有不用公布源码的方便,也有编译的麻烦。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 2011-02-01
      • 2011-02-20
      • 2016-06-20
      • 2011-03-06
      相关资源
      最近更新 更多