原作者 Matt

原链接 BSD for Linux Users


BSD和Linux的不同源自他们不同的哲学。只要理解这点,其他的一切都顺理成章。

  • toc {:toc}

3. 设计:基本系统

我认为“基本系统”这个概念会让 Linux 用户最头疼。这很自然,因为“基本系统”这回事在 Linux 世界里不存在。

Linux 最初仅仅是个 kernel。 除了能用来和人争"操作系统到底包括什么",单独的 kernel 没什么用。还需要各种用户态的程序才能做事。

Linux 一直是个杂烩:拿来一个 kernel,拿来一个 ls,一个 ps,vim,perl,gzip,tar,等等.

Linux 从来没有“基本系统”和“额外程序”的划分。因为 MySQL,ls,KDE,whois,dc,GnuCash 等系统的每一部分都是“额外”。

BSD 与此相反,开发一向是中心式的。始终有一个实体对整个系统负责。 BSD 不用 GNU ls 或 GNU libc。BSD 用 BSD ls 和 BSD libc。 它们直接来源于 CSRG 发布的 BSD,从没被单独开发或打包。 没有一个地方给你下载“BSD libc”,因为在 BSD 世界中,单独的 libc 没用,单独的 ls 没用,单独的 kernel 没用。 系统是个整体,不是拼起来的很多块。

X 不属于 FreeBSD 基本系统,X 是额外的软件包。 既然 X 不是基本系统,xterm KDE Gnome Mozilla 等跑在 X 下的显然也不是。 这些额外的软件受到不同的对待。最大的不同是它们的开发在哪进行。

因为 X 和控制台驱动的集成的关系,NetBSD 和 OpenBSD 的基本系统中都含有一个 X 的实现。 这些 X 含有大量为 BSD 做的修改,所以不适合作为单独的软件包来开发。

整个基本系统是一起被开发的。 严格地讲,基本系统中确实有一些 sendmail BIND tcpdump ssh 之类分开来开发的软件。 Linux 用户能一眼认出 groff gcc gzip 等 GNU 软件。 这些软件受到的对待是不同的,他们在做了一些修改后才融入 BSD 版本树。 很多现在独立的软件过去是 BSD 才有的。BIND 和 sendmail 曾经是 BSD 的一部分,后来才分开。 我的 FreeBSD 自称用了 gcc 3.2.2。 技术上来说这个其实不是真正的 gcc 3.2.2,是一个基于 gcc 3.2.2 的 FreeBSD 编译器。 技术上来说,我用的也不是 tcpdump 3.7.2,而是一个基于 tcpdump 3.7.2 的 FreeBSD 版 tcpdump。

当然在大多数情况下,FreeBSD 版本和原版没有明显区别。 为了让编译正常进行,往往会修改编译时的配置(Makefile 等)。 有时会打补丁让编译和运行正常通过。有时会有更大的更改。 所有这些改动都是一起维护的,它们必须互相适应。 因此 BSD 从设计上就保证了基本系统里的各部分能相互配合。

把一个由外部维护的软件加入基本系统的原因一般是因为它的功能足够“基本”。 FreeBSD 基本系统包括 OpenSSH 的 ssh 服务器端和客户端,因为这年头 SSH 太基本了。 gcc 和 binutils 也是基本系统的一部分,因为编译基本系统需要用它们。 X 和 Gnome 和 PostgreSQL 和 Apache不是基本系统,可能永远都不会是。 因为它们不是系统必需的。

有必要强调“基本系统”这个东西。我认为它是 BSD 和 Linux 的开发方法论中最显著的不同。 Linux 发行版是把各部分拼装起来,可能会在发布前测试,甚至可能有一些定制。 但是这远不同于 BSD 中的紧密集成。 BSD 基本系统的组件不是来自"别的地方", 它们一出生就是基本系统的一部分.

一些 Linux 发行版(我知道 Debian 和 Gentoo)比较接近这种基本系统/额外组件的划分,在“系统运行所需”和其他东西之间有一条分隔线。 这仍然和 BSD 不同。 Linux 的各软件只是被收入发行版,不存在像"Gentoo tftp"这样的东西。 BSD 中的很多软件也来自外界,但基本系统由自己的开发者维护。BSD 基本系统始终属于 BSD。

基本系统有时也被称为“最小系统”,听起来就像维护者的目标是让它小而紧凑。 其实不是这样。我们确实想让它小和紧凑,那是因为我们想要一个“基本”的系统。 我从未在一台机器上只装 BSD 基本系统,可能永远都不会装。我也没听说谁装过这样的机器。 “基本系统”只需要让系统跑起来,让你可以更新或安装其他软件。 之后你根据需求,要用什么就装什么。

据说上面这些更符合 FreeBSD 的情况。 NetBSD 和 OpenBSD 选择"基本系统"的条件要宽松一些。 实际装时,你还是应当 rtfm。

既然已经讲了基本系统,下面我们来讲 ports tree。


4. 设计:ports系统

下面讲第二类:额外的软件。 在 BSD 世界中,这些一般叫做“ports”系统。这名字背后有一段故事。

传统上,如果想在自己的机器上运行某个软件,首先要编译它。为了能编译它,你需要调节它。 你的系统可能需要不同的头文件,不同的常量。部分代码可能需要重写,因为一些基础假设未必适用于你的机器。

换句话说,你需要把它“移植”到你的的 OS,可能还移植到具体的系统. ports 系统被设计来做"移植"的。 虽然从名字上看不出,ports 也负责编译,安装,打包(为了反安装)。

但是和其他很多东西一样,在 ports 的成长中,这个名字逐渐变得名不副实。 目前 FreeBSD ports 包括了超过 10,000 种软件,这个数字很快就会不准。 ports 最大的特征是所有东西都是从源代码编译出来,而不是安装编译好的二进制包。 这又是一个会卡住 Linux 用户的显著差别。 从代码编译只是个副作用,不是主要的目的。 有时 BSD 也提供二进制包,但其实这些二进制包也是用 ports tree 编译出来的。

确实大部分 Linux 用户安装 binary 包,大部分 BSD 用户从代码编译。这是因为工具的不同。 设计 ports 的主要目的就是从源代码编译。make 和安装不是主要功能。 而 Linux 包管理器, 比如 RPM 和 dpkg, 是被设计来安装 binary 包. 从代码编译不是第一选择. 这是历史原因. 我提到过 Unix 一向不重视 binary 包. 软件包管理也是近期才出现. 传统上像删除软件包这种事是需要手动解决的.

有个著名的 Linux 发行版叫 Gentoo. Gentoo 的 portage 系统是个大卖点,很多人认为这个和 BSD 的 ports 非常像。 最明显的相似之处是 portage 也从代码编译。从代码编译能避免 binary 包的很多问题。 我没用过 portage,但是听说 portage 综合了各种方案的优点。我想看它几年后会发展成怎样。 它仍然像 Linux 多过像 BSD,但可能是主要 Linux 发行版中最像 BSD 的。

安装 binary 包省时而且省空间。 从头编译也有优点,比如能避免各种 lib 版本问题 (我最受不了 binary 这点)。 在 Linux 和 BSD 上都可以安装 binary 包,都可以从代码编译。但是 Linux 和 BSD 用户各有所好。 用户的偏好是因为系统的偏好,系统的偏好又是因为用户的偏好。

要认识到 ports 和 RPM 的区别不仅是“ports 编译,RPM 安装”。 ports 的设计目的是涵盖安装中的各种阶段: 依赖关系,打包,安装,反安装等。 RPM 只是个 binary 包。如果要管理依赖关系,就需要更高级的工具如 urpmi,apt-get。 因为它是 binary 包,你就要处理 lib 的版本冲突,缺少的编译选项,以及其他不亲自编译导致的种种问题。

ports 像 BSD 的其他东西一样, 是中心化的。 "ports tree"是一个分类好的大目录。 每个项目会含有 Makefile,checksum 文件,文件列表 等东西。 每个这样的小目录代表一个软件. 当你运行 make 时,黑魔法会为你做好各种事。如下载源代码,打需要的补丁,递归地安装好依赖项,并且用正确的选项开始编译。

这个大目录里的所有文件由 FreeBSD 项目维护。 如果有人写了一个 KDE,KDE 不会自动出现在 ports tree 中。 需要有什么人把这些“胶水”文件写出来 然后提交到 FreeBSD 的 CVS 版本库。 这提供了某种程度的“保险”,保证每个软件和 ports 的其他软件能兼容。 它还保证所有依赖项都能得到满足,因为一个软件不能依赖不在 ports 里的东西。

当然也有失败的时候。 依赖项的网站可能会 down,导致无法下载代码。 第三方软件的新版本可能会使直接或间接依赖它的软件工作不正常。 ports 不解决所有问题,但是“我需要 A,A 依赖 B,我找不到 B”这样的问题远少于 RPM 这样的无中心系统。

如果需要更详细的介绍,请参考 FreeBSD 手册中 ports 的部分。

我们已经介绍了对 Linux 用户比较难懂的“基本系统”和“ports tree”。 下面我们来讨论发布和升级。