软件自带依赖库还是共享对象库/为什么linux发行版之间不能有一个统一的二进制软件包标准

Bestcoderg Bestcoderg     2022-12-23     631

关键词:

接前文:Linux软件包(源码包和二进制包)及其区别和特点

在前文,我们知道了linux软件包分为源码包和二进制包两种方式,而不同的发行版之间又有着自己的二进制打包格式。

首先,软件运行依赖着各种各样的库,那么安装软件时到底是选择自带依赖库还是共享对象库之间就产生了分歧。最具有代表性的就是Microsoft的msi与linux各种发行版的打包格式的分歧。

Windows - MSI

  MSI文件是Windows Installer的数据包,它实际上是一个数据库,包含安装一种产品所需要的信息和在很多安装情形下安装程序所需的指令和数据。MSI文件将程序的组成文件与功能关联起来。此外,它还包含有关安装过程本身的信息:如安装序列、目标文件夹路径、系统依赖项、安装选项和控制安装过程的属性。

linux各种发行版

  如DPKG、RPM等。

MIS与DPKG、RPM等

  对于这几种方式的分歧,实则无好坏之分。在我看来,autotools、dpkg、msi 分别是基于源码、共享对象库、静态链接下最佳的软件包解决方案。这三个方案各有优缺点,但由于他们基于不同的开发方式、商业模式,是不能相互替换的。

  比方说,你不能在 Windows 上用 dpkg 去发布软件,因为商业软件为了便于技术支持往往是静态链接或者打包所有依赖的,客户环境的不确定对你来说是个灾难。如果软件包自带依赖,这样就不需要一个全局包管理器了(主要是因为商业软件的需要,Linux因为基于开源环境才有可能做全局包管理)。用户也可以安装同一个软件的多个版本实例,互不干扰。目前msi的做法就很好,用户指定一个安装目录就行了,方便的操作这点对于普通用户来说至关重要(当然也是被巨佬们诟病的对象)。但是缺点在于没有一个全局的安装包管理,windows下的安装/卸载几乎必然会造成垃圾遗留,因为一个程序它无法知道它安装的dll是它自己的还是别的程序的,于是卸载就不会删除。这也是windows用久之后会变慢的一大原因。(当然,在installer的作者用心去写的情况下,写的好的软件,卸载自然不会有太多的垃圾残留。自带依赖根本不会让软件膨胀多少,膨胀的部分往往不是库而是资源文件、帮助文档之类)

  你也不能把 Linux 上所有开源软件全换成 msi 那种形式。在 Linux 上开发通常会用到很多比较 high-level 的库。每个库功能很专一,但也很全面,比方说 OpenSSL 就提供加密相关的功能,但它支持很多加密算法,所以每个库也可能比较大。如果全用静态链接,出来的每个二进制文件里有很多依赖是重复的,比方说 glibc、libstdc++、zlib 等等。这样每个二进制文件几 M 甚至几十 M。在linux全局包管理的方式下用户能够方便的对包进行管理(不会出现Windows下卸载一个软件要找出十几个依赖的库/软件进行删除的情况,不用进行十几次繁琐的删除引导程序),用户也不用自己对库的版本进行控制,非常方便。

所以为什么linux发行版之间有着不同的二进制软件包标准?

首先linux 本质就是个核,核以上的事情都是发行版自行处理的,而大多数软件又都是动态链接的,各个linux发行版系统的结构不同导致了library 版本又各自不同,所以才会有这种兼容性问题(这种兼容性问题主要是在于一些与系统本身机构关系很大的软件, 但普通的应用软件实际上并没有要特殊处理的地方 ,理想状态下是可以实现采用统一打包方式的。)。在 Windows 上这叫做 dll hell,但是 Windows 操作系统这一块因为它从核到用户态都是封闭的,所以兼容性要好很多。这个问题更多的像是一个社会问题而不是一个技术问题。当然这也导致了一些问题,如限制了新软件的传播(对于不同的发行版都进行分别打包这是要要了程序员的狗命吗?滑稽~)

  

 参考文章:https://www.v2ex.com/t/57266

构建相互依赖的共享库(Linux)

】构建相互依赖的共享库(Linux)【英文标题】:Buildingofsharedlibswhichdependoneachother(Linux)【发布时间】:2015-03-0505:39:24【问题描述】:我接管了一堆非常复杂的库和可执行文件(Linux)。整个系统过去是使用静态库开发的,然后几... 查看详情

如何解决linux安装软件的依赖?

...件仓库里没该软件,要解决依赖,如何去做?参考技术A为什么会依赖:编写软件的人不想自己一个人做完所有的事情,就像寻求外援,于是就找上了各种各样的软件包。举个例子,我只是想写一个QQ,但是如果没有图形界面库(... 查看详情

在当前 Linux 发行版上打包 C++11 软件是不是安全?

】在当前Linux发行版上打包C++11软件是不是安全?【英文标题】:IsitsafetopackageC++11softwareoncurrentLinuxdistributions?在当前Linux发行版上打包C++11软件是否安全?【发布时间】:2015-01-2920:02:45【问题描述】:作为Linux发行版的下游维护者... 查看详情

cppcms - 共享库 - Linux

】cppcms-共享库-Linux【英文标题】:cppcms-Sharedlibrary-Linux【发布时间】:2013-04-1718:58:05【问题描述】:我正在尝试在Linux(Debian发行版)上使用cppcms框架。我按照网站上构建教程中描述的步骤,然后尝试构建helloworld应用程序。我已... 查看详情

java加载一个目录下有依赖关系本地库的通用代码

具体参考:全网首发:Linux自带opencv库的JAVA调用失败/java.lang.UnsatisfiedLinkError:libopencv_ml.so.405:无法打开共享对象文件_柳鲲鹏-CSDN博客 查看详情

ctypes 加载具有依赖关系的 c 共享库

】ctypes加载具有依赖关系的c共享库【英文标题】:ctypesloadingacsharedlibrarythathasdependencies【发布时间】:2011-01-2014:31:02【问题描述】:在Linux上,我有一个依赖于其他库的c共享库。LD_LIBRARY_PATH已正确设置以允许链接器加载所有库。... 查看详情

安装程序检查软件包依赖关系的原因是linux中的许多软件包都依赖于(__)?

参考技术A系统lib/系统库/lib根目录下的所程序的共享库目录。此目录下包含系统引导和在根用户执行命令时候所必需用到的共享库。做个不太好但是比较形象的比喻,点类似于Windows上面的system32目录。理说,这里存放的文件应该... 查看详情

在 linux 中使用另一个共享库构建共享库

...问题描述】:我有一个使用共享库B的共享库A,以及一个依赖于A的应用程序P。我不想将P与A和B联系起来,而是将P与A联系起来,将A与B联系起来(并以某种方式将B与P隐藏起来)我该怎么办?共享库是使用\'g++-shared... 查看详情

如何在 petalinux 中检查共享库依赖项

】如何在petalinux中检查共享库依赖项【英文标题】:howtocheckforsharedlibrarydependanciesinpetalinux【发布时间】:2018-03-1418:16:44【问题描述】:我已经成功地使用arm-linux-gnueabi为ZynqZedboard交叉编译了一个示例应用程序。我在上面运行petali... 查看详情

Linux 共享库链接错误(未定义符号)

...布时间】:2018-01-2613:04:09【问题描述】:我正在使用一个依赖于另一个的共享库。libA.so使用libB.so。所有文件都使用-fPIC编译。链接使用-shared。当我在libA.so上调用dlopen时,它在libB.so中找不到符号,我收到“未定义符号”错误。dl... 查看详情

Linux:为啥加载器会找到我的共享库?

...享库?【英文标题】:Linux:Whyloaderfindsmysharedlibrary?Linux:为什么加载器会找到我的共享库?【发布时间】:2015-12-1810:11:11【问题描述】:我已经用CMake编译了一个共享库作为子项目,然后主应用程序链接到该库。库和应用程序位... 查看详情

gcc 将共享库与依赖库链接

】gcc将共享库与依赖库链接【英文标题】:gcclinkingsharedlibrarieswithdependentlibraries【发布时间】:2012-06-1703:10:19【问题描述】:我有一个包含多个可执行目标和多个共享库的复杂项目。共享库目前没有链接它们的依赖共享库,结果... 查看详情

Linux - 为啥我的可执行文件将 libpthread 作为共享库?

...标题】:Linux-Whydoesmyexecutablehavelibpthreadasasharedlibrary?Linux-为什么我的可执行文件将libpthread作为共享库?【发布时间】:2016-08-0401:54:10【问题描述】:所以基本上我想知道为什么我的可执行文件将libpthread作为共享库,而我的代码... 查看详情

linux查看程序(动态库)进程的依赖库的方法(代码片段)

...录1.利用`ldd`查看可执行程序(动态库)的依赖库2.利用pldd获取进程的内存映射信息,进程的依赖共享库3.利用pmap工具查询未知的可执行程序的依赖库4.利用pmap查看正在运行时的进程的依赖库5.ln命令6.versionGLIBCXX_... 查看详情

静态库共享库

...操作系统支持的函数库分为静态库和动态库,动态库又称共享库。Linux系统有几个重要的目录存放相应的函数库,如/lib  /usr/lib。 二、静态函数库、动态函数库 A. 查看详情

C++ 静态库中的共享全局变量:Linux

...定义了一个全局变量foo。“B”和“C”是两个动态库,都依赖于A,因此(静态)与A链接。然后B和C最终在同一个进程中加载(例如:应用程序加载B和C)。如果我们在windows环境中,我们将获得两个不同的fo 查看详情

c++基础语法梳理:链接装载库丨linux的共享库(代码片段)

Linux的共享库(SharedLibrary)Linux下的共享库就是普通的ELF共享对象。共享库版本更新应该保证二进制接口ABI(ApplicationBinaryInterface)的兼容命名libname.so.x.y.zx:主版本号,不同主版本号的库之间不兼容,... 查看详情

linux共享库两种加载方式简述

...小,节省空间,提高效率,具有很高的灵活性,对于升级软件版本也更加容易。与静态库不同,动态库里面的函数不是执行程序本身的一部分,而是在程序执行时按需载入,其执行代码可以同时在多个程序中共享。由于在编译过... 查看详情