1.“传统软件包”是指使用包管理器发布的图形应用程序,而不使用容器,如apt、dnf、pacman等。
2.“发行模式”是指发行过程,如常年支持版(LTS)、稳定版和开发版等。
3.“类似的应用程序”是指两个在技术上真正相像的应用程序,如和。
4.在这种事例中,我将使用ArchLinux作为参考。但是,这种行为与这些大量采用传统软件包格式的发行版是一致的。
5.Nix不使用容器,它也不是一种容器格式。但为了简单起见,我暂时把它称为一种容器格式。
根本问题
图片来源:来自的
大多数(其实不是全部)大量采用传统软件包格式的发行版都有这个共同的问题:它们都没有借助容器或其他便捷的方式来分离依赖关系。用浅显的话说,容器是一个袋子,我们可以把东西放到上面,在不影响主系统(主机)的情况下单独使用它们。
容器一般不会影响“盒子”外的任何东西。但是它们是可移植的,由于它们可以安装在其他发行版上,同时提供一致的体验。借助容器的包管理器会将每位软件包安装在不同的容器中,这提供了一个额外的安全层。这给了开发者更多的控制权和灵活性,她们可以决定在软件包内捆绑哪些。
传统的软件包格式形成了一些问题,例如依赖性和包的冲突,这种问题一般须要解决,而不同的发行版有不同的解决办法。
依赖性和软件包的冲突
假如我们企图安装(),而()早已安装在ArchLinux上,我们会碰到这个问题:
$paru-Svisual-studio-code-bin
[...]
::Conflictsfound:
visual-studio-code-bin:code
::Conflictingpackageswillhavetobeconfirmedmanually
Aur(1)OldVersionNewVersionMakeOnly
aur/visual-studio-code-bin1.70.1-1No
这就是所谓的软件包冲突,即两个或多个软件包不能共存。在这些情况下,我们不能同时安装VisualStudioCode和Code-OSS。
当两个应用程序或软件包提供相同的文件linux系统安装,具有相同的名称,并被放置在同一目录下,这么它们实际上是不能共存的,由于这种文件会发生冲突。在这个事例中,VisualStudioCode和Code-OSS都提供了一个名为code的文件,它们都被置于/usr/bin中。VisualStudioCode提供的code文件用于启动VisualStudioCode,而Code-OSS的code文件则用于启动Code-OSS。其实这个事例只展示了VisualStudioCode和Code-OSS,但这些情况常常发生在不同的应用程序、库和其他软件中。
难以选择依赖项
图片来源:来自的
传统软件包格式的最大问题之一是node.js安装linux,打包者不能选择依赖项。
比如,假若一个应用程序近来更新,须要依赖版本1的程序A,但发行版只提供了版本0.9的程序A,这么对于升级该应用程序来说就不太理想,由于发行版未能满足要求。这意味着打包者将不得不暂缓打包,直至该发行版发布新的依赖项,或则采用变通的方式。
同样,假如一个应用程序须要依赖0.8.1版本的程序A,但发行版却只提供了0.9版本的程序A,这么这个应用程序都会表现失常,甚至完全不能运行。
带补丁的库和编译配置
为了扩充,一些应用程序须要带补丁的库或额外的编译配置就能正常运行。诸如,OBSStudio须要一个来与OBSStudio更好地整合。
在传统的软件包格式下,一次只能安装一个依赖项的变体。假如发行版提供的是未打过补丁的FFmpeg,这么就没有办法安装打过补丁的FFmpeglinux 系统格式,除非打包者能解决这个问题。假如安装了打过补丁的FFmpeg,但另一个程序高度依赖未打过补丁的FFmpeg、打过其他补丁的FFmpeg、内置或删掉了其他功能的FFmpeg,这么其他程序都会出现bug。
现代应用程序本质上是脆弱的。依赖关系树中的一个小错误或不一致,都会造成应用程序的bug,使用户体验恶化,甚至会让人感觉是应用程序的问题,而不是软件包本身的问题,这都会阻碍应用程序的名声。
变通方式
让我们瞧瞧目前开发者拿来打包应用程序的变通方式:
1.第一种解决方式是在不同的目录中安装依赖库。诸如,Electron是一个巨大的框架,开发者用它来建立应用程序,之后将它们捆绑上去。但是,基于Electron的应用程序是不同的,由于它们是构建在不同版本的Electron之上的。Discord捆绑了Electron13,而Element捆绑了Electron19。对于ArchLinux上的Electron打包,个别目录须要安装在/opt/APPLICATION_NAME中,所以这种Electron版本。
2.第二种解决方式是篡改应用程序。诸如,给应用程序打上补丁,使其在没有个别依赖库或功能的情况下编译linux 系统格式,这可以使应用程序成功编译,但不能保证该应用程序才能启动或按预期工作。
3.第三种解决方式是在编译应用程序时禁用许多编译选项,这也可能禁用一些功能。比如,在ArchLinux上,OBSStudio在编译时禁用了许多基本功能,这。
这种解决方式因人而异,有些会限制应用程序的功能,有些会引入稳定性问题等等。
不一致的体验
图片来源:来自的
尽管这种技术限制在整个传统软件包格式中是一致的,但用户体验常常不是这样。因为软件包的发布形式,发行模式与传统软件包格式相结合会影响用户体验。
一些发行版,如ArchLinux,接近于开发版,因而有最新版本的软件包。但是Debian和UbuntuLTS是LTS常年支持版,所以它们的好多软件包都落后几个版本。同时,FedoraLinux和Ubuntu稳定版处于Debian/UbuntuLTS和ArchLinux之间。
一些软件包格式喜欢尽可能少地给软件包打补丁,以保持它们最接近原版;而另一些格式打补丁是为了降低更多的功能,使用旧库或进行其他类型的修改,以改善用户体验。一些格式喜欢使软件愈发轻量化;而另一些格式更喜欢尽可能地添加更多外置功能。软件包有各类各样的习惯和偏好。
正如我们所见到的,一个应用程序在不同的发行版中的建立方法十分不同。据悉,不同的发行版的依赖关系也是不同的。传统软件包格式的许多技术限制须要依照发行模式和打包策略采取不同的解决方式。那些微小的变化常常给用户带来不完整的、不合格的体验和错误的印象。一些应用程序可能在个别发行版上运行得更好,但在其他发行版上运行得很差,而其他一些应用程序则运行得更好。虽然一个应用程序在每位发行版上的重构方法不同,但其名称和品牌却保持原貌,给用户留下错误的印象。
解决方案
图片来源:来自的
如上所述,解决这种问题的方式是使用容器。
容器被设计拿来分离系统的几个方面。通过使用容器,打包者可以选购依赖项而不受主机上的库限制。为此,打包者可以发布最新的、功能完整的软件包,同时保持发行的稳定性。
这一点十分重要,由于这种容器格式可以将应用程序和发行版发挥出最大的作用,而不会对系统导致破坏性的影响。
Nix和Flatpak
是一个跨平台的包管理器,可以在类Unix操作系统中运行,如Linux发行版、BSD和macOS。Nix有几个nixos.wiki(分支)供用户使用。
另一方面,是一个用于Linux桌面的通用软件包格式,它也借助容器,但另外还有沙盒来隔离它们。它借以之后可以供普通人使用,并被设计为与软件商店(如GNOME“软件(Software)”和KDE“发现(Discover))集成。换句话说,Flatpak更像是发行版的一个扩充,而不是一个软件包格式的代替品,由于它的设计本意不是为了替代系统包管理器。
假如使用NixOS等发行版,Nix也可以作为一种扩充或单独使用。
类似的应用
Nix和Flatpak解决了传统软件包格式的许多基本问题。因为应用程序的分离,这种格式可以安装类似的应用程序,如VisualStudioCode和Code-OSS,而不会冲突。
多个版本
Nix和Flatpak可以安装同一个应用程序的多个版本。使用Nix,我可以从nixpkgs-stable(LTS)安装应用程序,同时也可以从nixpkgs-unstable(开发版)安装同一个应用程序。
同样地,使用Flatpak,我可以同时从stable和beta分支安装应用程序。我可以从更多的途径和分支继续安装同一个应用程序,而不会碰到冲突。
挑剔的依赖项
图片来源:来自的
据悉,打包者可以将应用程序与不同变体的库捆绑在一起,因而有机会启用更多的建立选项,并使用打过补丁或特定版本的库,进而为用户提供完整的体验。
这意味着打包者可以将打了补丁的FFmpeg与OBSStudio捆绑在一起,只为了用在OBSStudio中。假如我在主机上安装了普通的FFmpeg,这么OBSStudio的补丁FFmpeg就不会与主机的FFmpeg发生干扰或冲突。
各个发行版的环境都是一致的
如上所述,各发行版使用不同的补丁、构建选项和环境建立应用程序。这引起了应用程序的碎片化,每位应用程序的建立方法和工作方法常常不尽相同。因为Nix和Flatpak是为跨发行版运行而设计的,它们在每位发行版中为应用程序提供一致的环境,前提是发行版提供了Nix或Flatpak的支持版本。
缺点
如同所有事物一样,Nix和Flatpak不是完美的。因为近来在Linux桌面上容器技术得到了推崇,它们可能为许多应用程序提供了不寻常的环境。
Flatpak除了包含了应用程序,还对它们进行沙盒处理。Flatpak的开发者早已施行了一个短期的变通方案,“在沙盒上打洞”,即所谓的静态权限。她们正在开发适当的常年解决方案,称为,以解决有关沙盒的许多问题,并使其像Android的安全模型一样。
惟一的短期问题是,工具包、框架和应用程序必须采用这种标准。GTK和Qt这样的工具包集成了其中一些门户(portal),但它们也须要时间来集成其他的门户。同时,许多其他的工具箱还没有真正集成任何门户。
工具包、框架和应用程序采用这种新标准是一个时间问题,由于在XDG门户之前没有任何适当的标准。应用程序可以直接访问文件系统和API,所以静态权限保持这些“标准”。
推论
传统软件包格式的根本问题是它没有借助容器。许多图形化的应用程序本质上是复杂的,须要十分具体的依赖关系能够按预期运行。许多发行版通过使用变通的方式在不同的环境中建立同一个应用程序,比如给应用程序打补丁或禁用个别建立选项。这造成了一个应用程序的不同变体、不一致的行为和不合格的用户体验。
其实,发行版的维护者不可能在几天内现实地重画她们的包管理器并使用容器。这种重画会破坏许多脚本、功能等,并且还须要很长时间才会投入生产环境。
我个人的建议是使用和推广Flatpak,由于它只是为了扩充现有的发行版,而不是替代它。打包者毋须害怕打包应用程序,以及诉诸变通的问题,由于Flatpak早已在处理这种问题了。
作者HariRanatheevilskeleton.gitlab.io。
Hari是Fedora刊物的Fedora编辑委员会的成员。他也是Fedoea质量保证(QA)的一员。Hari希望通过推广各类技术和帮助须要帮助的人,为Linux桌面的采用做出贡献。