依赖地狱:为什么不创建可移植的应用程序

nul*_*ter 5 distribution-choice package-management unix-philosophy distributions

回到我使用 Windows 的时代,应用程序是以独立的方式安装的。这为最终用户/系统管理员提供了很大的自由来决定升级什么和在哪里,什么时候打补丁,而不会干扰其他应用程序。

在 *NIX 中,纠缠的依赖是一个令人头疼的问题。PC-BSD 试图通过PBI克服这个问题,通过创建独立的应用程序。AFAIK,这现在似乎已被弃用,他们回到了包管理方式(PBI 现在是端口的包装器),并且所有 Linux 发行版都朝着同一个方向运行:到最后有数百个依赖项,甚至桌面环境也有望依赖关于系统管理守护进程

基于数百个依赖项构建应用程序使程序员的生活更轻松,但给最终用户和系统管理员带来了令人震惊的问题。例如,我不能再让一个古老的 Debian Etch 版本的应用程序在 Debian Jessie 中运行。我知道很多人都会谈到安全、补丁和最新系统的故事,但开源意味着可以自由决定更新什么、何时何地更新。有非常正当的理由不更新系统或其中的一部分,或者至少不按照典型的 *NIX 包管理器引导用户的方式进行更新(即离线工作的机器、旧硬件、与需要更新的旧数据的兼容性)保持合规性,...)。其他时候,系统管理员更喜欢分几个步骤来确保安全。

就个人而言,我认为我作为系统管理员应该决定更新什么,何时更新,并承担风险。以目前的情况,这是不可能的。(即在 Debian 中有一个新版本的 libc6,这在任何地方都有依赖关系)。如果我决定保留两个或更多存储库来解决这个问题,我就会产生另一个噩梦。

我知道某些依赖项(即安装了 MySQL)是可以接受的,因为这是一个主要的依赖项,但我不明白为什么像库这样的小依赖项不简单地嵌入到代码中。磁盘便宜。许多移植到 Windows 的 Linux 应用程序都实现了这一点。

编辑:以确保它不仅仅是基于意见

在 *NIX 中安装软件的选项有哪些(为了简单起见,我们将其称为 Debian/FreeBSD)以便:

  • 保持软件的某个特定版本运行多年而无需升级,并确保无论后续的基本操作系统和库升级如何,都可以保持不变,ala apt-get hold但永远。

  • 决定在不与其他软件/库冲突的情况下升级/降级。

  • 安装该软件的两个或更多版本。

Jails/chroot/VM 不是选项,尽管它们是明显的解决方法。还,

  • 是什么让 PBI 未能实现返回端口/包管理的独立性目标?

sai*_*895 6

我无法回答为什么 PBI 没有成功,但我可以回答为什么 Linux 中首选共享库。

主要论点安全性,即如果常用库中存在漏洞,则只需更新该库,而不是所有使用该库的应用程序(由于 ABI 兼容性)。这也意味着(如果您主要坚持主存储库和 PPA(在 Ubuntu 的情况下)),您不必安装 4 个不同版本的库,因为您的应用程序是针对这些版本编译的(例如 Windows ,您可能在其中安装了不同版本的 .NET 库,或安装了不同版本的 Visual C++ 运行时)。

尽管如此,在某些情况下,应用程序可能不会被强制使用库的系统版本,而是可以使用它们自己的版本。例如,Chromium 依赖于大多数发行版存储库中存在的许多库。在正常情况下,应用程序会被编译,以便它们使用的库是发行版编译的库。但是,在 Ubuntu 中(至少),Chromium 是用它自己的库版本编译的,因为:

  • 使用系统版本的库意味着必须为每个版本的 Ubuntu 测试 Chromium。
  • Chromium 在很大程度上已经使用了最新版本的库,这意味着存在漏洞的可能性要低得多。

至于磁盘空间参数,您可能会争辩说,安装debootstrapDebian Jessie 的 ed 版本需要不到 1 GB 的磁盘空间,因此非常适合较小的 SD 卡。另一方面,Windows至少需要几 GB 的磁盘空间。

对于较旧的软件,您可以静态编译应用程序,并且大部分依赖项都是独立的。但是,因为您的发行版可能没有可用的库的静态版本(Debian 和 Ubuntu 在大多数情况下没有),您需要自己编译这些库以获取这些库的静态版本。

最后,Unix 的原则之一是每个应用程序只做一件事,并且擅长它。如果应用程序和库是静态链接的,那么它们可能被认为是(间接)做很多事情。