【问题标题】:Does python + pyinstaller support multiple OS/Versions of linux?python + pyinstaller 是否支持多个操作系统/版本的 linux?
【发布时间】:2025-11-23 04:20:17
【问题描述】:

我在 python 中编写了几个小脚本,并使用 pyinstaller 构建了二进制文件。

当我在我的 Ubuntu 16.04 机器上构建它们时——它们会在我构建它们的机器上运行良好。但是将文件移动到 Centos / Redhat 7.4 机器会给我 GCLIB 和其他 .so 版本依赖错误。

  • 使用相同版本的 Centos 在 docker 上构建相同的二进制文件不会出现这些错误。
  • 如果我尝试在 Centos 6.6 上运行在 Centos 7.4 上编译的二进制文件,我会再次遇到错误 -- 但在 Centos 6.6 上构建它可以在 Centos 6.6 上正常工作

我现在已经使用较低版本的 Centos 来构建我的二进制文件解决了这个问题。

  • 我的具体问题是——在 Python 中,它是基于目标操作系统(仅假设 linux 目标)在不同操作系统上构建二进制文件的常用方法,还是我正在做的是 hack/坏解决这个问题的方法?

我正在尝试了解如何以标准方式解决此问题。

【问题讨论】:

  • Pyinstaller 在 Linux 上并不是什么大事。 Windows 作为目标操作系统更为常见。在 Linux 上,更多的包是通过pip 安装的,它也负责二进制依赖。但是它们是有问题的,因为需要安装完整的构建系统和库。有像 Docker 或 AppImage(以及更多)这样的系统以空间为代价来解决这个问题。
  • 你需要你的脚本是二进制文件吗?因为如果没有,那么你的问题实际上已经解决了。如果需要,您仍然可以为 Windows 构建。或者您可以阅读snap 之类的软件包。
  • 这些是脚本,但它们有时可能需要连接到数据库,然后使用外部库。目标服务器无法访问 Internet。这让我可以选择构建二进制文件并与运营团队共享。提供一个完整的依赖文件夹(我不确定它是否总是有效)或设置一个 pip repo(服务器没有互联网访问权限)。阅读@Brian Campbell 的回复。 Docker 似乎是一种合理的方式,可以让操作更轻松。

标签: python linux pyinstaller software-distribution


【解决方案1】:

只要 pyinstaller 生成的二进制文件只依赖于 glibc,那么它应该是在可用的最旧系统上构建它的有效方法,并且它应该可以在未来的系统上运行。

一般而言,glibc 被设计为向后兼容,因此针对旧版本 glibc 构建的应用程序仍可使用新 glibc 运行,但反之则不行。它通过符号版本控制来做到这一点,其中您链接到的每个符号都可以有一个与之关联的版本,并且在任何情况下,较新的 glibc 更改了某些函数的 ABI,它还将具有与旧 ABI 公开的兼容性例程使用旧符号版本,以便与旧符号版本链接的应用程序将与兼容性例程动态链接,而如果您有一个与较新符号版本链接的应用程序,则旧 glibc 中不会有较新版本动态链接到。

虽然其他库也可以做到这一点,但没有多少库作者愿意这样做,因此较新的版本可能根本不兼容,而 glibc 开发人员通常会尝试保持兼容性。

所以是的,只要最终的二进制文件只链接到 glibc,或者其他遵循类似符号版本控制方案的库,以确保旧的二进制文件仍然可以正确链接到新版本的库,构建它是完全有效的针对旧版本,然后在各种 Linux 发行版的较新版本上运行它,甚至通常也可以跨发行版运行。

不幸的是,如果链接到较新的 glibc,则没有好方法让链接器选择较旧的符号版本,因此最简单的方法通常是在 Docker 或其他包含较旧发行版的容器中您希望与之兼容的最旧的 glibc。

【讨论】:

  • docker 在这里可能有点矫枉过正。 snap呢?
  • 很公平。回答我的问题。谢谢! :)
  • @MarcinOrlowski 这就是我提到“或其他类型的容器”的原因。使用您选择的容器或构建系统技术,无论是dockersnappbuilder,还是其他。只要您可以使用它来针对您希望支持的最古老的发行版运行构建过程,您就可以了。
  • 我的意思是 docker 不如 snap 更适合 OP 需求。并非所有容器技术都相同,而是名称不同。
最近更新 更多