编译LFS的一些经验

LFS 全称叫做 Linux From Scratch ,顾明思议,就是“从头开始的 Linux”。官方网址 中文翻译网址

LFS 可以说是一个项目,也可以说是一本书。它会教你如何从头构建你自己的 Linux 发行版。这里说的“从头”,是纯粹的从头的,包括编译工具,也是需要自己构建出来的。比如 Gcc,这是整个构建过程中比较核心的工具,LFS 先从 Gcc 源码编译了一个 Gcc,又编译了一个 Glibc。因为 Libstdc++ 是依赖 Glibc 的,所以有了 Glibc 之后,才可以第二次编译 Gcc(这次带上 Libstdc++)。其他工具也是一样,这样就有了一个临时的工具集。当编译一个 Linux 所有的工具链都准备好之后,就用 chroot 进入临时的系统,独立于宿主系统。在这个临时系统中编译 Linux。即,这个工具从编译工具到最后 boot 启动成功,都是需要自己编译的,没有使用现成的 binary。

LFS 让我感到很惊艳,这是个了不起的工程。从上面的例子可以看出,这个工程需要经验老到的梳理很多循环依赖,和编译错误。

现在的编程世界有了各种方便的包管理工具,和提前编译好的二进制文件。一般我们需要什么工具,只要找对应平台的二进制来下载使用就好了。却从来没有想过,如果“从头”编译一个东西会是怎样的。会不会有一天,像《基地》里面的帝国那样,机器都无比复杂,没有任何一个人清楚怎么修理,而导致帝国的崩坏呢?

小时候我经常陷入这样的幻想:如果从零制作一个东西,会是怎么样的。比如说桌子,造桌子需要斧头,和钉子,这些又需要钢铁,那么就需要炼钢。炼钢技术需要有火,还有要XX等等。这个项目,也算满足了我的一个幻想。

废话了这么多,只想跟大家推荐一下 LFS,真的很值得一试。即使最后你不使用最终构建的 Linux 作为自己日常使用的 Linux,从中也能学到很多东西。比如,我今天从这个项目中才知道 su - 后面的这个 - 是什么含义

这篇博客,也记录一下我构建 LFS 时候的一些坑,因为我发现中文方面的资料和讨论比较少。希望对后面去玩 LFS 的人有些帮助。

环境问题

我是在 Mac 上,使用 VirtualBox 虚拟化出来的 Fedora 构建的(推荐大家这么做)。也可以直接使用 Linux 系统编译,不用虚拟化和 Docker 啥的,因为书里面就会教你如何构建一个纯净的工具系统。但是不推荐用 OS X 来构建,APFS 会有很多坑。

最开始需要分区,挂载到宿主系统。我在虚拟机里面没有搞定,然后想起来,我在 Virtualbox 里面呀!遂直接用 Virtualbox 挂载了一个新的硬盘上去。搞定。

第一次编译 LFS 尽量不要自己做定制,严格按照书上的来,不然可能会白费一些力气。

下载

要下载的内容基本都是源代码,在准备的章节中,LFS 整理了一个 URL 列表,可以直接用 wget 下载。我发现即使用代理,有些下载还是很慢,2个小时都没下载完。后来直接去 DigitalOcean 开了一台 VPS,3min就下完了。推荐还是用外网的机器直接下载然后 scp 拷贝回来吧。

机器配置

LFS 每一个工具的构建都写的很标准,标明了构建耗时。用的单位是 SBU (Standard Build Unit),表示时间需要构建 BinUtils 的几倍长。有些构建相当耗时,我一开始给构建用的机器分配了 2CPU/8G MEM ,最后加到了 4CPU/8G MEM。但是还是觉得挺慢,所以推荐大家有多少资源就给多少吧。LFS 整个过程大多数时间都在等待编译完成。

在 LFS 中可以学到什么

尽量看懂书里面的每一行脚本,和解释,能学到很多东西的,不要急着粘贴命令。

The key to learning what makes a Linux system work is to know what each package is used for and why you (or the system) may need it.

操作仔细

注意一下编译的输出。由于编译太耗时了,有可能编译结束的时候,就忘记自己当前在哪一步了。一定要仔细一些,我有次 make 之后忘记执行 make install 了,其实后面执行命令的时候,通过 ./configure 输出,可以看到某些工具用的不是工具链里面,是系统里面的,是可以提前发现的。LFS 越到后面,发现错误的成本越大。轻则需要从错误处再走一遍,重则找不到错误的源头,功夫白费了。

编译完第5章建议备份一下 $LFS/tools ,以后编译别的东西可以直接用这个工具链。

一些可能的坑

  • 进入第六章之后,如果中途中断了(总不能一口气编译完吧)。下次进入的时候要重新操作 6.26.4,进行 mount 和进入 chroot 和 mount 一些虚拟文件系统;

    If the virtual kernel file systems have been unmounted, either manually or through a reboot, ensure that the virtual kernel file systems are mounted when reentering the chroot. This process was explained in Section 6.2.2, “Mounting and Populating /dev” and Section 6.2.3, “Mounting Virtual Kernel File Systems”.

  • 即使编译 stable 版本的 LFS,也可能遇到一些书中没有标明的测试失败。只要不是大面积的失败,几个失败可能并不是重要的。我编译的过程中遇到的未预期的测试失败记录在这里了,供后面的人参考。
  • 推荐使用 virtualbox 添加一块新盘来做,这样即使 host 机器有什么问题(比如 grub 设置错误导致无法启动),可以很方便的将这个新盘 mount 到另外一台虚拟机,直接更改里面文件。
  • 如果使用 virtualbox 的话,在设置 grub 的时候,要注意将 grub 安装到 /dev/sda,然后 boot 的磁盘添加 /dev/sdb.

相关资料推荐

推荐一些相关的资料,解决了我的疑惑,也可能解决你的疑惑。

  1. The magic behind configure, make, make install 编译的过程中你要运行无数次 ./configure && make && make install ,这篇文章解释了这些命令是哪里来的,以及 ./configure 和 Makefile 是从哪里来的;
  2. Libraries: Static or shared?

电影推荐

有些编译很漫长,第三轮 glibc 要将近1小时,第三轮 Gcc(加上 check)需要4h左右。准备些爆米花边看电影边编译吧。

  • 《勇士》 汤姆·哈迪主演的拳击题材的电影;
  • Rudderless 一个比较复杂的话题,音乐题材;
  • 《血钻》 莱昂纳多·迪卡普里奥主演的战争动作片,讲南非黑钻的故事。

最后,如果在构建的过程中遇到问题,可以在这里留言,大家交流学习。



编译LFS的一些经验”已经有6条评论

  1. 您好,我来自V2ex,希望能跟您交换友情链接。

    我的博客也基本上是技术类文章,全部都是原创内容。

    希望得到回复,我的博客地址是:https://www.fi-ads.com/

    已经添加您的链接到我的友情链接页面。

    非常感谢!

  2. 我有一个想法不知道是不是可行,在一开始就把整个LFS目录初始化为一个git仓库,每成功一个步骤commit一次,这样万一哪步搞砸了回来比较容易。

    • 感觉是可行的,但是有两个问题:
      1) 这个过程大部分是各种软件的代码和二进制文件,用 git 备份速度会很慢,占用空间很大。
      2) LFS 编译的过程并没有指导如何编译 git,你可能要自己解决依赖问题。尤其是在 chroot 之后。

      可能一些 versioning file system 更合适。https://en.wikipedia.org/wiki/Versioning_file_system

      不过感觉还是更麻烦了,倒不如编译的时候仔细一点不出错 ^_^

回复 laixintao 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注