1.1 软件包的演变史
关于软件包,在不同的时期,具有不同的形态。最早期的软件包是一些可以运行的程序组成的集合,可能还要加上若干配置文件和动态库。举个例子,程序员把自己写好的脚本文件或者二进制文件(源码编译生成的)、程序所依赖的动态库文件(比如以.so和.dll为扩展名的文件)及配置文件复制到一个目录中,取名为execute,这时execute就可以称为一个软件包了。
有读者可能会有疑问:这样就能称为软件包了?是的,它确实是一个软件包,因为这个目录当中已经包含了一个应用运行需要的所有东西:从可执行程序到配置文件,再到共享库等,都具备了。之所以有人怀疑其能否称得上是软件包,是因为它看起来有些原始和简单罢了。上面所描述的软件包,在短期内能够满足一些简单应用的需求。然而,随着应用的不断复杂化和技术的不断革新,这种格式的软件包逐渐不能满足人们的需要了。比如,某个工程的软件包包含了数百个文件,每次把这些文件复制并安装到别的机器上,都要花费不少时间。另外,当某个软件包中的文件被意外删除或者修改后,管理人员并不知道,这样就会导致在别的环境下,虽然软件能够正常安装,但是在运行时,可执行程序很可能不能正常工作。于是,人们开始规划更高级别的软件包。
为了保证使用的软件包能够方便且快速地复制到别的机器上,人们开始选用压缩文件的方式来封装软件包。比如对execute进行压缩后,它就成了另外的一种软件包:通过tar或者gzip压缩后得到.tar.gz、.rar或者.zip格式的文件,这时我们就获得了一个较为高级的软件包。之所以称其为高级软件包,是因为这种格式的软件包把程序和配置压缩成了一个单一的文件,这样的格式既方便数据复制,又节省了磁盘空间,在通过网络传输时,还能减少带宽资源。另外,为了保证每次的软件修改都能被安装者区分,一些制作压缩格式软件包的开发人员会用一个校验和去标识新发布的软件包,比如通过md5sum校验和来供使用者核对包的完整性。我们在很多下载站点经常看到这样的现象:在页面中资源下载链接的后面,通常会紧跟着一个md5sum的字符串,当使用者完成软件包下载后,就可以在他的机器上通过以下命令:
md5sum文件名
来计算获取软件包的md5sum校验和,然后和下载页面的md5sum值进行对比:如果两者一致,说明下载的包是完整的;如果不一致,说明下载的包有问题。通常,大多数开发者也会为压缩包加上一个自定义的版本信息,比如,test-1.1.tgz文件就是一个针对test-1.0.tgz软件包的升级版安装包。
笔者曾经参与过一个持续了两年的项目,项目组的程序基本都是通过压缩包的方式来发布的。每次发布程序时,维护人员都必须通过手动的方式,把动态库、二进制程序和配置文件压缩成一个.tgz文件,复制到要部署的2000多台机器上,并解压缩到指定目录下,然后直接启动运行。另外,经常光顾kernel.org的读者应该也留意到了,在内核源码的下载页面中,通常的下载资源都是采用压缩包加版本的格式来提供下载的,而且伴随每个下载链接,通常都会有一个.sign文件,称为特征文件,这个文件中存储了下载文件的GPG签名(参考GPG相关文档),这也是一种典型的压缩格式的软件包。我们可以看到,在日常使用方面,相对于最原始的零散文件方式的软件包,压缩格式的软件包已经比较方便了。
再往后发展,就出现了更高级的软件包,比如.rpm、.bin或者.deb格式的软件包。这些格式的软件包,相对于压缩格式的软件包又有了更进一步的发展,它们不仅支持文件压缩功能,还有依赖维护、脚本的嵌入等功能。要了解每种软件包的具体功能,需要读者去翻阅对应的文档。RedHat公司开发贡献的RedHat Package Manager(RPM)可以说是这些高级别软件包中最典型的一个,在本书中,我们将会选取这种格式的软件包作为讨论对象。