Linux的可移植.so库

3
我正在编写一个与图形相关的Python应用程序,依赖于PySDL2库。 PySDL2依赖于编译的SDL2二进制库,可以从SDL网站下载。 我编写了一个引导脚本来自动化这个过程,但它仅适用于Windows,因为Linux没有二进制下载。
问题是如何在Linux上进行二进制SDL2下载?
无法确定是否有可能创建在所有Linux上都能工作的.so文件,因为在每个CPU上都能工作的.so文件是不可能的。这主要是因为尚不清楚是否已经朝着这个方向做了任何工作(我相信人们已经试图研究这个问题),如果有的话,为什么没有采用可移植的.so文件格式(跨不同发行版和CPU的平台)。

更新:我不介意在用户空间安装具有更新和安全修复程序的依赖项(软件包),但这应该以可移植的脚本自动化。

2个回答

4

不要这样做。

最可靠的方法是创建一个完整的 静态构建 库堆栈。

但这会让你的应用程序变得非常臃肿,如果这些库中出现任何安全问题,你将需要自己更新并且所有用户都需要重新下载。

通过使用发行版提供的 SDL 库,你的应用程序将受益于由 Linux 社区 进行的 SDL 修复和更新

考虑为最常见的发行版(即 Debian、Ubuntu、Redhat、Fedora)提供包,然后在这些包上具有适当的依赖关系,以使用发行版提供的 SDL 库。

当你看 Skype、Google 等公司如何分发他们的二进制文件时,它们总是以特定于发行版的软件包形式提供,这些软件包可以与系统库一起工作。例如 Skype:

Depends: libasound2 (>= 1.0.16), libc6 (>= 2.3.6-6~), libc6 (>= 2.7),
  libgcc1 (>= 1:4.1.1), libqt4-dbus (>= 4:4.5.3), libqt4-network (>= 4:4.8.0),
  libqt4-xml (>= 4:4.5.3), libqtcore4 (>= 4:4.7.0~beta1), libqtgui4 (>= 4:4.8.0),
  libqtwebkit4 (>= 2.1.0~2011week13), libstdc++6 (>= 4.6), libx11-6, libxext6,
  libxss1, libxv1, libssl1.0.0

如您所见,Skype并未包含所有库文件。在安装Skype时,用户可能需要依赖其包管理器来解决这些依赖关系。
此外,Linux用户非常不愿意下载或安装二进制文件。如果您真的想让人们使用您的应用程序,最好将其开源并由某个人将其包含在主要Linux发行版中。 Linux不是Windows。 Linux上几乎没有病毒的原因之一是因为大多数人不会下载不受信任的软件。

是的 - 我的应用程序是开源的 - 在这里 - https://bitbucket.org/techtonik/discovery/src/tip/graphics/pysdl2/?at=default =) - anatoly techtonik
总之,这个解决方案不具备可移植性。有没有办法改进呢? - anatoly techtonik
我真的很怀疑我的应用程序是否会被包含在Linux发行版中,因为它太过复杂,即使是安装一个现有软件包的新版本都很困难。 - anatoly techtonik
我经常自己构建新的软件包。大多数情况下构建很简单,你的问题表明你尝试的方法过于复杂了。许多软件包可以通过debhelper自动打包,然后debian/rules文件只包含一个规则,即:“%:dh $@”,也就是“让debhelper处理一切”。 - Has QUIT--Anony-Mousse
对于Linux用户来说,“用户友好”意味着:“已经随我的发行版提供,不需要我从网络上某个不明确的地方运行不受信任的.exe文件”……你可能需要等待pySDL2可用,然后用户可能就不再需要信任你的任何.so文件了。 - Has QUIT--Anony-Mousse
显示剩余4条评论

3
关于CPU架构,Linux不支持Fat Binaries(一个二进制文件包含多个架构的情况,例如OS X中有此功能)。Ryan Gordon提出了一个名为Fat ELF的提案,但遗憾的是未被采纳。
在SDL2的特定情况下,默认情况下该库仅链接到非常少量的库:

ldd /usr/local/lib/libSDL2.so

    linux-vdso.so.1 =>  (0x00007fffd1f0b000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f414c44e000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f414c24a000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f414c02c000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f414be24000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f414ba5c000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f414cac4000)
SDL所依赖的其余二进制文件是动态加载的(使用dlopen),而且SDL非常适应特定二进制文件的不同版本。因此,简而言之,如果您在某个具有特定版本的libc、libpthread等系统中编译,并设法找到具有兼容二进制文件的不同系统,则有很大机会至少运行SDL二进制文件。实际上,最好依赖于系统提供的二进制文件,或者接受您将使用自定义的SDL2支持一组有限的发行版的事实。
请注意,此限制也适用于静态链接SDL!如果您认为可以继续添加静态链接的二进制文件,直到制作出一个几百兆字节的静态球在任何地方都能运行(就像我做的那样!),那么还有其他限制会阻止您这样做,从许可问题到由于静态链接libpthread而导致的段错误。

这很遗憾,但我想这和Windows上的.dll情况一样糟糕。我认为该操作系统上的系统库是向后兼容的,Linux也应该是如此,对吧?至少我可以尝试构建这个.so文件,如果无法启动,就说:“抱歉,伙计,请找出如何为您的系统编译SDL2 + PySDL”。有没有其他提示可以增加可移植性百分比?静态链接是否有帮助? - anatoly techtonik
我认为你有两个主要的选择,一个是创建一个软件包(Debian/Ubuntu 的 .deb 软件包,Fedora 的 RPM 软件包等),并将 SDL2 列为依赖项(以及 Python 2 或 3,以及最终用户需要安装的其他内容)。或者你可以制作一个安装脚本,下载、编译和安装 SDL2,如果你使用标准的 Pythonic 方式来做这件事情会更好(这就是 PySDL2 所做的:https://pypi.python.org/pypi/PySDL2/0.8.0) - gabomdq
如果你采用打包的方式,操作系统会自动为你处理root权限。如果你编写Python distutils脚本,你可以在没有root权限的情况下进行安装(例如使用virtualenv),但我认为一般用户知道他们必须使用sudo进行安装。 - gabomdq

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