为什么 Linux 打包软件时不将依赖一起打包,安装时再检测此依赖是否已存在,如存在则放弃安装。
现有的方式是各是各的,打包软件时给出一张表:我需要 xxx 依赖,然后系统自行安装,这就导致如果当前源里没有这个依赖,则软件安装失败,有些软件甚至依赖好多个源。。
有类似的,比如 flatpak、snap、appimage。
但是工作模式和 lz 说的有点儿不一样,上面这些自带依赖,而且依赖随着 app 走,不会进入系统。
所以现在有很多 AppImage 格式的应用了
现在都采用 Appimage,就是差不多你说的这种情况。
> 有些软件甚至依赖好多个源
ppa 源的受害者
因为有些依赖是不适合自带依赖了,例如几乎所有程序都要用的 glibc,因为强行跨版本共存会有很多问题
如果自带依赖,那通常就是全部依赖都带上( flatpak、snap、appimage、docker )而不是装一半检测一半。
而且你也不知道你自行安装的依赖会不会破坏其他软件的依赖关系,例如你安装了低版本 libqt5 导致发行版别的 qt 应用找不到符号开不了。所以还不如安装的时候通过包管理器告知缺少依赖,安装发行版维护的依赖包。
最麻烦但问题最少的实践是针对发行版各个版本维护各自的软件源,例如 docker 和 cuda 的官方软件源,就是工作量比较大,或者想办法进入发行版仓库,由发行版团队去解决部署的问题。
然后多个软件依赖同一个库的不同版本,GG。
你安装的乱七八糟的软件打包的依赖和系统其它软件依赖的这个库版本不一样且不兼容,GG。
----
解决方案是 Docker,是 Flatpak 等手段。他们都不是安装到系统,而是安装到一个专用的目录,或者虚拟环境。
Linux 支持静态编译,把你要的库都打包到一个执行文件,也可以指定调用的动态库路径,调用指定版本的动态库,对于小的库,静态编译没什么问题。但不做静态编译,甚至只给源代码,是开源的传统,它有利于开源生态吧。
一种是向你想得那样把依赖打包到一起,缺点就是软件包大,优点就是好分发,像是 Flatpkg 还支持一些安全性质。
另外一种是让软件的源变得健壮起来,尽可能包含所有软件,并且消除依赖问题。
所以我选择了 Manjaro
举个例子,官方哪个源里的哪个软件不能自洽?
静态链接不仅仅是安装包大的问题。假设有 100 个软件都用到了 openssl,然后某一天 openssl 爆出一个漏洞。如果是用动态链接则只需要升级动态库就可以了,而静态链接则需要重新编译这 100 个软件再进行逐一升级。
我觉得大部分 linux 上的软件包都有某某协议才是关键点。
不同协议的软件你打包在一起,不方便吧。
dll hell
为啥我感觉回到了 15 年前左右的 rpm 时代。
存在自己改编译配置的空间
貌似 ubtuntu 20.04 的 default 已经从 apt 到 snap 啦。
可以节省不少空间,而且现在有 snap,appimage,flat 多种选择 所以...
正常的发行版打包都是能自我满足的,少数第三方因为结构复杂所以有时候没办法只能从多个源里抽包。
举个例子,我在维护的一个软件包依赖某个 dmo 打包的版本。我当然可以自己维护一套,但是那就意味着往下整个依赖树都要变成我来维护了。所以暂时还没决定要不要这么做。
用 arch,用 manjaro,你就不会对 linux 有这样的认识了。
> 如果当前源里没有这个依赖
这显然是打包者的责任了……
> 安装时再检测此依赖是否已存在,如存在则放弃安装
这句话我不太明白什么意思……
这为啥会是打包者的责任……打包者能管所有安装用户的系统加了哪些源么?
打包者需要维护包依赖,确保打的包至少在官方默认安装环境下可用,否则打包还有什么意义?
用户自己作死修改源列表不在讨论范围。
没必要一起打包啊
也就几次 make 命令搞定的事情,依赖缺什么装什么呗,完全打包好开箱即用不用依赖的大概只有 java 程序了吧
打包者的责任关用户加了哪些源什么事。
打包者要做的是保证用户在只有官方源和你的源的时候软件包要正常安装。
比如你用 Debian,然后用了 sury 的 PHP 源,那 sury 就要保证你在只有 Debian 官方源和 sury 源的前提下,他的 PHP 包能安装。至于你再去开了一堆其他的源,这关 sury 啥事。
所以「如果当前源里没有这个依赖」这个假设,在正常维护的源里是不应该存在的。这个依赖要么是发行版提供,要么是打包者提供。
ppa 源国内访问好成问题额
snap 有个问题就是…jetbrains 家的产品,不支持中文输入法~
你是要像 Android/iOS 那样打包吗,先去看看你的手机,还有没有“仅在 wifi 环境下下载安装包”的选项。将依赖包一起打到发行包上,确实省事了,但那会造成安装包和安装后应用的体积剧增,并且大部分剧增的空间还是重复的。手机端因其特殊性——不能在安装时联网从远程库下载依赖包而且也不能把所有依赖包都预先安装的操作系统上、使用群体是消费者——所以不得不使用那种打包方式,而 Linux 是服务器且其使用群体是开发者,就别想跟小白那样省事了。
npm:喵喵喵?
最近 Manjaro 的曝光率很高阿
所以 docker 出来了 ,解决这些破烂依赖的 神器
lz 没分清打包和源码发行
后者肯定不带依赖,只带依赖检测机制。开发者没必要对外部依赖的质量负责,只需要使用就行了
前者带依赖声明,可以由包管理机制负责安装上去,版本协调和质量都由打包者负责
全包的场景,可以维持依赖关系的稳定性,但缺点是开发方同时还得负责外部依赖的版本管理
第二句的意思是,安装时再在系统中检测所需要的依赖是否已在系统中存在并符合要求,如果所需要的依赖已存在并且符合要求,就不在重复安装这些依赖
这和 docker 两码事
用了十年 linux 桌面了
目前还没有遇到过楼主说的情况
当然也有可能是我安装的软件少
打包我理解为已经编译好了,编译好的东西再要检测依赖的复杂度可能超过你想象。
一般发行版 repo 有软件就会有其依赖,你说的“现有方式”更像用户配置 repo 出错时的现象。
以前用 ubuntu 的时候经常遇到依赖的问题,现在用了 arch,很省心
了解以下 Docker 镜像的分层,或者制作一个简单的 Dockerfile 吧。Docker 只不过是把所有层(类似于所有依赖)一并打包,虽然使用者看不到依赖,但依赖仍然存在。
Docker 镜像包的体积,那可是相当感人,一个 Docker 镜像就是一个准操作系统,镜像制作者必须小心的处理才能使得镜像包的体积不那么非人。原本就有几百 M 的应用软件做个 Docker 镜像再额外多几十 M 没啥问题,但原本就十来 M 甚至不足 1M 的工具软件打成 Docker 镜像,原始依赖和额外依赖加起来变成上百 M,那就是问题了。
先问是不是再问为什么。
Mysql/JREJDK/Oracle 那么一大堆的 binary dis 包里面的都是静态编译依赖的。
后一句意思是在安装过程中才去检测是否存在不合理。
可以试试 manjaro
那时还不会科学上网的我,ppa = error
想问下,AppImage 格式的软件怎么创建快捷方式在导航栏呢
本来一份函数库就够了,复制个几十份一百份放硬盘里纯属浪费资源,有那个空间我放点什么不好。Windows 那种一个 C 盘占一百多两百 G 才烦人。
问这种问题之前可以做点背景搜索,每种设计都有它的优缺点,都有他的使用方法,自己搞不定依赖就好好想想是不是自己没按照建议从源里安装而是到处乱装野包,至于源里搞不定要么说明你这源不行,要么说明这发行版不行,那就赶紧换个维护者更上心的。
既然需要用 Linux,先了解一下 Linux 下的使用习惯总是不吃亏的,这种吐槽真的没什么帮助。既然它存在了,说明大多数人觉得这个合理,不然早就被淘汰了。
会在正式发布的前一天来个急刹车换回来。
我们环境里还只让用 boot.iso 自带的包.... 要装什么只能自己编译