根据《Linux From Scratch 版本 20200901-systemd,中文翻译版》构建 LFS systemd 10.0
的归纳总结。
LFS 简介
LFS 项目主要是从源码一步一步构建一个定制的 Linux 系统。具体内容可以访问项目主页。
LFS 构建过程
- 阅读官方手册。
- 宿主机环境检查,安装相应软件包,完成相关配置。
- 新建分区。
- 下载需要的软件包和补丁。
- 配置工作环境,主要包括创建目录布局、添加
lfs
用户、完成lfs
用户的环境配置。 - 编译交叉工具链。
- 用编译好的交叉工具链,交叉编译基本工具,用于构建其他软件包。
- 进入 Chroot 环境,构建一些额外工具,用于后续构建和测试。
- 构建完整的 LFS 系统。
- 完成系统的基本设置。
- 配置内核和引导加载器。
- 收尾工作。
常见问题及个人理解
构建 LFS 系统的意义
如果是为了构建自己使用 Linux 系统,我真的不推荐 LFS,除非你有不得不用 LFS 系统的理由,不然用现成的 Linux 发行版比较靠谱。
那么对于大部分人来说,构建 LFS 的意义肯定不是自己使用了,而是体验一步一步从源码构建的过程。这个过程,能让我们熟悉如何从源码安装软件包,了解一个系统包括哪些必要的组件,以及在一定程度上知晓它们的依赖关系。这对今后使用其他 Linux 发行版是有好处的,至少在一定程度上具备了从源码自己构建相关软件包的能力。
当前,这一切的前提,是理解了构建 LFS 的大部分指令的含义,而不是复制粘贴完成构建。
多次构建工具链的意义
这也是 LFS 作者重点讨论的内容。来看手册上描述的三个阶段:
阶段 | Build | Host | Target | 操作描述 |
---|---|---|---|---|
1 | pc | pc | lfs | 在 pc 上使用 cc-pc 构建交叉编译器 cc1 |
2 | pc | lfs | lfs | 在 pc 上使用 cc1 构建 cc-lfs |
3 | lfs | lfs | lfs | 在 lfs 上使用 cc-lfs 重新构建并测试它本身 |
根据官方手册,抛开用于验证的第三阶段,我们构建了两遍工具链,不妨来反向思考这个问题。
最终我们希望用工具链 cc-lfs
来构建完整的 LFS 系统,所以我们需要构建 cc-lfs
。
现在我们需要在宿主机上构建 cc-lfs
,如果直接用宿主机自带的 cc-pc
,那么构建的 cc-lfs
将依赖于我们的宿主系统,这显然不是我们想要的结果,所以必须使用交叉编译工具链 cc1
来避免这种依赖,这就是第二遍构建——用 cc1
构建 cc-lfs
。
现在要在宿主机上构建交叉编译工具链 cc1
,自然是使用宿主机自带的工具链 cc-pc
,这就是第一次构建——用 cc-pc
构建交叉编译器 cc1
。
多次切换环境的意义
在构建 LFS 的过程中,我们进行了多次环境的切换,下面列出所有可能的环境切换:
- 从普通用户切换到
root
用户。 - 从
root
用户切换到lfs
用户。 - 从
lfs
用户返回到root
用户。 - 从
root
用户切换到 Chroot 环境。 - 从 Chroot 环境返回到
root
用户。 - 从
root
用户返回到普通用户。
第一次切换和第六次对应,是为了用 root
权限执行一些指令。
第二次切换和第三次切换对应,这个切换不是强制要求的,因为用 root
权限进行操作存在较大风险,所以通过切换到 lfs
用户来降低这种风险,同时创建一个新用户也能更容易地建立干净的工作环境。
第四次切换和第五次切换对应,因为我们希望在一个与宿主机隔离的环境中构建 LFS,确保尽可能不受宿主系统影响,所以进入了 Chroot 这个临时环境。
工具链编译顺序的问题
这部分内容 LFS 作者给出了完整的介绍,简单概括如下:
我们首先安装 Binutils。这是由于 GCC 和 Glibc 的 configure 脚本首先测试汇编器和链接器的一些特性,以决定启用或>禁用一些软件特性。
下一步安装 GCC。
下一步安装“净化的” (sanitized) Linux API 头文件。这允许 C 标准库 (Glibc) 与 Linux 内核提供的各种特性交互。
下一步安装 Glibc。在构建 Glibc 时需要着重考虑编译器,二进制工具,以及内核头文件。
接下来构建 C++ 标准库,然后是第 6 章中那些需要自身才能构建的程序后。
在第 6 章一节的末尾,构建 lfs 本地编译器。首先使用和其他程序相同的 DESTDIR 第二次构建 binutils,然后第二次> 构建 GCC,构建时忽略 libstdc++ 和其他不重要的库。
在第 7 章中,进入 chroot 环境后,首先安装 libstdc++。之后临时性地安装工具链的正常工作所必须的程序。还要构建测试其他程序时必须的程序。此后,核心工具链成为自包含的本地工具链。在第 8 章中,构建、测试并最后一次安装所有软件包,它们组成功能完整的系统。
自动构建 LFS
官方的 ALFS 项目,是利用 shell 或 Python 脚本解析 LFS 手册的 XML 代码,生成相应的构建脚本完成全自动构建。但这个项目似乎很久没人维护了,目前依然停留在较早版本。这是一个非常智能的构建脚本,但技术要求相对较高。
本人基于官方手册,抱着写着玩的心态,写了一个自动构建 LFS 的项目,该项目使用 shell 脚本编写,可以自动构建 LFS systemd 10.0
到一个虚拟磁盘文件,项目地址如下:https://github.com/FreeFlyingSheep/lfs。
原本准备用 Python 重构一个脚本,但感觉实际意义不大,又耗时,就鸽了……