【问题标题】:Portable .so library for Linux适用于 Linux 的便携式 .so 库
【发布时间】:2014-01-13 15:06:35
【问题描述】:

我正在编写一个 Python 应用程序,它使用图形并依赖于 PySDL2 库。 PySDL2 依赖于编译的SDL2 二进制库,可以是downloaded from SDL site。我写了一个bootstrap script to automate the process,但它只适用于Windows,因为Linux 没有二进制下载。

问题是如何为 Linux 下载二进制 SDL2?

目前尚不清楚是否有可能创建适用于所有 Linux 的 .so 文件,是否是因为不可能创建适用于每个 CPU 的 .so 文件,这主要是因为它是不清楚是否已经在这个方向上做了任何工作(我相信人们试图研究这个问题),如果是,那么为什么不采用可移植 .so 文件的格式(针对不同发行版和 CPU 的跨平台)。

更新:我不介意安装包含 Linux 社区提供的更新和安全修复程序的依赖项(包),但这应该在用户空间中完成,并且我需要能够使用可移植脚本。

【问题讨论】:

    标签: python linux shared-libraries sdl-2 pysdl2


    【解决方案1】:

    不要这样做。

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

    但这会使您的应用程序完全膨胀,如果这些库中存在任何安全问题,您需要自己更新,并且您的所有用户都需要重新下载。

    通过使用发行版提供的 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 上很少有病毒的原因之一是因为大多数人不下载不受信任的软件。

    【讨论】:

    • 好的。我怎样才能在用户空间做到这一点?当我下载 .dll 时,我不需要 root 权限来运行二进制文件,并且使用 Linux 社区构建的包,用户需要 root 权限才能运行它。我也不知道如何告诉用户命令它需要为他的平台运行,这会扼杀所有的乐趣并破坏体验。最终用户应该下载并运行我的程序 - 不要花 10 分钟尝试获取所有依赖项。所以我想自动化这一步。
    • 是的 - 我的应用是开源的 - 它在这里 - bitbucket.org/techtonik/discovery/src/tip/graphics/pysdl2/… =)
    • 综上所述,解决方案不可移植。有什么好办法吗?
    • 我真的怀疑我的应用程序是否会包含在 Linux 发行版中,因为它是 way too complicated 甚至安装现有软件包的更新版本。
    • 我经常自己构建新包。大多数都是微不足道的,你的问题表明你正在尝试一种过于复杂的方法。 debhelper 可以自动打包很多包,然后debian/rules 文件包含一条规则,%: dh $@,又名:“让 debhelper 处理所有事情”。
    【解决方案2】:

    关于 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”。是否有任何其他提示如何提高可移植性百分比?静态链接有帮助吗?
    • 我认为您拥有的两个主要选择是创建一个包(用于 Debian/Ubuntu 的 .deb 包,用于 Fedora 的 RPM 等),并将 SDL2 列为依赖项(连同 Python 2 或3,以及最终用户需要安装的任何其他内容)。或者您可以制作一个下载、编译和安装 SDL2 的安装脚本,如果您使用标准的 Pythonic 方式会更好(这就是 PySDL2 所做的:pypi.python.org/pypi/PySDL2/0.8.0
    • 如果您采用打包方式,操作系统会为您处理 root 权限。如果你制作 Python distutils 脚本,你可以在没有 root 权限的情况下安装(例如使用 virtualenv),但我认为一般用户都知道他们必须使用 sudo 安装。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    相关资源
    最近更新 更多