星期日, 十二月 31, 2006

对包管理器依赖问题的思考(1)

可以肯定的是,目前的包管理器解决依赖问题的方法,应该都是外部方法。大体上,就是维护一种外部的表,说明某个特定的二进制软件包依赖于其他那些包,后某个包被其他哪些包所依赖。

如果 crablfs 要解决依赖关系的问题,当然也可以使用这种办法。假设现在我已经有一个发行版(Ditux),那么我们需要做的就是有人来维护这样一个表,并经常的进行必要的升级和更新。至于这个表的生成方法,可以考虑从 LFS BOOK 的 xml docbook 中直接生成作为一个基础,再增加一些包等。

但是就我来说,对于从源代码编译来的软件包,这并不是最好的方法,因为源代码编译的灵活性是很强的,不象二进制包有很多限制并采用保守参数。虽然针对源代码编译,也有 FreeBSD 的 ports 和 Gentoo 的 portage 等系统(有时间还要好好研究一下,应该可以获得很多灵感的),但这种纯粹集中式的方式也是以放弃灵活性为代价的,因而缺乏足够的定制能力,而现代的很多应用,不论是个人用户还是企业,都可能有一些特定的定制环境以适应一些特殊的需求。既然现在已经进入 Web 2.0 时代,为什么在其他应用中,定制的需求就不会增加呢?

所以我想应该换一个角度来进行思考。与由专人来负责所有的依赖表相对,我想正确的作法其实应该是由每个应用软件包的作者提供依赖说明,因为只有作者最清楚自己写的东西依赖于哪些别的东西,而增加这也一个说明并不会给他增加多大的成本。

因此直接的想法是在包中增加一个说明文件,说明自己依赖于其他哪些包。然后包管理器在安装时检查这个文件,并自动解决依赖关系。

这样做的问题是,这个文件是静态的,而依赖关系可能会随编译时的参数不同而不同。因此正确的作法应该是根据编译时参数自动生成依赖说明,比如在 ./configure 时自动生成,然后包管理器以此为基础来解决依赖问题(对于 python 这些包,其实也可以类似解决)。目前当然基本上是没有这也的 ./configure 的,有的有说明,但没有统一的规范。

如果以这种方式,当包管理器检测到有依赖问题时,如果它无法在系统中已有包中找到解决,它应该提示用户是否已经使用的正确的参数(有时侯是路径的问题导致找不到某些特定的文件),如果用户确认或在运行参数中指定了,则自动到官方网站下载包及其安装 profiles 并自动编译和安装。当然这个 profiles 会使用保守参数进行编译--当然,在我的设计中,官方网站可以上传用户的定制环境,因此用户也可以指定使用自己的定制参数。另外,可以做进一步的检测机制以检查一个依赖包是否存在,从而更准确的判断是否是路径等问题导致依赖失败等。

安装之后,会自动在系统中生成依赖表。这主要是为了在卸载某个包的时候保证依赖链不会被破坏。

另外,对 crablfs 还需要考虑一个分类问题。比如 mplayer 和 media.mplayer 或 util-linux 和 base.util-linux 应该如何整合出同样的效果?

同时,我还需要再研究一下 pkg-config 这些东西,以进行更深入的思考和设计。

有一点我还想说明的是,在我看来,如果定制环境的 profiles 都可以保存下来并且可以很方便的跨平台使用,那么包的依赖问题就不再是一个那么明显和重要的问题了。带着你的 profiles 也就是你的解决方案到任何地方,你都可以很方便的重建你的环境,而这个已解决的方案自然是没有依赖问题的。只是在增加新的软件时,如果没有自动依赖关系处理可能会有点烦琐,但从某个角度来看,这也是有回报的:你只是多麻烦了一次,却始终保持了对系统的绝对控制!

当然,自动依赖处理还是要加上的,为了不同的用户需求!

没有评论: