Linux From Scratch(从零开始构建Linux)

版本 6.1.1

Gerard Beekmans

版权所有 (c) 1999–2005, Gerard Beekmans

保留所有权利。

在满足以下条件的前提下,允许以源程序和二进制形式再发布和使用,无论是否经过修改

  • 任何形式的再发布都必须保留上述版权声明、本条件列表和以下免责声明

  • 未经事先明确的书面许可,不得使用 “Linux From Scratch” 的名称或其贡献者的名称来认可或推广源自本材料的产品

  • 任何源自 Linux From Scratch 的材料都必须包含对 “Linux From Scratch” 项目的引用

本软件由版权所有者和贡献者按 “原样” 提供,不提供任何明示或暗示的保证,包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下,版权所有者或贡献者均不对任何直接、间接、附带、特殊、惩戒性或后果性损害(包括但不限于采购替代商品或服务;使用、数据或利润的损失;或业务中断)承担责任,无论其原因如何,无论基于合同、严格责任还是侵权(包括疏忽或其他)的责任理论,即使已被告知此类损害的可能性。


目录

前言

1. 序言

我在 Linux 上的冒险始于 1998 年,当时我下载并安装了我的第一个发行版。在使用了一段时间后,我发现了一些我非常希望改进的问题。例如,我不喜欢启动脚本的安排或程序默认配置的方式。我尝试了许多替代发行版来解决这些问题,但每个发行版都有其优点和缺点。最后,我意识到如果我想要从我的 Linux 系统中获得完全的满足感,我必须从头开始构建自己的系统。

这意味着什么?我决心不使用任何类型的预编译包,也不使用任何安装基本实用程序的 CD-ROM 或启动盘。我将使用我当前的 Linux 系统来开发我自己的自定义系统。这个 “完美” 的 Linux 系统将具有各种系统的优点,而没有其相关的缺点。一开始,这个想法相当令人生畏,但我仍然致力于这样一个理念:可以构建一个符合我的需求和愿望的系统,而不是仅仅符合一个不适合我需求的标准。

在解决了诸如循环依赖和编译时错误等问题后,我创建了一个自定义构建的 Linux 系统,该系统已完全运行并且适合个人需求。此过程还允许我创建紧凑且精简的 Linux 系统,这些系统比传统操作系统更快并且占用更少的空间。我将此系统称为 Linux From Scratch 系统,或简称为 LFS 系统。

当我与 Linux 社区的其他成员分享我的目标和经验时,很明显,人们对我的 Linux 冒险中所提出的想法持续感兴趣。这种定制构建的 LFS 系统不仅可以满足用户规范和要求,还可以为程序员和系统管理员提供理想的学习机会,以提高他们的 Linux 技能。出于这种广泛的兴趣,Linux From Scratch 项目诞生了。

这本 Linux From Scratch 书籍为读者提供了设计和构建自定义 Linux 系统的背景知识和指导。本书重点介绍了 Linux From Scratch 项目以及使用该系统的好处。用户可以决定其系统的所有方面,包括目录布局、脚本设置和安全性。最终的系统将完全从源代码编译,用户将能够指定程序安装的位置、原因和方式。本书使读者可以根据自己的需要完全自定义 Linux 系统,并允许用户更好地控制自己的系统。

我希望您能在自己的 LFS 系统上工作愉快,并享受拥有一个真正 属于您自己的 系统的众多好处。

--
Gerard Beekmans
gerard AT linuxfromscratch D0T org

2. 读者对象

人们想阅读本书的原因有很多。主要原因是希望从源代码安装 Linux 系统。许多人提出的一个问题是,“既然可以直接下载和安装现有的 Linux 系统,为什么还要费力地从头开始手动构建一个 Linux 系统呢?” 这是一个好问题,也是本书本节的推动力。

LFS 存在的一个重要原因是帮助人们了解 Linux 系统如何从内部工作。构建 LFS 系统有助于演示 Linux 的工作原理,以及事物如何协同工作和相互依赖。这种学习体验提供的最好的事情之一是能够根据自己的口味和需求自定义 Linux。

LFS 的一个关键好处是它允许用户更好地控制系统,而无需依赖他人的 Linux 实现。使用 LFS, 处于驾驶员的位置,并决定系统的各个方面,例如目录布局和引导脚本设置。您还可以决定程序安装的位置、原因和方式。

LFS 的另一个好处是能够创建一个非常紧凑的 Linux 系统。在安装常规发行版时,人们通常被迫包含几个可能永远不会使用的程序。这些程序浪费磁盘空间,或者更糟的是,浪费 CPU 周期。构建一个小于 100 兆字节 (MB) 的 LFS 系统并不困难,这比大多数现有安装要小得多。这听起来仍然占用很多空间吗?我们中的一些人一直在努力创建一个非常小的嵌入式 LFS 系统。我们成功构建了一个专门运行 Apache Web 服务器的系统,大约使用了 8MB 的磁盘空间。进一步剥离可以将这个大小减少到 5 MB 或更少。用常规发行版试试看!这只是设计您自己的 Linux 实现的众多好处之一。

我们可以将 Linux 发行版比作在快餐店购买的汉堡包——你不知道你吃的东西可能含有什么。另一方面,LFS 不会给你一个汉堡包。相反,LFS 提供了制作所需汉堡包的确切食谱。这允许用户查看食谱,省略不需要的成分,并添加自己的成分以增强汉堡的味道。当您对食谱感到满意时,就可以开始准备它了。它可以按照精确的规格制作——烤、烘烤、油炸或烧烤。

我们可以使用的另一个类比是将 LFS 与已完工的房屋进行比较。LFS 提供了房屋的骨架计划,但由您来建造它。LFS 保持了在整个过程中调整计划的自由,根据用户的需求和偏好进行自定义。

自定义构建的 Linux 系统的另一个优点是安全性。通过从源代码编译整个系统,您可以审核所有内容并应用所有所需的安全补丁。不再需要等待其他人编译修复安全漏洞的二进制包。除非您检查补丁并自己实施,否则您无法保证新的二进制包已正确构建并充分修复了问题。

Linux From Scratch 的目标是构建一个完整且可用的基础级系统。不希望从头开始构建自己的 Linux 系统的读者可能无法从本书的信息中受益。如果您只想知道计算机启动时发生了什么,我们推荐 “从开机到 Bash 提示符” HOWTO,位于 http://axiom.anu.edu.au/~okeefe/p2b/ 或 The Linux Documentation Project (TLDP) 的网站 http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html。该 HOWTO 构建的系统与本书类似,但它严格专注于创建一个能够启动到 BASH 提示符的系统。考虑一下您的目标。如果您希望在学习的过程中构建一个 Linux 系统,那么本书是您的最佳选择。

构建您自己的 LFS 系统的理由太多了,无法在此一一列出。本节只是冰山一角。随着您继续您的 LFS 体验,您会发现信息和知识真正带来的力量。

3. 先决条件

构建 LFS 系统并非易事。它需要具备一定的 Unix 系统管理知识,以便解决问题并正确执行列出的命令。特别是,作为最低要求,读者应该已经能够使用命令行(shell)复制或移动文件和目录,列出目录和文件内容,以及更改当前目录。还要求读者具备使用和安装 Linux 软件的合理知识。

由于 LFS 书籍假定 至少 具备这种基本技能,因此各种 LFS 支持论坛不太可能为您提供太多帮助;您会发现您关于此类基本知识的问题可能不会得到解答,或者您只会简单地被推荐到 LFS 必备预读清单。

在构建 LFS 系统之前,我们建议阅读以下 HOWTO:

4. 主机系统要求

主机必须运行至少 2.6.2 内核,并使用 GCC-3.0 或更高版本编译。存在此要求的两个主要原因。首先,如果主机的内核未使用 GCC-3.0 或更高版本编译,则本机 POSIX 线程库 (NPTL) 测试套件将发生段错误。其次,使用 Udev 需要 2.6.2 或更高版本的内核。Udev 通过从sysfs文件系统读取来动态创建设备。但是,大多数内核驱动程序最近才实现对此文件系统的支持。我们必须确保所有关键系统设备都被正确创建。

为了确定主机内核是否满足上述要求,请运行以下命令

cat /proc/version

这将产生类似于以下的输出

Linux version 2.6.2 (user@host) (gcc version 3.4.0) #1
    Tue Apr 20 21:22:18 GMT 2004

如果上述命令的结果未说明主机内核是 2.6.2(或更高版本),或者未使用 GCC-3.0(或更高版本)编译器编译,则需要安装一个。有两种方法可以解决这个问题。首先,查看您的 Linux 供应商是否提供 2.6.2(或更高版本)内核包。如果是这样,您可能希望安装它。如果您的供应商不提供 2.6.2(或更高版本)内核包,或者您更愿意不安装它,那么您可以自己编译一个 2.6 内核。编译内核和配置引导加载程序(假设主机使用 GRUB)的说明位于 第 8 章中。第二个选项也可以被视为衡量您当前 Linux 技能的标准。如果第二个要求过于苛刻,那么 LFS 书籍此时可能对您没有太大用处。

5. 排版

为了使内容更易于理解,本书中使用了一些排版约定。本节包含 Linux From Scratch 中使用的排版格式的一些示例。

./configure --prefix=/usr

除非周围的文本另有说明,否则此形式的文本旨在完全按照所见进行键入。它也用于解释部分中,以标识正在引用的命令。

install-info: unknown option '--dir-file=/mnt/lfs/usr/info/dir'

此形式的文本(固定宽度文本)显示屏幕输出,可能是由于执行命令的结果。此格式也用于显示文件名,例如/etc/ld.so.conf.

强调

本书中使用了这种形式的文本,用于多种目的。其主要目的是强调重要点或项目。

http://www.linuxfromscratch.org/

此格式用于 LFS 社区内部和外部页面的超链接。它包括 HOWTO、下载位置和网站。

cat > $LFS/etc/group << "EOF"
root:x:0:
bin:x:1:
......
EOF

创建配置文件时使用此格式。第一个命令告诉系统创建文件$LFS/etc/group从以下行中键入的内容,直到遇到文件结束 (EOF) 序列。因此,通常将整个部分按原样键入。

[REPLACED TEXT]

此格式用于封装不按原样键入或复制粘贴的文本。

passwd(5)

此格式用于引用特定的手册页(以下简称 “man” 页)。括号内的数字表示 man 中的特定部分。例如,passwd 有两个 man 页面。根据 LFS 安装说明,这两个 man 页面将位于/usr/share/man/man1/passwd.1/usr/share/man/man5/passwd.5。两个 man 页面都包含不同的信息。当书中使用passwd(5)它专门指/usr/share/man/man5/passwd.5man passwd 将打印它找到的第一个与 “passwd” 匹配的 man 页面,这将是/usr/share/man/man1/passwd.1。对于此示例,您需要运行 man 5 passwd 才能阅读被引用的特定页面。应该注意的是,大多数 man 页面在不同部分中没有重复的页面名称。因此,通常 man [程序名] 就足够了。

6. 结构

本书分为以下几个部分。

6.1. 第一部分 - 介绍

第一部分解释了关于如何继续 LFS 安装的一些重要注意事项。本节还提供了关于本书的元信息。

6.2. 第二部分 - 准备构建

第二部分描述了如何为构建过程做准备——创建分区、下载软件包和编译临时工具。

6.3. 第三部分 - 构建 LFS 系统

第三部分指导读者构建 LFS 系统——逐个编译和安装所有软件包、设置引导脚本和安装内核。生成的 Linux 系统是构建其他软件的基础,可以根据需要扩展系统。在本书的结尾,有一个易于使用的参考,列出了所有已安装的程序、库和重要文件。

7. 勘误表

用于创建 LFS 系统的软件不断更新和增强。在 LFS 书籍发布后,可能会出现安全警告和错误修复。要检查此版本的 LFS 中的软件包版本或说明是否需要进行任何修改以适应安全漏洞或其他错误修复,请在继续构建之前访问 http://www.linuxfromscratch.org/lfs/errata/6.1.1/。您应该注意显示的任何更改,并在您进行构建 LFS 系统的过程中将其应用于本书的相关部分。

第一部分. 介绍

第一章. 介绍

1.1. 如何构建 LFS 系统

LFS 系统将通过使用先前安装的 Linux 发行版(例如 Debian、Mandrake、Red Hat 或 SuSE)来构建。这个现有的 Linux 系统(主机)将用作起点,以提供必要的程序,包括编译器、链接器和 shell,来构建新系统。在发行版安装期间选择 “开发” 选项,以便能够访问这些工具。

作为将整个单独的发行版安装到您的计算机上的替代方案,您可能希望使用 Linux From Scratch LiveCD。该 CD 作为主机系统运行良好,提供了成功遵循本书中说明所需的所有工具。此外,它还包含所有源代码包、补丁和本书的副本。因此,一旦您拥有 CD,就不需要网络连接或额外下载。有关 LFS LiveCD 的更多信息或下载副本,请访问 http://www.linuxfromscratch.org/livecd/

本书的 第 2 章 描述了如何创建一个新的 Linux 本地分区和文件系统,这是将编译和安装新 LFS 系统的地方。第 3 章 解释了需要下载哪些软件包和补丁来构建 LFS 系统,以及如何将它们存储在新的文件系统上。第 4 章 讨论了适当的工作环境的设置。请仔细阅读 第 4 章,因为它解释了开发人员在开始通过 第 5 章 及之后的内容之前应该了解的几个重要问题。

第 5 章 解释了许多软件包的安装,这些软件包将形成基本开发套件(或工具链),用于在 第 6 章 中构建实际系统。需要其中一些软件包来解决循环依赖关系——例如,要编译一个编译器,您需要一个编译器。

第五章也向用户展示了如何构建工具链的第一个版本,包括Binutils和GCC(第一个版本基本上意味着这两个核心软件包将被重新安装第二次)。下一步是构建Glibc,即C语言库。Glibc将由第一个版本中构建的工具链程序编译。然后,将构建工具链的第二个版本。这一次,工具链将与新构建的Glibc动态链接。剩余的第五章软件包使用这个第二个版本的工具链构建。完成此操作后,除了运行中的内核外,LFS的安装过程将不再依赖于宿主发行版。

将新系统与宿主发行版隔离的这种努力可能看起来有些过度,但完整的技术解释在第 5.2 节,“工具链技术说明”中提供。

第六章中,构建了完整的LFS系统。chroot (change root) 程序用于进入一个虚拟环境,并启动一个新的shell,其根目录将设置为LFS分区。这与重新启动并指示内核将LFS分区挂载为根分区非常相似。系统实际上并没有重新启动,而是使用了chroot,因为创建一个可启动系统需要额外的工作,而这目前还不是必需的。 主要优点是“chrooting”允许构建者在构建LFS的同时继续使用宿主系统。在等待软件包编译完成时,用户可以切换到不同的虚拟控制台 (VC) 或 X 桌面,并继续像往常一样使用计算机。

为了完成安装,LFS-Bootscripts在第七章中设置,内核和启动加载器在第八章中设置。第九章包含有关在此书之外进一步扩展 LFS 体验的信息。 完成本书中的步骤后,计算机就可以重新启动到新的 LFS 系统中了。

这就是整个过程的简要概述。有关每个步骤的详细信息将在后续章节和软件包描述中讨论。 那些看起来复杂的事项将被澄清,并且当读者开始 LFS 冒险时,一切都会变得清晰明了。

1.2. 更新日志

这是 Linux From Scratch 书籍的 6.1.1 版本,日期为 2005 年 11 月 30 日。如果本书超过六个月,可能已经有更新更好版本可用。要了解最新版本,请通过 http://www.linuxfromscratch.org/ 检查其中一个镜像站点。

以下是自本书上一个版本以来所做的更改列表。 首先是摘要,然后是详细日志。

  • 已升级到

    • Perl 5.8.7

    • Zlib 1.2.3

  • 已添加

    • binutils-2.15.94.0.2.2-gcc4-1.patch

    • bzip2-1.0.3-install_docs-1.patch

    • bzip2-1.0.3-bzgrep_security-1.patch

    • glibc-2.3.4-rtld_search_dirs-1.patch

    • glibc-2.3.4-tls_assert-1.patch

    • texinfo-4.8-tempfile_fix-1.patch

    • util-linux-2.12q-umount_fix-1.patch

    • vim-6.3-security_fix-2.patch

  • 已移除

    • zlib-1.2.2-security_fix-1.patch;

  • 2005 年 11 月 30 日 [matt]: LFS-6.1.1 发布。

  • 2005 年 11 月 24 日 [matt]: LFS-6.1.1-pre2 发布。

  • 2005 年 11 月 24 日 [matt]: 修复了 Glibc 中的一个问题,该问题阻止某些程序(包括 OpenOffice.org)运行。

  • 2005 年 11 月 23 日 [gerard]: 在第 6 章/节中更正了对“man page”的引用,改为“HTML 文档”。

  • 2005 年 11 月 18 日 [manuel]: 修复了 module-init-tools-testsuite 包的解压问题。

  • 2005 年 11 月 18 日 [manuel]: PDF 修复。

  • 2005 年 11 月 17 日 [matt]: LFS-6.1.1-pre1 发布。

  • 2005 年 11 月 12 日 [matt]: 改进了用于确定 Glibc 和 LFS 之外的软件包都支持的区域设置的启发式方法(错误 1642)。 非常感谢 Alexander Patrakov 强调了众多问题并审查了各种建议的修复方法。

  • 2005 年 11 月 12 日 [matt]: 省略了作为单独步骤运行 Bzip2 的测试套件,因为 make 会自动运行它(错误 1652)。

  • 2005 年 11 月 7 日 [matt]: 阻止 Udev 终止宿主系统上的 udevd 进程(修复了错误 1651)。 感谢 Alexander Patrakov 提供的报告和修复程序。

  • 2005 年 11 月 5 日 [matt]: 在第 5 章的工具链健全性检查中添加一条注释,解释说如果 TCL 构建失败,则表明工具链已损坏(错误 1581)。

  • 2005 年 11 月 4 日 [matt]: 更正了运行 Module-Init-Tools 测试套件的说明(修复了错误 1597)。 感谢 Greg Schafer、Tushar Teredesai 和 Randy McMurchy 提供的补丁。

  • 2005 年 10 月 29 日 [manuel]: PDF 修复。

  • 2005 年 10 月 23 日 [manuel]: 添加了 Bash 文档安装。 添加了关于 libiconv 和 Cracklib 的注释。 修复了 Sed 文档的安装。 用 sed 命令替换了 IPRoute2 的补丁。

  • 2005 年 10 月 19 日 [manuel]: 将致谢更新为当前 trunk 版本。 在 preface 和 chapter01 页面中移植了一些修订更改。 将 chapter02 移至第二部分。 添加了 -v 开关。 从 trunk 移植了一些拼写错误和修订修复。

  • 2005 年 10 月 19 日 [manuel]: 将样式表、Makefile 和相关文件更新为当前 trunk 版本。

  • 2005 年 10 月 15 日 [matt]: 使用了更新版本的 Udev 规则文件(修复了错误 1639)。

  • 2005 年 10 月 15 日 [matt]: 添加了 Udev 规则文件所需的 cdrom 组

  • 2005 年 10 月 14 日 [ken]: 添加了一个补丁,允许从运行 gcc-4 的主机构建 binutils,更新了 glibc 指令以用于 rtld 补丁,更新了 perl 和 zlib 的空间/时间。

  • 2005 年 10 月 14 日 [matt]: 添加了一个补丁来修复 util-linux 中的安全漏洞。

  • 2005 年 10 月 14 日 [matt]: 添加了更新的 vim 安全补丁。

  • 2005 年 10 月 14 日 [jhuntwork]: 添加了 bzip2 安全和安装文档补丁。

  • 2005 年 10 月 14 日 [jhuntwork]: 为 texinfo 添加了 tempfile 补丁。

  • 2005 年 10 月 14 日 [ken]: 更新了更新日志中的软件包和补丁,仅反映自 6.1 以来的更改。 更新 zlib。

  • 2005 年 10 月 13 日 [ken]: 修复了已安装文件列表中的已知错误并提高了 perl 版本。

1.3. 资源

1.3.1. 常见问题解答

如果在构建 LFS 系统期间遇到任何错误,有任何疑问,或者认为书中存在拼写错误,请首先查阅位于 http://www.linuxfromscratch.org/faq/ 的常见问题解答 (FAQ)。

1.3.2. 邮件列表

linuxfromscratch.org服务器托管了许多用于 LFS 项目开发的邮件列表。 这些列表包括主要的开发和支持列表等。 如果常见问题解答不能解决您遇到的问题,下一步是在 http://www.linuxfromscratch.org/search.html 上搜索邮件列表。

有关不同列表的信息、如何订阅、存档位置和其他信息,请访问 http://www.linuxfromscratch.org/mail.html

1.3.3. 新闻服务器

托管在linuxfromscratch.org的邮件列表也可以通过网络新闻传输协议 (NNTP) 服务器访问。 发布到邮件列表的所有消息都会复制到相应的新闻组,反之亦然。

新闻服务器位于news.linuxfromscratch.org.

1.3.4. IRC

LFS 社区的几位成员在我们的社区 Internet Relay Chat (IRC) 网络上提供帮助。 在使用此支持之前,请确保您的问题尚未在 LFS 常见问题解答或邮件列表存档中找到答案。 您可以在

上找到 IRC 网络irc.linuxfromscratch.org。 支持频道名为 #LFS-support。

1.3.5. 参考资料

有关软件包的其他信息,有用的提示可在位于 http://www.linuxfromscratch.org/~matthew/LFS-references.html 的 LFS 软件包参考页面中找到。

1.3.6. 镜像站点

LFS 项目在全球范围内拥有多个镜像站点,以便更方便地访问网站和下载所需的软件包。 请访问 LFS 网站 http://www.linuxfromscratch.org/mirrors.html 以获取当前镜像站点的列表。

1.3.7. 联系方式

请将所有问题和评论发送到其中一个 LFS 邮件列表(参见上文)。

1.4. 帮助

如果在阅读本书时遇到问题或疑问,请查看 http://www.linuxfromscratch.org/faq/#generalfaq 上的常见问题解答页面。 问题通常已经在那里得到解答。 如果您的问题未在此页面上得到解答,请尝试找到问题的根源。 以下提示将为您提供一些故障排除指导: http://www.linuxfromscratch.org/hints/downloads/files/errors.txt

如果您在常见问题解答中找不到您的问题,请在 http://www.linuxfromscratch.org/search.html 上搜索邮件列表。

我们还有一个出色的 LFS 社区,愿意通过邮件列表和 IRC 提供帮助(请参阅本书的 第 1.3 节,“资源”)。 但是,我们每天都会收到几个支持问题,其中许多问题可以通过首先访问常见问题解答和搜索邮件列表来轻松解答。 因此,为了让我们能够提供最好的帮助,您需要先自己做一些研究。 这使我们能够专注于更多不寻常的支持需求。 如果您的搜索没有产生解决方案,请在您的帮助请求中包含所有相关信息(如下所述)。

1.4.1. 需要提及的事项

除了对所经历问题的简要说明之外,在任何帮助请求中都需要包含的基本事项包括

  • 所使用的书籍版本(在本例中为 6.1.1)

  • 用于创建 LFS 的宿主发行版和版本

  • 遇到问题的软件包或部分

  • 收到的确切错误消息或症状

  • 请注意您是否完全按照本书进行操作

注意

偏离本书的内容并不意味着我们将不会帮助你。毕竟,LFS 是关于个人偏好的。坦诚地说明对既定流程的任何更改,有助于我们评估并确定您的问题的可能原因。

1.4.2. 配置脚本问题

如果在运行 configure 脚本时出现问题,请查看config.log文件。此文件可能包含在 configure 期间遇到的但未在屏幕上打印的错误。如果您需要寻求帮助,请包含相关的行。

1.4.3. 编译问题

屏幕输出和各种文件的内容对于确定编译问题的原因都很有用。来自 configure 脚本和 make 运行的屏幕输出可能很有帮助。没有必要包含整个输出,但要包含足够的相关信息。以下是从 make 的屏幕输出中包含的信息类型的示例

gcc -DALIASPATH=\"/mnt/lfs/usr/share/locale:.\"
-DLOCALEDIR=\"/mnt/lfs/usr/share/locale\" 
-DLIBDIR=\"/mnt/lfs/usr/lib\"
-DINCLUDEDIR=\"/mnt/lfs/usr/include\" -DHAVE_CONFIG_H -I. -I.
-g -O2 -c getopt1.c
gcc -g -O2 -static -o make ar.o arscan.o commands.o dir.o 
expand.o file.o function.o getopt.o implicit.o job.o main.o 
misc.o read.o remake.o rule.o signame.o variable.o vpath.o 
default.o remote-stub.o version.o opt1.o
-lutil job.o: In function `load_too_high':
/lfs/tmp/make-3.79.1/job.c:1565: undefined reference 
to `getloadavg'
collect2: ld returned 1 exit status
make[2]: *** [make] Error 1
make[2]: Leaving directory `/lfs/tmp/make-3.79.1'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/lfs/tmp/make-3.79.1'
make: *** [all-recursive-am] Error 2

在这种情况下,很多人只会包含底部部分

make [2]: *** [make] Error 1

这不足以正确诊断问题,因为它只指出发生了错误,而不是什么出错了。应该保存整个部分,如上面的示例所示,因为它包含执行的命令和相关的错误消息。

一篇关于在互联网上寻求帮助的优秀文章可以在网上找到:http://catb.org/~esr/faqs/smart-questions.html。阅读并遵循本文档中的提示,以增加获得所需帮助的可能性。

第二部分. 准备构建

第2章. 准备新分区

2.1. 简介

在本章中,将准备用于托管 LFS 系统的分区。我们将创建分区本身,在其上创建文件系统,并挂载它。

2.2. 创建新分区

像大多数其他操作系统一样,LFS 通常安装在专用分区上。构建 LFS 系统的推荐方法是使用可用的空分区,或者如果您有足够的未分区空间,则创建一个。但是,LFS 系统(实际上甚至可以有多个 LFS 系统)也可以安装在已经被另一个操作系统占用的分区上,并且不同的系统将和平共存。文档 http://www.linuxfromscratch.org/hints/downloads/files/lfs_next_to_existing_systems.txt 解释了如何实现这一点,而本书讨论了使用全新分区进行安装的方法。

一个最小系统需要一个大约 1.3 GB (千兆字节) 的分区。这足以存储所有源 tarball 并编译软件包。但是,如果 LFS 系统旨在成为主要的 Linux 系统,则可能会安装其他软件,这将需要额外的空间 (2-3 GB)。LFS 系统本身不会占用这么多空间。这部分需求的主要目的是提供足够的可用临时存储空间。编译软件包可能需要大量的磁盘空间,这些空间将在软件包安装后被回收。

因为并非总是有足够的随机存取内存 (RAM) 可用于编译过程,所以最好使用一个小磁盘分区作为交换空间。内核使用它来存储不常用的数据,并为活动进程留下更多内存。LFS 系统的交换分区可以与宿主系统使用的交换分区相同,在这种情况下,不需要创建另一个。

启动磁盘分区程序,例如 cfdiskfdisk,并使用命令行选项命名将在其上创建新分区的硬盘 - 例如/dev/hda对于主集成驱动器电子设备 (IDE) 磁盘。创建 Linux 本地分区和交换分区(如果需要)。请参考cfdisk(8)或者fdisk(8)如果您还不知道如何使用这些程序。

记住新分区的指定 (例如,hda5)。本书将此称为 LFS 分区。还要记住交换分区的指定。稍后需要在/etc/fstab文件中使用这些名称。

2.3. 在分区上创建文件系统

现在已经设置了一个空白分区,可以创建文件系统了。 Linux 世界中最广泛使用的系统是第二个扩展文件系统 (ext2),但随着更新的高容量硬盘的出现,日志文件系统越来越受欢迎。我们将创建一个 ext2 文件系统。可以在 http://www.linuxfromscratch.org/blfs/view/svn/postlfs/filesystems.html 找到其他文件系统的构建说明。

要在 LFS 分区上创建 ext2 文件系统,请运行以下命令

mke2fs -v /dev/[xxx]

[xxx] 替换为 LFS 分区的名称(hda5在我们之前的例子中)。

注意

某些宿主发行版在其文件系统创建工具 (e2fsprogs) 中使用自定义功能。这可能会导致在第 9 章中启动到新的 LFS 时出现问题,因为 LFS 安装的 e2fsprogs 不支持这些功能;您会收到类似于“unsupported filesystem features, upgrade your e2fsprogs”的错误。要检查您的宿主系统是否使用自定义增强功能,请运行以下命令

debugfs -R feature /dev/[xxx]

如果输出包含除以下之外的功能:dir_index; filetype; large_file; resize_inode or sparse_super 那么您的宿主系统可能具有自定义增强功能。在这种情况下,为了避免以后的问题,您应该编译标准的 e2fsprogs 软件包,并使用生成的二进制文件来重新创建 LFS 分区上的文件系统

cd /tmp
tar -xjvf /path/to/sources/e2fsprogs-1.37.tar.bz2
cd e2fsprogs-1.37
mkdir -v build
cd build
../configure
make #note that we intentionally don't 'make install' here!
./misc/mke2fs -v /dev/[xxx]
cd /tmp
rm -rfv e2fsprogs-1.37

如果创建了交换分区,则需要通过发出以下命令对其进行初始化以供使用。如果您使用的是现有交换分区,则无需格式化它。

mkswap -v /dev/[yyy]

[yyy] 替换为交换分区的名称。

2.4. 挂载新分区

现在已经创建了文件系统,需要使分区可访问。为了做到这一点,需要在所选的挂载点挂载分区。就本书而言,假设文件系统挂载在/mnt/lfs下,但目录选择由您决定。

选择一个挂载点并将其分配给LFS环境变量,方法是运行

export LFS=/mnt/lfs

接下来,创建挂载点并挂载 LFS 文件系统,方法是运行

mkdir -pv $LFS
mount -v /dev/[xxx] $LFS

[xxx] 替换为 LFS 分区的指定。

如果使用多个分区用于 LFS(例如,一个用于///usr),请使用以下命令挂载它们

mkdir -pv $LFS
mount -v /dev/[xxx] $LFS
mkdir -v $LFS/usr
mount -v /dev/[yyy] $LFS/usr

[xxx][yyy] 替换为适当的分区名称。

确保没有使用过于严格的权限(例如 nosuid、nodev 或 noatime 选项)挂载此新分区。运行没有任何参数的 mount 命令,以查看为已挂载的 LFS 分区设置了哪些选项。如果设置了 nosuidnodev 和/或 noatime,则需要重新挂载该分区。

现在已经建立了一个可以工作的地方,是时候下载软件包了。

第3章. 软件包和补丁

3.1. 简介

本章包括构建基本 Linux 系统需要下载的软件包列表。列出的版本号对应于已知可以工作的软件版本,本书是基于它们的使用编写的。我们强烈建议不要使用较新版本,因为一个版本的构建命令可能不适用于较新版本。最新的软件包版本也可能存在需要解决的问题。这些解决方法将在本书的开发版本中开发和稳定。

下载位置可能并非始终可访问。如果自本书出版以来下载位置发生了变化,Google (http://www.google.com/) 为大多数软件包提供了一个有用的搜索引擎。如果此搜索不成功,请尝试在 http://www.linuxfromscratch.org/lfs/packages.html 讨论的替代下载方式之一。

下载的软件包和补丁需要存储在某个方便在整个构建过程中可用的位置。还需要一个工作目录来解压源代码并构建它们。$LFS/sources可以同时用作存储 tarball 和补丁的地方以及用作工作目录。通过使用此目录,所需的元素将位于 LFS 分区上,并且在构建过程的所有阶段都可用。

要创建此目录,请在开始下载会话之前,以用户 root 身份执行以下命令

mkdir -v $LFS/sources

使此目录可写且粘滞。“粘滞”意味着即使多个用户对目录具有写权限,也只有文件的所有者才能删除粘滞目录中的文件。以下命令将启用写入和粘滞模式

chmod -v a+wt $LFS/sources

3.2. 所有软件包

下载或以其他方式获取以下软件包

Autoconf (2.59) - 908 千字节 (KB)

http://ftp.gnu.org/gnu/autoconf/

Automake (1.9.5) - 748 KB

http://ftp.gnu.org/gnu/automake/

Bash (3.0) - 1,824 KB

http://ftp.gnu.org/gnu/bash/

Bash 文档 (3.0) - 1,994 KB

http://ftp.gnu.org/gnu/bash/

Binutils (2.15.94.0.2.2) - 11,056 KB

https://linuxkernel.org.cn/pub/linux/devel/binutils/

Bison (2.0) - 916 KB

http://ftp.gnu.org/gnu/bison/

Bzip2 (1.0.3) - 596 KB

http://www.bzip.org/

Coreutils (5.2.1) - 4,184 KB

http://ftp.gnu.org/gnu/coreutils/

DejaGNU (1.4.4) - 852 KB

http://ftp.gnu.org/gnu/dejagnu/

Diffutils (2.8.1) - 648 KB

http://ftp.gnu.org/gnu/diffutils/

E2fsprogs (1.37) - 3,100 KB

http://prdownloads.sourceforge.net/e2fsprogs/

Expect (5.43.0) - 416 KB

http://expect.nist.gov/src/

File (4.13) - 324 KB

ftp://ftp.gw.com/mirrors/pub/unix/file/

注意

文件 (4.13) 可能已无法在所列位置找到。主下载站点的管理员有时会在发布新版本时删除旧版本。您也可以在以下位置找到可能包含正确版本的替代下载站点: http://www.linuxfromscratch.org/lfs/download.html#ftp

Findutils (4.2.23) - 784 KB

http://ftp.gnu.org/gnu/findutils/

Flex (2.5.31) - 672 KB

http://prdownloads.sourceforge.net/lex/

Gawk (3.1.4) - 1,696 KB

http://ftp.gnu.org/gnu/gawk/

GCC (3.4.3) - 26,816 KB

http://ftp.gnu.org/gnu/gcc/

Gettext (0.14.3) - 4,568 KB

http://ftp.gnu.org/gnu/gettext/

Glibc (2.3.4) - 12,924 KB

http://ftp.gnu.org/gnu/glibc/

Glibc-Linuxthreads (2.3.4) - 236 KB

http://ftp.gnu.org/gnu/glibc/

Grep (2.5.1a) - 520 KB

http://ftp.gnu.org/gnu/grep/

Groff (1.19.1) - 2,096 KB

http://ftp.gnu.org/gnu/groff/

GRUB (0.96) - 768 KB

ftp://alpha.gnu.org/gnu/grub/

Gzip (1.3.5) - 284 KB

ftp://alpha.gnu.org/gnu/gzip/

Hotplug (2004_09_23) - 40 KB

https://linuxkernel.org.cn/pub/linux/utils/kernel/hotplug/

Iana-Etc (1.04) - 176 KB

http://www.sethwklein.net/projects/iana-etc/downloads/

Inetutils (1.4.2) - 752 KB

http://ftp.gnu.org/gnu/inetutils/

IPRoute2 (2.6.11-050330) - 276 KB

http://developer.osdl.org/dev/iproute2/download/

Kbd (1.12) - 624 KB

https://linuxkernel.org.cn/pub/linux/utils/kbd/

Less (382) - 216 KB

http://ftp.gnu.org/gnu/less/

LFS-Bootscripts (3.2.1) - 32 KB

http://downloads.linuxfromscratch.org/

Libtool (1.5.14) - 1,604 KB

http://ftp.gnu.org/gnu/libtool/

Linux (2.6.11.12) - 35,792 KB

https://linuxkernel.org.cn/pub/linux/kernel/v2.6/

Linux-Libc-Headers (2.6.11.2) - 2,476 KB

http://ep09.pld-linux.org/~mmazur/linux-libc-headers/

M4 (1.4.3) - 304 KB

http://ftp.gnu.org/gnu/m4/

Make (3.80) - 904 KB

http://ftp.gnu.org/gnu/make/

Man (1.5p) - 208 KB

https://linuxkernel.org.cn/pub/linux/utils/man/

Man-pages (2.01) - 1,640 KB

https://linuxkernel.org.cn/pub/linux/docs/manpages/

Mktemp (1.5) - 68 KB

ftp://ftp.mktemp.org/pub/mktemp/

Module-Init-Tools (3.1) - 128 KB

https://linuxkernel.org.cn/pub/linux/utils/kernel/module-init-tools/

Module-Init-Tools-Testsuite (3.1) - 34 KB

https://linuxkernel.org.cn/pub/linux/utils/kernel/module-init-tools/

Ncurses (5.4) - 1,556 KB

ftp://invisible-island.net/ncurses/

Patch (2.5.4) - 156 KB

http://ftp.gnu.org/gnu/patch/

Perl (5.8.7) - 9,628 KB

http://ftp.funet.fi/pub/CPAN/src/

Procps (3.2.5) - 224 KB

http://procps.sourceforge.net/

Psmisc (21.6) - 188 KB

http://prdownloads.sourceforge.net/psmisc/

Readline (5.0) - 1,456 KB

http://ftp.gnu.org/gnu/readline/

Sed (4.1.4) - 632 KB

http://ftp.gnu.org/gnu/sed/

Shadow (4.0.9) - 1,084 KB

ftp://ftp.pld.org.pl/software/shadow/

注意

Shadow (4.0.9) 可能已无法在所列位置找到。主下载站点的管理员有时会在发布新版本时删除旧版本。您也可以在以下位置找到可能包含正确版本的替代下载站点: http://www.linuxfromscratch.org/lfs/download.html#ftp

Sysklogd (1.4.1) - 72 KB

http://www.infodrom.org/projects/sysklogd/download/

Sysvinit (2.86) - 88 KB

ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/

Tar (1.15.1) - 1,580 KB

http://ftp.gnu.org/gnu/tar/

Tcl (8.4.9) - 2,748 KB

http://prdownloads.sourceforge.net/tcl/

Texinfo (4.8) - 1,492 KB

http://ftp.gnu.org/gnu/texinfo/

Udev (056) - 476 KB

https://linuxkernel.org.cn/pub/linux/utils/kernel/hotplug/

Udev 规则配置 - 5 KB

http://downloads.linuxfromscratch.org/udev-config-4.rules

Util-linux (2.12q) - 1,344 KB

https://linuxkernel.org.cn/pub/linux/utils/util-linux/

Vim (6.3) - 3,620 KB

ftp://ftp.vim.org/pub/vim/unix/

Vim (6.3) 语言文件 (可选) - 540 KB

ftp://ftp.vim.org/pub/vim/extra/

Zlib (1.2.3) - 415 KB

http://www.zlib.net/

这些软件包的总大小:146 MB

3.3. 需要的补丁

除了软件包之外,还需要一些补丁。这些补丁修复了软件包中应该由维护者修复的任何错误。这些补丁还对软件包进行小的修改,使其更易于使用。构建 LFS 系统需要以下补丁

Bash Avoid Wcontinued 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/bash-3.0-avoid_WCONTINUED-1.patch

Bash 各种修复 - 23 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/bash-3.0-fixes-3.patch

Binutils 从运行 Gcc4 的主机构建补丁 - 2 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/binutils-2.15.94.0.2.2-gcc4-1.patch

Bzip2 文档补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/bzip2-1.0.3-install_docs-1.patch

Bzip2 Bzgrep 安全修复补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/bzip2-1.0.3-bzgrep_security-1.patch

Coreutils 抑制 Uptime, Kill, Su 补丁 - 15 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/coreutils-5.2.1-suppress_uptime_kill_su-1.patch

Coreutils Uname 补丁 - 4 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/coreutils-5.2.1-uname-2.patch

Expect Spawn 补丁 - 7 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/expect-5.43.0-spawn-1.patch

Flex Brokenness 补丁 - 156 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/flex-2.5.31-debian_fixes-3.patch

GCC Linkonce 补丁 - 12 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/gcc-3.4.3-linkonce-1.patch

GCC No-Fixincludes 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/gcc-3.4.3-no_fixincludes-1.patch

GCC Specs 补丁 - 14 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/gcc-3.4.3-specs-2.patch

Glibc Rtld Search Dirs 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/glibc-2.3.4-rtld_search_dirs-1.patch

Glibc Fix Testsuite 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/glibc-2.3.4-fix_test-1.patch

Glibc TLS Assertion 补丁 - 6 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/glibc-2.3.4-tls_assert-1.patch

Gzip 安全补丁 - 2 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/gzip-1.3.5-security_fixes-1.patch

Inetutils Kernel Headers 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/inetutils-1.4.2-kernel_headers-1.patch

Inetutils No-Server-Man-Pages 补丁 - 4 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/inetutils-1.4.2-no_server_man_pages-1.patch

Mktemp Tempfile 补丁 - 3 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/mktemp-1.5-add_tempfile-2.patch

Perl Libc 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/perl-5.8.7-libc-1.patch

Readline 修复补丁 - 7 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/readline-5.0-fixes-1.patch

Sysklogd 修复补丁 - 27 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/sysklogd-1.4.1-fixes-1.patch

Tar Sparse 修复补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/tar-1.15.1-sparse_fix-1.patch

Texinfo Tempfile 修复补丁 - 2 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/texinfo-4.8-tempfile_fix-1.patch

Util-linux Cramfs 补丁 - 3 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/util-linux-2.12q-cramfs-1.patch

Util-linux Umount 补丁 - 1 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/util-linux-2.12q-umount_fix-1.patch

Vim 安全补丁 - 8 KB

http://www.linuxfromscratch.org/patches/lfs/6.1.1/vim-6.3-security_fix-2.patch

除了上述必需的补丁之外,LFS 社区还创建了许多可选补丁。这些可选补丁解决了小问题或启用了默认情况下未启用的功能。您可以随意浏览位于 http://www.linuxfromscratch.org/patches/ 的补丁数据库,并获取任何其他补丁以满足系统需求。

第 4 章. 最后的准备工作

4.1. 关于 $LFS

在本书中,环境变量LFS将被使用多次。始终定义此变量至关重要。它应该设置为为 LFS 分区选择的挂载点。检查LFS变量是否已正确设置

echo $LFS

确保输出显示 LFS 分区挂载点的路径,如果遵循提供的示例,则为/mnt/lfs。如果输出不正确,可以使用以下命令设置变量

export LFS=/mnt/lfs

设置此变量的好处是,您可以按字面意思键入诸如 mkdir $LFS/tools 之类的命令。当 shell 处理命令行时,它会自动将“$LFS”替换为“/mnt/lfs”(或变量设置的任何值)。

不要忘记检查$LFS在您离开并重新进入当前工作环境时(例如,对 root 或其他用户执行“su”时)是否已设置。

4.2. 创建 $LFS/tools 目录

第 5 章 中编译的所有程序都将安装在$LFS/tools下,以使其与在 第 6 章 中编译的程序分开。此处编译的程序是临时工具,不会成为最终 LFS 系统的一部分。通过将这些程序保存在单独的目录中,可以在使用后轻松丢弃它们。这还可以防止这些程序最终出现在主机生产目录中(在 第 5 章 中很容易意外地发生)。

root 身份运行以下命令来创建所需的目录

mkdir -v $LFS/tools

下一步是创建一个/tools主机系统上的符号链接。这将指向 LFS 分区上新创建的目录。也以 root 身份运行此命令

ln -sv $LFS/tools /

注意

上述命令是正确的。ln 命令有一些语法变体,因此请务必在报告您认为的错误之前检查 info coreutils lnln(1)

创建的符号链接使工具链能够被编译,以便它始终引用/tools,这意味着编译器、汇编器和链接器将在本章(当我们仍在使用主机中的某些工具时)和下一章(当我们“chrooted”到 LFS 分区时)中工作。

4.3. 添加 LFS 用户

当以用户 root 身份登录时,一个小错误可能会损坏或破坏系统。因此,我们建议以非特权用户身份构建本章中的软件包。您可以使用自己的用户名,但为了更容易设置干净的工作环境,请创建一个名为 lfs 的新用户作为新组(也称为 lfs)的成员,并在安装过程中使用此用户。以 root 身份,发出以下命令以添加新用户

groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs

命令行选项的含义

-s /bin/bash

这使 bash 成为用户 lfs 的默认 shell。

-g lfs

此选项将用户 lfs 添加到组 lfs

-m

这将为 lfs 创建一个主目录。

-k /dev/null

此参数通过将输入位置更改为特殊空设备来防止从骨架目录(默认为/etc/skel)可能复制文件。

lfs

这是创建的组和用户的实际名称。

要以 lfs 身份登录(与以 root 身份登录时切换到用户 lfs 不同,后者不需要 lfs 用户拥有密码),请为 lfs 提供密码

passwd lfs

授予 lfs$LFS/tools的完全访问权限,方法是使 lfs 成为目录所有者

chown -v lfs $LFS/tools

如果按照建议创建了单独的工作目录,请将此目录的所有权授予用户 lfs

chown -v lfs $LFS/sources

接下来,以用户 lfs 身份登录。这可以通过虚拟控制台、显示管理器或使用以下替换用户命令来完成

su - lfs

-”指示 su 启动登录 shell,而不是非登录 shell。这两种类型的 shell 之间的区别可以在bash(1)info bash 中找到详细信息。

4.4. 设置环境

通过为 bash shell 创建两个新的启动文件来设置良好的工作环境。以用户 lfs 身份登录时,发出以下命令以创建一个新的.bash_profile:

cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

当以用户 lfs 身份登录时,初始 shell 通常是一个 登录 shell,它会读取主机上的/etc/profile(可能包含一些设置和环境变量),然后读取.bash_profileexec env -i.../bin/bash 命令在.bash_profile文件中将正在运行的 shell 替换为一个全新的 shell,其环境完全为空,除了HOME, TERMPS1变量。这确保了主机系统上任何不需要且可能有害的环境变量都不会泄漏到构建环境中。此处使用的技术实现了确保干净环境的目标。

shell 的新实例是一个 非登录 shell,它不读取/etc/profile或者.bash_profile文件,而是读取.bashrc文件。现在创建.bashrc文件。

cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL PATH
EOF

set +h 命令关闭 bash 的哈希功能。哈希通常是一个有用的功能——bash 使用哈希表来记住可执行文件的完整路径,以避免一次又一次地搜索PATH来查找同一个可执行文件。但是,应该尽快使用新的工具。通过关闭哈希功能,shell 将始终搜索PATH,以便在程序运行时找到。这样,shell 将在$LFS/tools中找到新编译的工具,一旦它们可用,而不会记住同一程序先前版本的不同位置。

将用户文件创建掩码 (umask) 设置为 022 可确保新创建的文件和目录只能由其所有者写入,但可由任何人读取和执行(假设 open(2) 系统调用使用默认模式,新文件最终将具有权限模式 644,目录具有模式 755)。

LFS变量应设置为所选的挂载点。

LC_ALL变量控制某些程序的本地化,使其消息遵循指定国家/地区的约定。如果主机系统使用的 Glibc 版本低于 2.2.4,则将LC_ALL设置为 “POSIX” 或 “C” 以外的值(在本章中)可能会导致您退出 chroot 环境并希望稍后返回时出现问题。 将LC_ALL设置为 “POSIX” 或 “C”(两者等效)可确保一切在 chroot 环境中按预期工作。

通过将/tools/bin放在标准PATH之前,在 第 5 章中安装的所有程序都会在安装后立即被 shell 拾取。 结合关闭哈希功能,这限制了当第 5 章环境中提供相同程序时,使用来自主机的旧程序的风险。

最后,为了使环境完全准备好构建临时工具,请执行刚创建的用户配置文件。

source ~/.bash_profile

4.5. 关于 SBUs

许多人想预先知道编译和安装每个软件包大约需要多长时间。 因为 Linux From Scratch 可以在许多不同的系统上构建,所以不可能提供准确的时间估计。 最大的软件包 (Glibc) 在最快的系统上大约需要 20 分钟,但在较慢的系统上可能需要长达三天的时间! 将使用标准构建单元 (SBU) 度量而不是提供实际时间。

SBU 度量的运作方式如下。 从本书中编译的第一个软件包是 第 5 章中的 Binutils。 编译此软件包所花费的时间将被称为标准构建单元或 SBU。 所有其他编译时间将相对于此时间表示。

例如,假设一个软件包的编译时间为 4.5 SBU。 这意味着如果一个系统花费 10 分钟来编译和安装 Binutils 的第一次传递,那么构建此示例软件包将花费 大约 45 分钟。 幸运的是,大多数构建时间都比 Binutils 的时间短。

一般来说,SBU 并不是完全准确的,因为它们取决于许多因素,包括主机系统的 GCC 版本。 请注意,在基于对称多处理器 (SMP) 的机器上,SBU 的准确性甚至更低。 提供它们是为了估计安装软件包可能需要多长时间,但在某些情况下,这些数字可能会相差几十分钟。

要查看一些特定机器的实际计时,我们建议访问 LinuxFromScratch SBU 主页:http://www.linuxfromscratch.org/~bdubbs/

4.6. 关于测试套件

大多数软件包都提供测试套件。 运行新构建软件包的测试套件是一个好主意,因为它可以提供“健全性检查”,表明一切都已正确编译。 通过其一组检查的测试套件通常证明该软件包的运行方式与开发人员的预期一样。 但是,它并不能保证该软件包完全没有错误。

有些测试套件比其他测试套件更重要。 例如,由于核心工具链软件包(GCC、Binutils 和 Glibc)在正常运行的系统中起着核心作用,因此它们的测试套件至关重要。 GCC 和 Glibc 的测试套件可能需要很长时间才能完成,尤其是在较慢的硬件上,但强烈建议使用。

注意

经验表明,从在 第 5 章中运行测试套件几乎没有什么收获。 无法避免的事实是,主机系统始终会对该章中的测试产生一些影响,经常导致无法解释的失败。 因为在 第 5 章中构建的工具是临时的并且最终会被丢弃,所以我们不建议普通读者在 第 5 章中运行测试套件。 提供了运行这些测试套件的说明,以供测试人员和开发人员使用,但它们是严格可选的。

运行 Binutils 和 GCC 的测试套件的一个常见问题是缺少伪终端 (PTY)。 这可能导致大量测试失败。 这可能出于多种原因发生,但最可能的原因是主机系统没有devpts文件系统设置正确。 第 5 章更详细地讨论了此问题。

有时,软件包测试套件会失败,但由于开发人员知道并且认为不重要的原因。 请查看位于 http://www.linuxfromscratch.org/lfs/build-logs/6.1.1/ 的日志,以验证这些失败是否是预期的。 该站点适用于本书中的所有测试。

第 5. 章 构建临时系统

5.1. 简介

本章介绍如何编译和安装最小的 Linux 系统。 该系统将包含足够的工具来开始在 第 6 章中构建最终 LFS 系统,并允许使用比最小环境更方便的工作环境。

构建此最小系统有两个步骤。 第一步是构建一个新的、独立于主机的工具链(编译器、汇编器、链接器、库和一些有用的实用程序)。 第二步使用此工具链来构建其他基本工具。

在本章中编译的文件将安装在$LFS/tools目录下,以将它们与下一章和主机生产目录中安装的文件分开。 由于此处编译的软件包是临时的,因此我们不希望它们污染即将到来的 LFS 系统。

重要提示

在发出软件包的构建指令之前,应以用户 lfs 身份解压软件包,并 cd 到创建的目录中。 构建说明假定正在使用 bash shell。

在编译之前,会修补几个软件包,但仅当需要修补程序来规避问题时才这样做。 在本章和下一章中通常都需要补丁,但有时只需要在一章中进行补丁。 因此,如果下载的补丁的说明似乎丢失,请不要担心。 应用补丁时也可能遇到有关 offsetfuzz 的警告消息。 不要担心这些警告,因为补丁仍然已成功应用。

在编译大多数软件包期间,屏幕上会滚动显示几个警告。 这些是正常的,可以安全地忽略。 这些警告与它们的外观一样,是关于不赞成使用但并非无效的 C 或 C++ 语法的警告。 C 标准经常更改,并且某些软件包仍使用较旧的标准。 这不是问题,但会提示警告。

重要提示

安装每个软件包后,删除其源目录和构建目录,除非另有明确说明。 删除源可防止以后重新安装同一软件包时出现错误配置。 只有三个软件包需要保留源目录和构建目录,以便以后的命令使用其内容。 请特别注意这些提醒。

最后一次检查LFS环境变量是否设置正确

echo $LFS

确保输出显示 LFS 分区挂载点的路径,如果遵循提供的示例,则为/mnt/lfs,使用我们的示例。

5.2. 工具链技术说明

本节介绍整体构建方法背后的一些原理和技术细节。 立即理解本节中的所有内容并非必不可少。 在执行实际构建之后,这些信息中的大多数会更清晰。 可以在过程中的任何时间参考本节。

第 5 章的总体目标是提供一个临时的环境,可以 chroot 到其中,并从中可以生成干净、无故障的目标 LFS 系统构建,如 第 6 章所示。 在此过程中,我们会尽可能地将新系统与主机系统分离,并在此过程中构建一个独立的、自托管的工具链。 应该注意的是,构建过程旨在最大限度地降低新读者的风险,并同时提供最大的教育价值。

重要提示

在继续之前,请注意工作平台的名称,通常被称为目标三元组(target triplet)。很多时候,目标三元组很可能是 i686-pc-linux-gnu。一个确定目标三元组名称的简单方法是运行许多软件包源代码自带的 config.guess 脚本。解压 Binutils 源代码并运行该脚本:./config.guess,并注意输出结果。

同时请注意平台的动态链接器的名称,通常被称为动态加载器(不要与 Binutils 自带的标准链接器 ld 混淆)。Glibc 提供的动态链接器负责查找和加载程序所需的共享库,准备程序运行,然后运行该程序。动态链接器的名称通常是ld-linux.so.2。 在不太常见的平台上,名称可能是ld.so.1,而较新的 64 位平台可能完全是其他名称。可以通过查看主机系统的/lib目录来确定平台动态链接器的名称。确定名称的万无一失的方法是通过运行:readelf -l <name of binary> | grep interpreter 来检查主机系统中的随机二进制文件并注意输出结果。涵盖所有平台的权威参考资料在 Glibc 源代码树根目录下的shlib-versions文件中。

以下是 第五章 构建方法的一些关键技术要点:

  • 该过程在原则上类似于交叉编译,即安装在相同前缀中的工具协同工作,因此利用了一点 GNU 的“魔法”。

  • 仔细操作标准链接器的库搜索路径,确保程序仅与选定的库链接。

  • 仔细操作 gccspecs文件,告诉编译器将使用哪个目标动态链接器。

首先安装 Binutils,因为 GCC 和 Glibc 的 configure 运行都会对汇编器和链接器执行各种功能测试,以确定要启用或禁用哪些软件功能。这一点比人们最初意识到的更为重要。错误配置的 GCC 或 Glibc 可能会导致工具链出现细微的损坏,这种损坏的影响可能要到整个发行版的构建接近尾声时才会显现出来。测试套件的失败通常会在执行过多额外工作之前突出显示此错误。

Binutils 将其汇编器和链接器安装在两个位置:/tools/bin/tools/$TARGET_TRIPLET/bin。一个位置中的工具硬链接到另一个位置。链接器的一个重要方面是其库搜索顺序。可以通过将 --verbose 标志传递给 ld 来获得详细信息。例如,ld --verbose | grep SEARCH 将说明当前的搜索路径及其顺序。它通过编译一个虚拟程序并将 --verbose 开关传递给链接器,显示哪些文件由 ld 链接。例如,gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded 将显示在链接期间成功打开的所有文件。

下一个安装的软件包是 GCC。可以在其 configure 运行期间看到的一个示例是

checking what assembler to use... 
        /tools/i686-pc-linux-gnu/bin/as
checking what linker to use... /tools/i686-pc-linux-gnu/bin/ld

这很重要,原因如上所述。它还表明 GCC 的 configure 脚本不会搜索 PATH 目录来查找要使用的工具。但是,在 gcc 本身的实际操作过程中,不一定使用相同的搜索路径。要找出 gcc 将使用哪个标准链接器,请运行:gcc -print-prog-name=ld

通过在编译虚拟程序时将 -v 命令行选项传递给 gcc,可以获得详细信息。例如,gcc -v dummy.c 将显示有关预处理器、编译和汇编阶段的详细信息,包括 gcc 包含的搜索路径及其顺序。

下一个安装的软件包是 Glibc。构建 Glibc 最重要的考虑因素是编译器、二进制工具和内核头文件。编译器通常不是问题,因为 Glibc 总是使用在PATH目录中找到的 gcc。二进制工具和内核头文件可能有点复杂。因此,不要冒险,并使用可用的配置开关来强制进行正确的选择。在运行 configure 之后,检查config.make文件中glibc-build目录中的所有重要详细信息。请注意使用 CC="gcc -B/tools/bin/" 来控制使用哪些二进制工具,以及使用 -nostdinc-isystem 标志来控制编译器的包含搜索路径。这些项突出了 Glibc 软件包的一个重要方面——它在构建机制方面非常自给自足,并且通常不依赖于工具链的默认设置。

在安装 Glibc 之后,进行一些调整以确保搜索和链接仅在/tools前缀内进行。安装一个调整后的 ld,它具有硬连线的搜索路径,该路径仅限于/tools/lib。然后修改 gcc 的 specs 文件,以指向/tools/lib中的新动态链接器。最后一步对于整个过程至关重要。如上所述,到动态链接器的硬连线路径嵌入到每个可执行和链接格式 (ELF) 共享可执行文件中。可以通过运行:readelf -l <name of binary> | grep interpreter 来检查这一点。修改 gcc 的 specs 文件可确保从此处到本章末尾编译的每个程序都将使用/tools/lib.

中的新动态链接器。需要使用新的动态链接器也是为 GCC 的第二遍应用 Specs 补丁的原因。如果不这样做,将导致 GCC 程序本身具有主机系统的/lib目录中的动态链接器的名称嵌入到其中,这将破坏摆脱主机的目标。

在 Binutils 的第二遍期间,我们能够利用 --with-lib-path 配置开关来控制 ld 的库搜索路径。从此时起,核心工具链是自包含和自托管的。 第五章 的其余软件包都针对/tools.

中的新 Glibc 构建。在 第六章 中进入 chroot 环境后,由于上述 Glibc 的自给自足的性质,要安装的第一个主要软件包是 Glibc。一旦将此 Glibc 安装到/usr中,就快速更改工具链的默认设置,然后继续构建目标 LFS 系统的其余部分。

5.3. Binutils-2.15.94.0.2.2 - 第一遍

Binutils 软件包包含一个链接器、一个汇编器和其他用于处理目标文件的工具。

预计构建时间: 1.0 SBU
所需磁盘空间: 179 MB
安装依赖于: Bash、Bison、Coreutils、Diffutils、Flex、GCC、Gettext、Glibc、Grep、M4、Make、Perl、Sed 和 Texinfo

5.3.1. 安装 Binutils

重要的是,Binutils 是第一个编译的软件包,因为 Glibc 和 GCC 都会对可用的链接器和汇编器执行各种测试,以确定要启用哪些自己的功能。

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,请在构建 Binutils 时取消设置它们。

如果您是从运行 Gcc-4 或更高版本的主机构建的,则必须修补此版本的 Binutils 的第一个构建,以便它可以由主机系统编译。

patch -Np1 -i ../binutils-2.15.94.0.2.2-gcc4-1.patch

Binutils 文档建议在源代码目录之外的专用构建目录中构建 Binutils。

mkdir -v ../binutils-build
cd ../binutils-build

注意

为了使本书其余部分中列出的 SBU 值发挥作用,请测量从配置到第一次安装(包括第一次安装)构建此软件包所花费的时间。为了轻松实现这一点,请将这三个命令包装在一个 time 命令中,如下所示:time { ./configure ... && make && make install; }

现在准备编译 Binutils

../binutils-2.15.94.0.2.2/configure --prefix=/tools --disable-nls

configure 选项的含义

--prefix=/tools

这告诉 configure 脚本准备将 Binutils 程序安装在/tools目录中。

--disable-nls

由于临时工具不需要 i18n,因此禁用国际化。

继续编译软件包

make

编译现已完成。通常,我们现在将运行测试套件,但在此早期阶段,测试套件框架(Tcl、Expect 和 DejaGNU)尚未到位。此时运行测试的好处是最小的,因为此第一遍的程序将很快被第二遍的程序替换。

安装软件包

make install

接下来,为稍后的“调整”阶段准备链接器

make -C ld clean
make -C ld LIB_PATH=/tools/lib

make 参数的含义

-C ld clean

这告诉 make 程序删除ld子目录中的所有已编译文件。

-C ld LIB_PATH=/tools/lib

此选项重建ld子目录中的所有内容。指定LIB_PATHMakefile 命令行变量允许我们覆盖默认值,并将其指向临时工具的位置。此变量的值指定链接器的默认库搜索路径。此准备工作将在本章后面用到。

警告

不要移除 Binutils 的构建和源码目录。本章后面的步骤还需要它们保持当前状态。

有关此软件包的详细信息,请参见 第 6.13.2 节,“Binutils 的内容。”

5.4. GCC-3.4.3 - 第一遍

GCC 软件包包含 GNU 编译器集合,其中包括 C 和 C++ 编译器。

大约编译时间: 4.4 SBU
所需磁盘空间: 219 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Findutils、Gawk、Gettext、Glibc、Grep、Make、Perl、Sed 和 Texinfo

5.4.1. 安装 GCC

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 GCC 时取消设置它们。

GCC 文档建议在源代码目录之外的专用构建目录中构建 GCC

mkdir -v ../gcc-build
cd ../gcc-build

准备 GCC 进行编译

../gcc-3.4.3/configure --prefix=/tools \
    --libexecdir=/tools/lib --with-local-prefix=/tools \
    --disable-nls --enable-shared --enable-languages=c

configure 选项的含义

--with-local-prefix=/tools

此开关的目的是移除/usr/local/includegcc 的包含搜索路径中移除。这不是绝对必要的,但是,它有助于最小化宿主系统的影响。

--enable-shared

此开关允许构建libgcc_s.so.1libgcc_eh.a。拥有libgcc_eh.a可用可确保 Glibc(我们编译的下一个软件包)的配置脚本生成正确的结果。

--enable-languages=c

此选项确保仅构建 C 编译器。

继续编译软件包

make bootstrap

make 参数的含义

bootstrap

此目标不仅仅编译 GCC,还会多次编译它。它使用第一轮编译的程序再次编译自身,然后再编译第三次。然后它会比较第二次和第三次编译,以确保它可以完美地重现自身。这也意味着它被正确编译。

编译现已完成。 此时,通常会运行测试套件,但是,如前所述,测试套件框架尚未到位。 此时运行测试的好处是最小的,因为第一次传递的程序将很快被替换。

安装软件包

make install

作为最后的润色,创建一个符号链接。许多程序和脚本运行 cc 而不是 gcc,这用于使程序保持通用性,因此可在未安装 GNU C 编译器的各种 UNIX 系统上使用。 运行 cc 使系统管理员可以自由决定要安装哪个 C 编译器。

ln -vs gcc /tools/bin/cc

有关此软件包的详细信息,请参见 第 6.14.2 节,“GCC 的内容。”

5.5. Linux-Libc-Headers-2.6.11.2

Linux-Libc-Headers 软件包包含“净化”的内核头文件。

大约编译时间: 0.1 SBU
所需磁盘空间: 26.9 MB
安装依赖于: Coreutils

5.5.1. 安装 Linux-Libc-Headers

多年来,通常的做法是在/usr/include中使用“原始”内核头文件(直接来自内核 tarball),但是在过去的几年中,内核开发人员采取了强硬的立场,认为不应该这样做。 这催生了 Linux-Libc-Headers 项目,该项目旨在维护 Linux 头文件的应用程序编程接口 (API) 稳定版本。

安装头文件

cp -Rv include/asm-i386 /tools/include/asm
cp -Rv include/linux /tools/include

如果您的架构不是 i386(兼容),请相应地调整第一个命令。

有关此软件包的详细信息,请参见 第 6.9.2 节,“Linux-Libc-Headers 的内容。”

5.6. Glibc-2.3.4

Glibc 软件包包含主要的 C 库。 此库提供用于分配内存、搜索目录、打开和关闭文件、读取和写入文件、字符串处理、模式匹配、算术等的例程。

大约编译时间: 11.8 SBU
所需磁盘空间: 454 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Gettext、Grep、Make、Perl、Sed 和 Texinfo

5.6.1. 安装 Glibc

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 Glibc 时取消设置它们。

应该注意的是,以除本书中建议的方法以外的任何方式编译 Glibc 都会使系统的稳定性面临风险。

当运行的内核是 2.6.11 或更高版本时,Glibc 有两个测试会失败。 该问题已被确定为测试本身的问题,而不是 C 库或内核的问题。 如果您计划运行测试套件,请应用此补丁

patch -Np1 -i ../glibc-2.3.4-fix_test-1.patch

Glibc 文档建议在源代码目录之外的专用构建目录中构建 Glibc

mkdir -v ../glibc-build
cd ../glibc-build

接下来,准备 Glibc 进行编译

../glibc-2.3.4/configure --prefix=/tools \
    --disable-profile --enable-add-ons \
    --enable-kernel=2.6.0 --with-binutils=/tools/bin \
    --without-gd --with-headers=/tools/include \
    --without-selinux

configure 选项的含义

--disable-profile

这会构建不带分析信息的库。 如果需要对临时工具进行分析,请省略此选项。

--enable-add-ons

这会告诉 Glibc 使用 NPTL 插件作为其线程库。

--enable-kernel=2.6.0

这告诉 Glibc 编译该库,以支持 2.6.x Linux 内核。

--with-binutils=/tools/bin

虽然不是必需的,但此开关可确保在 Glibc 构建期间不会出现与使用哪个 Binutils 程序有关的错误。

--without-gd

这会阻止 memusagestat 程序的构建,该程序坚持链接到宿主系统的库(libgd、libpng、libz 等)。

--with-headers=/tools/include

这告诉 Glibc 针对最近安装到 tools 目录中的头文件编译自身,以便它确切地知道内核具有哪些功能,并可以相应地进行优化。

--without-selinux

从包含 SELinux 功能的主机(例如 Fedora Core 3)进行构建时,Glibc 将构建为支持 SELinux。由于 LFS 工具环境不包含对 SELinux 的支持,因此使用此类支持编译的 Glibc 将无法正常运行。

在此阶段,可能会出现以下警告

configure: WARNING:
*** These auxiliary programs are missing or 
*** incompatible versions: msgfmt
*** some features will be disabled.
*** Check the INSTALL file for required versions.

缺少或不兼容的 msgfmt 程序通常是无害的,但有时会在运行测试套件时引起问题。 此 msgfmt 程序是 Gettext 软件包的一部分,宿主发行版应提供该软件包。 如果 msgfmt 存在但被认为是不兼容的,请升级宿主系统的 Gettext 软件包,或继续不使用它,并查看测试套件是否可以正常运行。

编译软件包

make

编译现已完成。 如前所述,运行本章中安装的临时工具的测试套件不是强制性的。 要运行 Glibc 测试套件(如果需要),以下命令将执行此操作

make check

有关特别重要的测试失败的讨论,请参见 第 6.11 节,“Glibc-2.3.4。”

在本章中,某些测试可能会受到宿主系统上现有工具或环境问题的不利影响。 本章中 Glibc 测试套件的失败通常不必担心。 在第 6 章中安装的 Glibc 是最终将被使用的 Glibc,因此它是需要通过大多数测试的 Glibc(即使在第 6 章中,仍然可能会发生一些失败,例如,对于数学测试)。

遇到故障时,请记下它,然后通过重新发出 make check 命令继续。 测试套件应从中断的地方开始并继续。 可以通过发出 make -k check 命令来避免此停止-启动序列。 如果使用此选项,请务必记录输出,以便以后可以检查日志文件中的失败。

Glibc 的安装阶段将在最后发出一个关于缺少/tools/etc/ld.so.conf的无害警告。 使用以下方法阻止此警告

mkdir -v /tools/etc
touch /tools/etc/ld.so.conf

安装软件包

make install

不同的国家和文化对于如何交流有着不同的习惯。 这些习惯的范围从表示日期和时间的格式到更复杂的问题,例如所说的语言。 GNU 程序的“国际化”通过区域设置进行工作。

注意

如果未在本章中运行测试套件(按照建议),则无需立即安装区域设置。 适当的区域设置将在下一章中安装。

无论如何都要安装 Glibc 区域设置,请使用以下命令

make localedata/install-locales

为了节省时间,运行上一个命令(该命令生成并安装 Glibc 知道的每个区域设置)的替代方法是仅安装那些想要和需要的区域设置。 这可以使用 localedef 命令来实现。 有关此命令的信息位于 Glibc 源代码的INSTALL文件中。 但是,为了使将来软件包的测试能够通过,特别是 GCC 中的 libstdc++ 测试,需要许多区域设置。 以下说明(代替上面使用的 install-locales 目标)将安装成功运行测试所需的最小区域设置集

mkdir -pv /tools/lib/locale
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i ja_JP -f EUC-JP ja_JP

有关此软件包的详细信息,请参见 第 6.11.4 节,“Glibc 的内容。”

5.7. 调整工具链

现在已安装了临时 C 库,本章其余部分中编译的所有工具都应链接到这些库。 为了完成此操作,需要调整链接器和编译器的 specs 文件。

链接器在 Binutils 的第一遍结束时进行了调整,通过在binutils-build目录中运行以下命令来安装

make -C ld install

从现在开始,所有内容将仅链接到/tools/lib.

注意

中的库。 如果错过了先前关于保留来自第一遍的 Binutils 源代码和构建目录的警告,请忽略上面的命令。 这会导致后续测试程序有很小的机会链接到宿主上的库。 这不是理想的,但不是一个大问题。 当稍后安装 Binutils 的第二遍时,情况会得到纠正。

现在已安装了调整后的链接器,应删除 Binutils 构建和源代码目录。

下一个任务是修改 GCC specs 文件,使其指向新的动态链接器。 一个简单的 sed 脚本将完成此操作

SPECFILE=`gcc --print-file specs` &&
sed 's@ /lib/ld-linux.so.2@ /tools/lib/ld-linux.so.2@g' \
    $SPECFILE > tempspecfile &&
mv -f tempspecfile $SPECFILE &&
unset SPECFILE

建议复制并粘贴上述命令,以确保准确性。 或者,可以手动编辑 specs 文件。 这是通过将每次出现的“/lib/ld-linux.so.2”替换为“/tools/lib/ld-linux.so.2”来完成的

请务必目视检查 specs 文件,以验证是否已进行预期的更改。

重要提示

如果在动态链接器的名称不是ld-linux.so.2的平台上工作,请在上面的命令中将“ld-linux.so.2”替换为平台的动态链接器的名称。 如有必要,请参阅第 5.2 节,“工具链技术说明”

宿主系统中的某些包含文件有可能已进入 GCC 的私有包含目录。 这可能是由于 GCC 的“fixincludes”过程导致的,该过程作为 GCC 构建的一部分运行。 本章稍后将对此进行更详细的说明。 运行以下命令以消除这种可能性

rm -vf /tools/lib/gcc/*/*/include/{pthread.h,bits/sigthread.h}

注意

此时,必须停止并确保新工具链的基本功能(编译和链接)按预期工作。 要执行健全性检查,请运行以下命令

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'

如果一切正常,应该没有错误,并且最后一个命令的输出应该具有以下形式:

[Requesting program interpreter: 
    /tools/lib/ld-linux.so.2]

请注意:/tools/lib显示为动态链接器的前缀。

如果输出未如上所示或根本没有输出,则表示出现问题。调查并重新执行这些步骤,找出问题所在并加以纠正。必须先解决此问题,然后才能继续。首先,再次执行健全性检查,使用 gcc 而不是 cc。如果这可行,则/tools/bin/cc符号链接丢失。请回顾 第 5.4 节,“GCC-3.4.3 - 第一遍” 并安装符号链接。接下来,确保PATH是正确的。可以通过运行 echo $PATH 并验证/tools/bin位于列表的开头。如果PATH是错误的,则可能意味着您未以用户 lfs 身份登录,或者在 第 4.4 节,“设置环境” 中出现了问题。另一种可能是上面的 specs 文件修改出现问题。在这种情况下,重新进行 specs 文件修改,注意复制并粘贴命令

一切就绪后,清理测试文件

rm -v dummy.c a.out

在下一节中构建 TCL 将作为工具链已正确构建的附加检查。如果 TCL 构建失败,则表明 Binutils、GCC 或 Glibc 安装出现问题,而不是 TCL 本身。

5.8. Tcl-8.4.9

Tcl 软件包包含工具命令语言。

预计构建时间: 0.9 SBU
所需磁盘空间: 23.3 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

5.8.1. 安装 Tcl

安装此软件包和接下来的两个软件包(Expect 和 DejaGNU)是为了支持运行 GCC 和 Binutils 的测试套件。为了测试目的而安装三个软件包可能看起来有些过分,但是知道最重要的工具正在正常工作是非常令人放心的,甚至至关重要。即使在本章中未运行测试套件(它们不是强制性的),也需要在 第 6 章 中运行测试套件。

准备 Tcl 以进行编译

cd unix
./configure --prefix=/tools

构建软件包

make

要测试结果,请发出:TZ=UTC make test。已知 Tcl 测试套件在某些尚未完全了解的主机条件下会遇到故障。因此,此处的测试套件故障并不令人意外,并且不被认为是关键的。TZ=UTC 参数将时区设置为协调世界时 (UTC),也称为格林威治标准时间 (GMT),但仅在测试套件运行期间有效。这样可以确保正确执行时钟测试。有关TZ环境变量的详细信息在 第 7 章 中提供。

安装软件包

make install

警告

不要删除tcl8.4.9源目录,因为下一个软件包将需要其内部标头。

设置一个变量,其中包含当前目录的完整路径。下一个软件包 Expect 将使用此变量来查找 Tcl 的标头。

cd ..
export TCLPATH=`pwd`

现在创建一个必要的符号链接

ln -sv tclsh8.4 /tools/bin/tclsh

5.8.2. Tcl 的内容

已安装的程序: tclsh(链接到 tclsh8.4)和 tclsh8.4
已安装的库: libtcl8.4.so

简短说明

tclsh8.4

Tcl 命令 shell

tclsh

到 tclsh8.4 的链接

libtcl8.4.so

Tcl 库

5.9. Expect-5.43.0

Expect 软件包包含一个程序,用于与其他交互式程序进行脚本对话。

大约编译时间: 0.1 SBU
所需磁盘空间: 4.0 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Sed 和 Tcl

5.9.1. 安装 Expect

首先,修复一个可能导致 GCC 测试套件运行期间出现错误失败的错误

patch -Np1 -i ../expect-5.43.0-spawn-1.patch

现在准备 Expect 以进行编译

./configure --prefix=/tools --with-tcl=/tools/lib \
   --with-tclinclude=$TCLPATH --with-x=no

configure 选项的含义

--with-tcl=/tools/lib

这样可以确保 configure 脚本在临时工具位置中找到 Tcl 安装,而不是可能在主机系统上找到现有安装。

--with-tclinclude=$TCLPATH

这明确告诉 Expect 在哪里可以找到 Tcl 的源目录和内部标头。使用此选项可以避免由于 configure 无法自动发现 Tcl 源目录的位置而导致失败的情况。

--with-x=no

这告诉 configure 脚本不要搜索 Tk(Tcl GUI 组件)或 X Window System 库,它们可能都位于主机系统上,但不会存在于临时环境中。

构建软件包

make

要测试结果,请发出:make test。请注意,已知 Expect 测试套件在某些我们无法控制的主机条件下会遇到故障。因此,此处的测试套件故障并不令人意外,并且不被认为是关键的。

安装软件包

make SCRIPTS="" install

make 参数的含义

SCRIPTS=""

这可以防止安装不需要的补充 expect 脚本。

现在删除TCLPATH变量

unset TCLPATH

现在可以删除 Tcl 和 Expect 的源目录。

5.9.2. Expect 的内容

已安装的程序: expect
已安装的库: libexpect-5.43.a

简短说明

expect

根据脚本与其他交互式程序进行通信

libexpect-5.43.a

包含允许将 Expect 用作 Tcl 扩展或直接从 C 或 C++(不使用 Tcl)使用的函数

5.10. DejaGNU-1.4.4

DejaGNU 软件包包含一个用于测试其他程序的框架。

大约编译时间: 0.1 SBU
所需磁盘空间: 6.1 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

5.10.1. 安装 DejaGNU

准备 DejaGNU 以进行编译

./configure --prefix=/tools

构建并安装软件包

make install

5.10.2. DejaGNU 的内容

已安装的程序: runtest

简短说明

runtest

一个包装器脚本,用于定位正确的 expect shell,然后运行 DejaGNU

5.11. GCC-3.4.3 - 第二遍

预计构建时间: 11.0 SBU
所需磁盘空间: 292 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Findutils、Gawk、Gettext、Glibc、Grep、Make、Perl、Sed 和 Texinfo

5.11.1. 重新安装 GCC

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 GCC 时取消设置它们。

现在已安装测试 GCC 和 Binutils 所需的工具 - Tcl、Expect 和 DejaGNU。 现在可以重建 GCC 和 Binutils,将它们与新的 Glibc 链接并正确测试它们(如果在本章中运行测试套件)。 请注意,这些测试套件高度依赖于主机提供的功能正常的 PTY。 PTY 通常通过devpts文件系统实现。 通过执行快速测试,检查主机系统在此方面是否已正确设置

expect -c "spawn ls"

响应可能是

The system has no more ptys.  
Ask your system administrator to create more.

如果收到以上消息,则主机未正确设置其 PTY。 在这种情况下,在解决此问题之前,运行 GCC 和 Binutils 的测试套件毫无意义。 请查阅 LFS 常见问题解答,网址为 http://www.linuxfromscratch.org//lfs/faq.html#no-ptys,以获取有关如何使 PTY 正常工作的更多信息。

首先更正一个已知问题,并进行必要的调整

patch -Np1 -i ../gcc-3.4.3-no_fixincludes-1.patch
patch -Np1 -i ../gcc-3.4.3-specs-2.patch

第一个补丁禁用了 GCC fixincludes 脚本。 前面已经简要提到了这一点,但是这里需要对 fixincludes 过程进行更深入的解释。 在正常情况下,GCC fixincludes 脚本会扫描系统以查找需要修复的头文件。 它可能会发现主机系统上的某些 Glibc 头文件需要修复,并会修复它们,然后将它们放在 GCC 私有 include 目录中。 在 第 6 章 中,安装了较新的 Glibc 之后,将在系统 include 目录之前搜索此私有 include 目录。 这可能会导致 GCC 找到主机系统上已修复的标头,这些标头很可能与用于 LFS 系统的 Glibc 版本不匹配。

第二个补丁更改了 GCC 动态链接器的默认位置(通常是ld-linux.so.2)。 它还删除了/usr/include从 GCC 的 include 搜索路径中删除。 现在进行修补,而不是在安装后调整 specs 文件,可以确保在 GCC 的实际构建过程中使用新的动态链接器。 也就是说,在构建过程中创建的所有最终(和临时)二进制文件都将链接到新的 Glibc。

重要提示

以上补丁对于确保整体构建成功至关重要。 请勿忘记应用它们。

再次创建一个单独的构建目录

mkdir -v ../gcc-build
cd ../gcc-build

在开始构建 GCC 之前,请记住取消设置任何覆盖默认优化标志的环境变量。

现在准备 GCC 以进行编译

../gcc-3.4.3/configure --prefix=/tools \
    --libexecdir=/tools/lib --with-local-prefix=/tools \
    --enable-clocale=gnu --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-languages=c,c++ --disable-libstdcxx-pch

新的 configure 选项的含义

--enable-clocale=gnu

此选项确保在任何情况下都为 C++ 库选择正确的区域设置模型。 如果配置脚本找到已安装的 de_DE 区域设置,它将选择正确的 gnu 区域设置模型。 但是,如果未安装 de_DE 区域设置,则存在构建应用程序二进制接口 (ABI) 不兼容的 C++ 库的风险,因为可能会选择不正确的通用区域设置模型。

--enable-threads=posix

此选项为多线程代码启用 C++ 异常处理。

--enable-__cxa_atexit

此选项允许使用 __cxa_atexit 而不是 atexit 来注册本地静态变量和全局对象的 C++ 析构函数。 对于完全符合标准的析构函数处理,此选项至关重要。 它还会影响 C++ ABI,因此生成的 C++ 共享库和 C++ 程序可以与其他 Linux 发行版互操作。

--enable-languages=c,c++

此选项确保构建 C 和 C++ 编译器。

--disable-libstdcxx-pch

不要为以下项目构建预编译头文件 (PCH):libstdc++。 它占用大量空间,而且我们不需要它。

编译软件包

make

现在不需要使用 bootstrap 目标,因为用于编译此 GCC 的编译器是从与之前使用的 GCC 源代码完全相同的版本构建的。

编译现已完成。 如前所述,运行本章中编译的临时工具的测试套件不是强制性的。 若无论如何都要运行 GCC 测试套件,请使用以下命令:

make -k check

-k 标志用于使测试套件运行到完成,而不是在第一次失败时停止。 GCC 测试套件非常全面,几乎可以保证会产生一些失败。 要接收测试套件结果的摘要,请运行

../gcc-3.4.3/contrib/test_summary

仅对于摘要,请通过 grep -A7 Summ 管道输出。

可以将结果与位于 http://www.linuxfromscratch.org/lfs/build-logs/6.1.1/ 的结果进行比较。

一些意想不到的失败并不总是可以避免的。 GCC 开发人员通常意识到这些问题,但尚未解决。 除非测试结果与上述 URL 的结果差异很大,否则可以安全地继续。

安装软件包

make install

注意

此时强烈建议重复我们在本章前面执行的健全性检查。 请参阅 第 5.7 节“调整工具链”,并重复测试编译。 如果结果错误,最可能的原因是没有正确应用 GCC Specs 补丁。

有关此软件包的详细信息,请参见 第 6.14.2 节,“GCC 的内容。”

5.12. Binutils-2.15.94.0.2.2 - 第二遍

Binutils 软件包包含一个链接器、一个汇编器和其他用于处理目标文件的工具。

预计构建时间: 1.5 SBU
所需磁盘空间: 114 MB
安装依赖于: Bash、Bison、Coreutils、Diffutils、Flex、GCC、Gettext、Glibc、Grep、M4、Make、Perl、Sed 和 Texinfo

5.12.1. 重新安装 Binutils

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,请在构建 Binutils 时取消设置它们。

再次创建一个单独的构建目录

mkdir -v ../binutils-build
cd ../binutils-build

准备编译 Binutils

../binutils-2.15.94.0.2.2/configure --prefix=/tools \
    --disable-nls --enable-shared --with-lib-path=/tools/lib

新的 configure 选项的含义

--with-lib-path=/tools/lib

此命令告诉配置脚本在编译 Binutils 期间指定库搜索路径,从而导致/tools/lib被传递给链接器。 这可以防止链接器搜索主机上的库目录。

编译软件包

make

编译现已完成。 如前所述,运行此章节中临时工具的测试套件不是强制性的。 若无论如何都要运行 Binutils 测试套件,请执行以下命令

make check

安装软件包

make install

现在为下一章中的“重新调整”阶段准备链接器

make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib

警告

不要 删除 Binutils 源代码和构建目录。 下一章中仍需要这些目录的当前状态。

有关此软件包的详细信息,请参见 第 6.13.2 节,“Binutils 的内容。”

5.13. Gawk-3.1.4

Gawk 包包含用于处理文本文件的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 16.4 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

5.13.1. 安装 Gawk

准备编译 Gawk

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.20.2 节“Gawk 的内容”

5.14. Coreutils-5.2.1

Coreutils 包包含用于显示和设置基本系统特征的实用程序。

预计构建时间: 0.9 SBU
所需磁盘空间: 53.3 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl 和 Sed

5.14.1. 安装 Coreutils

准备编译 Coreutils

DEFAULT_POSIX2_VERSION=199209 ./configure --prefix=/tools

在针对 2.3.2 之后版本的 Glibc 编译时,此软件包存在问题。 一些 Coreutils 实用程序(例如 headtailsort)将拒绝其传统语法,这种语法已使用了大约 30 年。 这种旧语法非常普遍,因此应该保持兼容性,直到可以更新使用它的许多位置。 通过设置DEFAULT_POSIX2_VERSION环境变量为 “199209” 即可实现向后兼容。 如果不希望 Coreutils 与传统语法向后兼容,则省略设置DEFAULT_POSIX2_VERSION环境变量。 重要的是要记住,这样做会产生后果,包括需要修补仍然使用旧语法的许多软件包。 因此,建议严格按照给出的说明进行操作。

编译软件包

make

要测试结果,请执行:make RUN_EXPENSIVE_TESTS=yes checkRUN_EXPENSIVE_TESTS=yes 参数告诉测试套件运行几个额外的测试,这些测试在某些平台上被认为相对昂贵(在 CPU 功率和内存使用方面),但在 Linux 上通常没有问题。

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.15.2 节“Coreutils 的内容”

5.15. Bzip2-1.0.3

Bzip2 包包含用于压缩和解压缩文件的程序。 使用 bzip2 压缩文本文件比使用传统的 gzip 压缩百分比更高。

大约编译时间: 0.1 SBU
所需磁盘空间: 3.5 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc 和 Make

5.15.1. 安装 Bzip2

Bzip2 包不包含 configure 脚本。 使用以下命令编译和测试它

make

安装软件包

make PREFIX=/tools install

有关此软件包的详细信息,请参阅 第 6.40.2 节“Bzip2 的内容”

5.16. Gzip-1.3.5

Gzip 包包含用于压缩和解压缩文件的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.2 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

5.16.1. 安装 Gzip

准备编译 Gzip

./configure --prefix=/tools

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.46.2 节“Gzip 的内容”

5.17. Diffutils-2.8.1

Diffutils 包包含显示文件或目录之间差异的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 5.6 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

5.17.1. 安装 Diffutils

准备编译 Diffutils

./configure --prefix=/tools

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.41.2 节“Diffutils 的内容”

5.18. Findutils-4.2.23

Findutils 包包含用于查找文件的程序。 提供这些程序是为了递归搜索目录树并创建、维护和搜索数据库(通常比递归查找更快,但如果数据库没有最近更新则不可靠)。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.9 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

5.18.1. 安装 Findutils

准备编译 Findutils

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.19.2 节“Findutils 的内容”

5.19. Make-3.80

Make 包包含用于编译软件包的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 7.1 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep 和 Sed

5.19.1. 安装 Make

准备编译 Make

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.49.2 节“Make 的内容”

5.20. Grep-2.5.1a

Grep 包包含用于搜索文件的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 4.5 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Make、Sed 和 Texinfo

5.20.1. 安装 Grep

准备编译 Grep

./configure --prefix=/tools \
    --disable-perl-regexp

configure 选项的含义

--disable-perl-regexp

这确保 grep 程序不会链接到主机上可能存在的 Perl 兼容正则表达式 (PCRE) 库,但一旦我们进入 chroot 环境,该库将不可用。

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.44.2 节“Grep 的内容”

5.21. Sed-4.1.4

Sed 包包含一个流编辑器。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.4 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Texinfo

5.21.1. 安装 Sed

准备编译 Sed

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有关此软件包的详细信息,请参阅 第 6.28.2 节“Sed 的内容”

5.22. Gettext-0.14.3

Gettext 包包含用于国际化和本地化的实用程序。 这些实用程序允许使用 NLS(本机语言支持)编译程序,从而使它们能够以用户的母语输出消息。

预计构建时间: 0.5 SBU
所需磁盘空间: 63.0 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

5.22.1. 安装 Gettext

准备编译 Gettext

./configure --prefix=/tools --disable-libasprintf \
    --without-csharp

configure 选项的含义

--disable-libasprintf

此标志告诉 Gettext 不要构建asprintf库。 因为本章和下一章中的任何内容都不需要此库,并且 Gettext 稍后会重新构建,所以排除它以节省时间和空间。

--without-csharp

这确保 Gettext 不会构建对 C# 编译器的支持,该编译器可能存在于主机上,但一旦我们进入 chroot 环境,该编译器将不可用。

编译软件包

make

要测试结果,请执行:make check。 这需要相当长的时间,大约 7 个 SBU。 众所周知,Gettext 测试套件在某些主机条件下会遇到故障,例如,当它在主机上找到 Java 编译器时。 LFS 补丁项目提供了一个实验性补丁,用于禁用 Java,网址为 http://www.linuxfromscratch.org/patches/

安装软件包

make install

该软件包的详细信息位于第 6.30.2 节,“Gettext 的内容”。

5.23. Ncurses-5.4

Ncurses 软件包包含用于终端无关处理字符屏幕的库。

预计编译时间: 0.7 SBU
所需磁盘空间: 27.5 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

5.23.1. 安装 Ncurses

准备编译 Ncurses

./configure --prefix=/tools --with-shared \
    --without-debug --without-ada --enable-overwrite

configure 选项的含义

--without-ada

这确保 Ncurses 不会构建对 Ada 编译器的支持,该编译器可能存在于宿主机上,但在进入 chroot 环境后将不可用。

--enable-overwrite

这告诉 Ncurses 将其头文件安装到/tools/include,而不是/tools/include/ncurses,以确保其他软件包可以成功找到 Ncurses 头文件。

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

该软件包的详细信息位于第 6.21.2 节,“Ncurses 的内容”。

5.24. Patch-2.5.4

Patch 软件包包含一个程序,用于通过应用通常由 diff 程序创建的“patch”文件来修改或创建文件。

大约编译时间: 0.1 SBU
所需磁盘空间: 1.5 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

5.24.1. 安装 Patch

准备编译 Patch

CPPFLAGS=-D_GNU_SOURCE ./configure --prefix=/tools

预处理器标志 -D_GNU_SOURCE 仅在 PowerPC 平台上需要。在其他架构上可以省略。

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

该软件包的详细信息位于第 6.51.2 节,“Patch 的内容”。

5.25. Tar-1.15.1

Tar 软件包包含一个归档程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 12.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

5.25.1. 安装 Tar

准备编译 Tar

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

该软件包的详细信息位于第 6.57.2 节,“Tar 的内容”。

5.26. Texinfo-4.8

Texinfo 软件包包含用于读取、编写和转换 info 页面的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 14.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Ncurses 和 Sed

5.26.1. 安装 Texinfo

准备编译 Texinfo

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

该软件包的详细信息位于第 6.34.2 节,“Texinfo 的内容”。

5.27. Bash-3.0

Bash 软件包包含 Bourne-Again SHell。

预计编译时间: 1.2 SBU
所需磁盘空间: 20.7 MB
安装依赖于: Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make、Ncurses 和 Sed。

5.27.1. 安装 Bash

当针对较新版本的 Glibc 编译时,Bash 存在问题,导致它不适当地挂起。 此补丁修复了该问题

patch -Np1 -i ../bash-3.0-avoid_WCONTINUED-1.patch

准备编译 Bash

./configure --prefix=/tools --without-bash-malloc

configure 选项的含义

--without-bash-malloc

此选项关闭使用 Bash 的内存分配 (malloc) 函数,该函数已知会导致分段错误。 通过关闭此选项,Bash 将使用 Glibc 中的 malloc 函数,该函数更稳定。

编译软件包

make

要测试结果,请执行: make tests

安装软件包

make install

为使用 sh 作为 shell 的程序创建一个链接

ln -vs bash /tools/bin/sh

该软件包的详细信息位于第 6.37.2 节,“Bash 的内容”。

5.28. M4-1.4.3

M4 软件包包含一个宏处理器。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.8 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl 和 Sed

5.28.1. 安装 M4

准备编译 M4

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

该软件包的详细信息位于第 6.24.2 节,“M4 的内容”。

5.29. Bison-2.0

Bison 软件包包含一个解析器生成器。

预计编译时间: 0.6 SBU
所需磁盘空间: 10.0 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、M4、Make 和 Sed

5.29.1. 安装 Bison

准备编译 Bison

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

该软件包的详细信息位于第 6.25.2 节,“Bison 的内容”。

5.30. Flex-2.5.31

Flex 软件包包含一个实用程序,用于生成识别文本中模式的程序。

预计编译时间: 0.6 SBU
所需磁盘空间: 22.5 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、M4、Make 和 Sed

5.30.1. 安装 Flex

Flex 包含几个已知错误。 这些可以使用以下补丁修复

patch -Np1 -i ../flex-2.5.31-debian_fixes-3.patch

GNU autotools 将检测到 Flex 源代码已被之前的补丁修改,并尝试相应地更新手册页。 这在许多系统上不起作用,并且默认页面很好,因此请确保它不会被重新生成

touch doc/flex.1

现在准备编译 Flex

./configure --prefix=/tools

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

该软件包的详细信息位于第 6.29.2 节,“Flex 的内容”。

5.31. Util-linux-2.12q

Util-linux 软件包包含各种实用程序。 其中包括用于处理文件系统、控制台、分区和消息的实用程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.9 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Ncurses、Sed 和 Zlib

5.31.1. 安装 Util-linux

默认情况下,Util-linux 不使用来自以下目录的最新安装的头文件和库/tools。这可以通过更改 configure 脚本来修复

sed -i 's@/usr/include@/tools/include@g' configure

准备编译 Util-linux

./configure

编译一些支持例程

make -C lib

只需要构建此软件包中包含的几个实用程序

make -C mount mount umount
make -C text-utils more

此软件包没有测试套件。

将这些程序复制到临时工具目录

cp mount/{,u}mount text-utils/more /tools/bin

该软件包的详细信息位于第 6.59.3 节,“Util-linux 的内容”。

5.32. Perl-5.8.7

Perl 软件包包含 Practical Extraction and Report Language。

预计编译时间: 0.8 SBU
所需磁盘空间: 81.6 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

5.32.1. 安装 Perl

首先,通过应用以下补丁来调整一些硬编码到 C 库的路径

patch -Np1 -i ../perl-5.8.7-libc-1.patch

准备编译 Perl(确保获得命令的“IO Fcntl POSIX”部分 - 它们都是字母)

./configure.gnu --prefix=/tools -Dstatic_ext='IO Fcntl POSIX'

configure 选项的含义

-Dstatic_ext='IO Fcntl POSIX'

这告诉 Perl 构建安装和测试下一章中的 Coreutils 软件包所需的最小静态扩展集。

只需要构建此软件包中包含的几个实用程序

make perl utilities

虽然 Perl 附带了一个测试套件,但不建议此时运行它。 只构建了 Perl 的一部分,并且现在运行 make test 也会导致构建 Perl 的其余部分,这在此时是不必要的。 如果需要,可以在下一章中运行测试套件。

安装这些工具及其库

cp -v perl pod/pod2man /tools/bin
mkdir -pv /tools/lib/perl5/5.8.7
cp -Rv lib/* /tools/lib/perl5/5.8.7

该软件包的详细信息位于第 6.33.2 节,“Perl 的内容”。

5.33. 剥离

本节中的步骤是可选的,但如果 LFS 分区相当小,则学习可以删除的不必要项目是有益的。 到目前为止构建的可执行文件和库包含大约 130 MB 的不需要的调试符号。 使用以下命令删除这些符号

strip --strip-debug /tools/lib/*
strip --strip-unneeded /tools/{,s}bin/*

上述命令中的最后一个命令将跳过大约 20 个文件,报告它无法识别它们的文件格式。 其中大多数是脚本而不是二进制文件。

请注意不要在库上使用--strip-unneeded。 静态库将被破坏,并且工具链软件包需要重新构建。

为了节省另外 30 MB,请删除文档

rm -rf /tools/{info,man}

现在 LFS 文件系统上将至少有 850 MB 的可用空间,可用于在下一阶段构建和安装 Glibc。 如果您可以构建和安装 Glibc,您也可以构建和安装其余部分。

第三部分. 构建 LFS 系统

第 6 章. 安装基本系统软件

6.1. 介绍

在本章中,我们进入构建站点并开始认真地构建 LFS 系统。 也就是说,我们 chroot 到临时迷你 Linux 系统中,进行一些最后的准备工作,然后开始安装软件包。

此软件的安装非常简单。 尽管在许多情况下,安装说明可以缩短和更通用,但我们选择为每个软件包提供完整的说明,以最大程度地减少出错的可能性。 了解 Linux 系统工作原理的关键是了解每个软件包的用途以及用户(或系统)为什么需要它。 对于每个已安装的软件包,都会给出其内容的摘要,然后是软件包安装的每个程序和库的简明描述。

如果使用本章中提供的编译器优化,请查看 http://www.linuxfromscratch.org/hints/downloads/files/optimization.txt 中的优化提示。 编译器优化可以使程序运行得更快一些,但它们也可能导致编译困难和运行程序时出现问题。 如果软件包在使用优化时拒绝编译,请尝试在不使用优化的情况下编译它,看看是否可以解决问题。 即使软件包在使用优化时确实可以编译,也存在因代码和构建工具之间的复杂交互而导致编译不正确的风险。 使用编译器优化所获得的潜在收益通常会被风险所抵消。 建议 LFS 的首次构建者在不进行自定义优化的情况下进行构建。 后续系统仍将运行非常快且同时稳定。

本章中安装软件包的顺序需要严格遵循,以确保没有程序意外获取引用/tools硬编码到其中的路径。 出于同样的原因,不要并行编译软件包。 并行编译可以节省时间(尤其是在双 CPU 机器上),但它可能会导致程序包含硬编码到/tools的路径,这将导致程序在删除该目录时停止工作。

在安装说明之前,每个安装页面都会提供关于软件包的信息,包括对其所包含内容的简要描述、大致的构建时间、构建过程所需的磁盘空间大小以及成功构建该软件包所需的任何其他软件包。安装说明之后,会列出软件包安装的程序和库(以及对这些程序和库的简要描述)。

为了跟踪哪个软件包安装了特定文件,可以使用软件包管理器。有关不同风格的软件包管理器的概述,请参阅 http://www.linuxfromscratch.org/blfs/view/svn/introduction/important.html。对于专门为 LFS 设计的软件包管理方法,我们推荐 http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt

注意

本书的其余部分将在以 root 用户身份登录的情况下执行,而不再是以 lfs 用户身份登录。 此外,请仔细检查是否设置了$LFS已设置。

6.2. 挂载虚拟内核文件系统

内核导出的各种文件系统用于与内核本身进行通信。 这些文件系统是虚拟的,因为它们不占用磁盘空间。 文件系统的内容驻留在内存中。

首先创建将要挂载文件系统的目录

mkdir -pv $LFS/{proc,sys}

现在挂载文件系统

mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys

请记住,如果由于任何原因停止处理 LFS 系统并稍后重新启动,请务必在进入 chroot 环境之前再次检查这些文件系统是否已挂载。

很快将从 chroot 环境中挂载其他文件系统。 为了使主机保持最新,现在为每个文件系统执行“伪挂载

mount -vft tmpfs tmpfs $LFS/dev
mount -vft tmpfs tmpfs $LFS/dev/shm
mount -vft devpts -o gid=4,mode=620 devpts $LFS/dev/pts

6.3. 进入 Chroot 环境

现在是进入 chroot 环境以开始构建和安装最终 LFS 系统的时候了。 以用户 root 身份,运行以下命令以进入目前仅填充临时工具的领域

chroot "$LFS" /tools/bin/env -i \
    HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
    PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
    /tools/bin/bash --login +h

传递给 env 命令的 -i 选项将清除 chroot 环境的所有变量。 之后,只有HOME, TERM, PS1PATH变量会被重新设置。 TERM=$TERM 结构会将 chroot 中的TERM变量设置为与 chroot 外部相同的值。 vimless 等程序需要此变量才能正常运行。 如果需要其他变量,例如CFLAGS或者CXXFLAGS,这是一个再次设置它们的好地方。

从现在开始,不再需要使用LFS变量了,因为所有工作都将仅限于 LFS 文件系统。 这是因为 Bash shell 被告知$LFS现在是根 (/) 目录。

请注意/tools/bin位于PATH中的最后。 这意味着一旦安装了临时工具的最终版本,它将不再被使用。 当 shell 不“记住”已执行二进制文件的位置时,就会发生这种情况——因此,通过将 +h 选项传递给 bash 来关闭哈希。

重要的是,本章和以下各章中的所有命令都必须在 chroot 环境中运行。 如果由于任何原因离开此环境(例如,重新启动),请记住首先挂载procdevpts文件系统(在上一节中讨论),然后再次进入 chroot,然后再继续安装。

请注意,bash 提示符会显示I have no name!这是正常的,因为/etc/passwd文件尚未创建。

6.4. 更改所有权

目前,/tools目录由用户 lfs 拥有,该用户仅存在于主机系统上。 尽管/tools目录可以在 LFS 系统完成后删除,但可以保留它以构建其他 LFS 系统。 如果/tools目录保持原样,则这些文件由没有相应帐户的用户 ID 拥有。 这是危险的,因为以后创建的用户帐户可能会获得相同的用户 ID,并且会拥有/tools目录及其中的所有文件,从而使这些文件容易受到恶意操作。

为了避免此问题,请稍后在创建/etc/passwd文件时,将 lfs 用户添加到新的 LFS 系统,并注意为其分配与主机系统上相同的用户和组 ID。 或者,通过运行以下命令将/tools目录的内容分配给用户 root

chown -R 0:0 /tools

该命令使用 0:0 而不是 root:root,因为在创建密码文件之前,chown 无法解析名称“root”。 本书假定您运行了此 chown 命令。

6.5. 创建目录

现在是时候在 LFS 文件系统中创建一些结构了。 通过发出以下命令来创建标准目录树

install -dv /{bin,boot,dev,etc/opt,home,lib,mnt}
install -dv /{sbin,srv,usr/local,var,opt}
install -dv /root -m 0750
install -dv /tmp /var/tmp -m 1777
install -dv /media/{floppy,cdrom}
install -dv /usr/{bin,include,lib,sbin,share,src}
ln -sv share/{man,doc,info} /usr
install -dv /usr/share/{doc,info,locale,man}
install -dv /usr/share/{misc,terminfo,zoneinfo}
install -dv /usr/share/man/man{1,2,3,4,5,6,7,8}
install -dv /usr/local/{bin,etc,include,lib,sbin,share,src}
ln -sv share/{man,doc,info} /usr/local
install -dv /usr/local/share/{doc,info,locale,man}
install -dv /usr/local/share/{misc,terminfo,zoneinfo}
install -dv /usr/local/share/man/man{1,2,3,4,5,6,7,8}
install -dv /var/{lock,log,mail,run,spool}
install -dv /var/{opt,cache,lib/{misc,locate},local}
install -dv /opt/{bin,doc,include,info}
install -dv /opt/{lib,man/man{1,2,3,4,5,6,7,8}}

默认情况下,创建目录的权限模式为 755,但这并非对所有目录都适用。 在上面的命令中,进行了两项更改——一项更改为用户 root 的主目录,另一项更改为临时文件的目录。

第一种模式更改确保不仅仅是任何人都可以进入/root目录——与普通用户对其主目录的处理方式相同。 第二种模式更改确保任何用户都可以写入/tmp/var/tmp目录,但不能从中删除另一个用户的文件。 后者被所谓的“粘滞位”禁止,即 1777 位掩码中的最高位 (1)。

6.5.1. FHS 合规性说明

目录树基于文件系统层次结构标准 (FHS)(可在 http://www.pathname.com/fhs/ 中找到)。 除了上面创建的树之外,此标准还规定了/usr/local/games/usr/share/games的存在。 FHS 对/usr/local/share子目录的结构并不精确,因此我们只创建所需的目录。 但是,如果您更喜欢严格遵守 FHS,请随意创建这些目录。

6.6. 创建基本符号链接

某些程序使用硬编码的程序路径,这些程序尚未存在。 为了满足这些程序的需求,请创建一些符号链接,这些符号链接将在本章的过程中,在安装软件后被实际文件替换。

ln -sv /tools/bin/{bash,cat,pwd,stty} /bin
ln -sv /tools/bin/perl /usr/bin
ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib
ln -sv bash /bin/sh

6.7. 创建 passwd、group 和 log 文件

为了使用户 root 能够登录并且名称“root”能够被识别,必须在/etc/passwd/etc/group文件中包含相关条目。

通过运行以下命令来创建/etc/passwd文件

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
EOF

root 的实际密码(此处使用的“x”只是一个占位符)将在稍后设置。

通过运行以下命令来创建/etc/group文件

cat > /etc/group << "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
EOF

创建的组不属于任何标准——这些组的确定部分基于本章中 Udev 配置的要求,部分基于许多现有 Linux 发行版采用的常见约定。 Linux 标准库 (LSB,可在 http://www.linuxbase.org 中找到) 仅建议除了 GID 为 0 的组“root”之外,还应存在 GID 为 1 的组“bin”。 所有其他组名和 GID 都可以由系统管理员自由选择,因为编写良好的程序不依赖于 GID 编号,而是使用组的名称。

要删除“I have no name!”提示,请启动一个新 shell。 由于完整的 Glibc 已在 第 5 章 中安装,并且/etc/passwd/etc/group文件已创建,因此用户名和组名的解析现在可以工作了。

exec /tools/bin/bash --login +h

请注意 +h 指令的使用。 这告诉 bash 不要使用其内部路径哈希。 如果没有此指令,bash 会记住它已执行的二进制文件的路径。 为了确保在安装后立即使用新编译的二进制文件,+h 指令将在本章的剩余时间内使用。

loginagettyinit 程序(以及其他程序)使用许多日志文件来记录诸如谁登录到系统以及何时登录的信息。 但是,如果这些日志文件尚不存在,则这些程序不会写入这些日志文件。 初始化日志文件并赋予它们正确的权限

touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chgrp -v utmp /var/run/utmp /var/log/lastlog
chmod -v 664 /var/run/utmp /var/log/lastlog

/var/run/utmp文件记录当前已登录的用户。/var/log/wtmp文件记录所有登录和注销。/var/log/lastlog文件记录每个用户上次登录的时间。/var/log/btmp文件记录错误的登录尝试。

6.8. 填充 /dev

6.8.1. 创建初始设备节点

当内核启动系统时,它需要存在一些设备节点,特别是consolenull设备。 设备节点将在硬盘上创建,以便在 udev 启动之前可用,并且在单用户模式下启动 Linux 时也可用(因此对console的权限有严格限制)。 通过运行以下命令来创建设备

mknod -m 600 /dev/console c 5 1
mknod -m 666 /dev/null c 1 3

6.8.2. 挂载 tmpfs 并填充 /dev

填充/dev目录的最佳方法是挂载一个虚拟文件系统(例如tmpfs)在/dev目录上,并允许在虚拟文件系统上动态创建设备,因为它们被检测到或访问。 这通常在启动过程中完成。 由于此新系统尚未启动,因此有必要执行 LFS-Bootscripts 软件包本来会执行的操作,即挂载/dev:

mount -nvt tmpfs none /dev

Udev 软件包实际上是在/dev目录中创建设备的原因。 由于它将在过程的稍后阶段安装,因此手动创建完成此系统构建所需的最小设备节点集

mknod -m 622 /dev/console c 5 1
mknod -m 666 /dev/null c 1 3
mknod -m 666 /dev/zero c 1 5
mknod -m 666 /dev/ptmx c 5 2
mknod -m 666 /dev/tty c 5 0
mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9
chown -v root:tty /dev/{console,ptmx,tty}

LFS 需要一些符号链接和目录,这些符号链接和目录是在系统启动期间由 LFS-Bootscripts 软件包创建的。 由于这是一个 chroot 环境而不是启动的环境,因此需要在其中创建这些符号链接和目录

ln -sv /proc/self/fd /dev/fd
ln -sv /proc/self/fd/0 /dev/stdin
ln -sv /proc/self/fd/1 /dev/stdout
ln -sv /proc/self/fd/2 /dev/stderr
ln -sv /proc/kcore /dev/core
mkdir -v /dev/pts
mkdir -v /dev/shm

最后,在新创建的目录上挂载正确的虚拟(内核)文件系统

mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm

上面执行的 mount 命令可能会导致以下警告消息

can't open /etc/fstab: No such file or directory.

This file—/etc/fstab—has not been created yet but is also not required for the file systems to be properly mounted. As such, the warning can be safely ignored.

6.9. Linux-Libc-Headers-2.6.11.2

Linux-Libc-Headers 软件包包含“净化”的内核头文件。

大约编译时间: 0.1 SBU
所需磁盘空间: 26.9 MB
安装依赖于: Coreutils

6.9.1. 安装 Linux-Libc-Headers

多年来,通常的做法是在/usr/include,但在过去几年中,内核开发人员一直坚决反对这样做。 这催生了 Linux-Libc-Headers 项目,该项目旨在维护 Linux 标头的 API 稳定版本。

安装头文件

cp -Rv include/asm-i386 /usr/include/asm
cp -Rv include/linux /usr/include

确保所有标头都归 root 所有

chown -Rv root:root /usr/include/{asm,linux}

确保用户可以读取标头

find /usr/include/{asm,linux} -type d -exec chmod -v 755 {} \;
find /usr/include/{asm,linux} -type f -exec chmod -v 644 {} \;

6.9.2. Linux-Libc-Headers 的内容

已安装的标头: /usr/include/{asm,linux}/*.h

简短描述

/usr/include/{asm,linux}/*.h

Linux API 头文件

6.10. Man-pages-2.01

Man-pages 软件包包含超过 1200 个 man 手册页。

大约编译时间: 0.1 SBU
所需磁盘空间: 25.8 MB
安装依赖于: Bash, Coreutils, 和 Make

6.10.1. 安装 Man-pages

运行以下命令安装 Man-pages

make install

6.10.2. Man-pages 的内容

已安装文件: 各种 man 手册页

简短描述

man pages

描述 C 和 C++ 函数、重要的设备文件以及重要的配置文件

6.11. Glibc-2.3.4

Glibc 软件包包含主要的 C 库。 此库提供用于分配内存、搜索目录、打开和关闭文件、读取和写入文件、字符串处理、模式匹配、算术等的例程。

预计构建时间: 12.3 SBU
所需磁盘空间: 476 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Gettext、Grep、Make、Perl、Sed 和 Texinfo

6.11.1. 安装 Glibc

注意

LFS 之外的一些软件包建议安装 GNU libiconv,以便在不同的编码之间转换数据。该项目的主页 (https://gnu.ac.cn/software/libiconv/) 上说:“该库提供了一个 iconv() 实现,用于那些没有该实现的系统,或者其实现无法从/向 Unicode 转换的系统。” Glibc 提供了一个iconv()实现,并且可以从/向 Unicode 转换,因此 LFS 系统不需要 libiconv。

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 Glibc 时取消设置它们。

Glibc 构建系统是自包含的,即使编译器规范文件和链接器仍然指向/tools,它也可以完美地安装。在安装 Glibc 之前,不能调整规范和链接器,因为 Glibc autoconf 测试会给出错误的结果,并破坏实现干净构建的目标。

linuxthreads tarball 包含 Glibc 安装的线程库的 man 手册页。从 Glibc 源代码目录中解包 tarball

tar -xjvf ../glibc-linuxthreads-2.3.4.tar.bz2

在某些罕见的情况下,当不存在标准搜索目录时,Glibc 可能会出现段错误。以下补丁可以防止这种情况发生

patch -Np1 -i ../glibc-2.3.4-rtld_search_dirs-1.patch

当运行的内核是 2.6.11.x 时,Glibc 有两个测试会失败。问题已确定是测试本身的问题,而不是 libc 或内核的问题。此补丁修复了该问题

patch -Np1 -i ../glibc-2.3.4-fix_test-1.patch

应用以下补丁以修复 Glibc 中的一个错误,该错误可能阻止某些程序(包括 OpenOffice.org)运行

patch -Np1 -i ../glibc-2.3.4-tls_assert-1.patch

Glibc 文档建议在源代码目录之外的专用构建目录中构建 Glibc

mkdir -v ../glibc-build
cd ../glibc-build

准备编译 Glibc

../glibc-2.3.4/configure --prefix=/usr \
    --disable-profile --enable-add-ons \
    --enable-kernel=2.6.0 --libexecdir=/usr/lib/glibc

新的 configure 选项的含义

--libexecdir=/usr/lib/glibc

这将 pt_chown 程序的默认位置从/usr/libexec更改为/usr/lib/glibc.

编译软件包

make

重要提示

在本节中,Glibc 的测试套件被认为是至关重要的。在任何情况下都不要跳过它。

测试结果

make -k check >glibc-check-log 2>&1
grep Error glibc-check-log

Glibc 测试套件高度依赖于主机系统的某些功能,尤其是内核。一般来说,Glibc 测试套件总是期望通过。但是,在某些情况下,一些失败是不可避免的。这是最常见的问题列表

  • 当在 CPU 不是相对较新的真正的 Intel 或正宗的 AMD 的系统上运行时,math 测试有时会失败。某些优化设置也已知是一个因素。

  • 由于主机系统问题,gettext 测试有时会失败。确切原因尚不清楚。

  • 如果您使用 noatime 选项挂载 LFS 分区,则 atime 测试将失败。正如 第 2.4 节“挂载新分区” 中提到的,在构建 LFS 时不要使用 noatime 选项。

  • 在较旧和较慢的硬件上运行时,由于超过了测试超时,某些测试可能会失败。

虽然这是一个无害的消息,但 Glibc 的安装阶段会抱怨缺少/etc/ld.so.conf的无害警告。 使用以下方法阻止此警告

touch /etc/ld.so.conf

安装软件包

make install

上述命令没有安装可以使系统以不同语言响应的语言环境。使用以下命令安装它

make localedata/install-locales

为了节省时间,另一种运行前一个命令(它生成并安装 glibc-2.3.4/localedata/SUPPORTED 文件中列出的每个语言环境)的替代方法是仅安装那些需要和想要的语言环境。这可以通过使用 localedef 命令来实现。有关此命令的信息位于INSTALL文件中。 但是,为了使将来软件包的测试能够通过,特别是 GCC 中的 libstdc++ 测试,需要许多区域设置。 以下说明(代替上面使用的 install-locales 目标)将安装成功运行测试所需的最小区域设置集

mkdir -pv /usr/lib/locale
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i ja_JP -f EUC-JP ja_JP

上述 make localedata/install-locales 命令安装的某些语言环境未被 LFS 和 BLFS 书籍中的某些应用程序正确支持。由于应用程序程序员做出假设导致在这种语言环境中出现各种问题,因此不应在利用多字节字符集(包括 UTF-8)或从右到左书写顺序的语言环境中使用 LFS。需要许多非官方和不稳定的补丁来解决这些问题,并且 LFS 开发人员已决定目前不支持如此复杂的语言环境。这同样适用于 ja_JP 和 fa_IR 语言环境——它们仅用于通过 GCC 和 Gettext 测试,并且 watch 程序(Procps 软件包的一部分)在其中无法正常工作。各种试图规避这些限制的尝试都记录在国际化相关的提示中。

构建 linuxthreads man 手册页,这是关于线程 API 的一个很好的参考(也适用于 NPTL)

make -C ../glibc-2.3.4/linuxthreads/man

安装这些手册页

make -C ../glibc-2.3.4/linuxthreads/man install

6.11.2. 配置 Glibc

/etc/nsswitch.conf需要创建文件,因为虽然 Glibc 在缺少或损坏此文件时提供默认值,但 Glibc 默认值在网络环境中效果不佳。还需要配置时区。

创建一个新文件/etc/nsswitch.conf通过运行以下命令

cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

要确定本地时区,请运行以下脚本

tzselect

在回答了有关位置的一些问题后,脚本将输出时区的名称(例如,EST5EDTCanada/Eastern)。然后创建/etc/localtime通过运行

cp -v --remove-destination /usr/share/zoneinfo/[xxx] \
    /etc/localtime

[xxx] 替换为 tzselect 提供的时区名称(例如,Canada/Eastern)。

cp 选项的含义

--remove-destination

这是强制删除已存在的符号链接所必需的。复制文件而不是使用符号链接的原因是为了涵盖以下情况/usr位于单独的分区上。这在引导到单用户模式时可能很重要。

6.11.3. 配置动态加载器

默认情况下,动态加载器(/lib/ld-linux.so.2)搜索/lib/usr/lib以查找程序运行时所需的动态库。但是,如果目录中存在库,而不是/lib/usr/lib,则需要将这些目录添加到/etc/ld.so.conf文件中,以便动态加载器可以找到它们。通常已知包含其他库的两个目录是/usr/local/lib/opt/lib,因此将这些目录添加到动态加载器的搜索路径中。

创建一个新文件/etc/ld.so.conf通过运行以下命令

cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf

/usr/local/lib
/opt/lib

# End /etc/ld.so.conf
EOF

6.11.4. Glibc 的内容

已安装程序: catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, mtrace, nscd, nscd_nischeck, pcprofiledump, pt_chown, rpcgen, rpcinfo, sln, sprof, tzselect, xtrace, zdump, 和 zic
已安装库: ld.so, libBrokenLocale.[a,so], libSegFault.so, libanl.[a,so], libbsd-compat.a, libc.[a,so], libcrypt.[a,so], libdl.[a,so], libg.a, libieee.a, libm.[a,so], libmcheck.a, libmemusage.so, libnsl.a, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libnss_nis.so, libnss_nisplus.so, libpcprofile.so, libpthread.[a,so], libresolv.[a,so], librpcsvc.a, librt.[a,so], libthread_db.so, 和 libutil.[a,so]

简短描述

catchsegv

可用于在程序以段错误终止时创建堆栈跟踪

gencat

生成消息目录

getconf

显示文件系统特定变量的系统配置值

getent

从管理数据库获取条目

iconv

执行字符集转换

iconvconfig

创建快速加载的 iconv 模块配置文件

ldconfig

配置动态链接器运行时绑定

ldd

报告每个给定程序或共享库需要哪些共享库

lddlibc4

协助 ldd 处理对象文件

locale

告诉编译器启用或禁用将 POSIX 语言环境用于内置操作

localedef

编译语言环境规范

mtrace

读取和解释内存跟踪文件,并以人类可读的格式显示摘要

nscd

一个守护进程,为最常见的名称服务请求提供缓存

nscd_nischeck

检查 NIS+ 查找是否需要安全模式

pcprofiledump

转储 PC 性能分析生成的信息

pt_chown

grantpt 的一个辅助程序,用于设置从属伪终端的所有者、组和访问权限

rpcgen

生成 C 代码以实现远程过程调用 (RPC) 协议

rpcinfo

对 RPC 服务器进行 RPC 调用

sln

一个静态链接的 ln 程序

sprof

读取并显示共享对象性能分析数据

tzselect

询问用户系统位置,并报告相应的时区描述

xtrace

通过打印当前执行的函数来跟踪程序的执行

zdump

时区转储器

zic

时区编译器

ld.so

共享库可执行文件的辅助程序

libBrokenLocale

被程序(如 Mozilla)用来解决损坏的区域设置

libSegFault

段错误信号处理程序

libanl

异步名称查找库

libbsd-compat

提供在 Linux 下运行某些 Berkey 软件分发 (BSD) 程序所需的移植性

libc

主要的 C 库

libcrypt

密码学库

libdl

动态链接接口库

libg

g++ 的运行时库

libieee

电气和电子工程师协会 (IEEE) 浮点库

libm

数学库

libmcheck

包含在启动时运行的代码

libmemusage

memusage 用来帮助收集程序内存使用情况的信息

libnsl

网络服务库

libnss

名称服务交换库,包含用于解析主机名、用户名、组名、别名、服务、协议等的函数

libpcprofile

包含用于跟踪特定源代码行中花费的 CPU 时间量的分析函数

libpthread

POSIX 线程库

libresolv

包含用于创建、发送和解释到 Internet 域名服务器的数据包的函数

librpcsvc

包含提供各种 RPC 服务的函数

librt

包含提供 POSIX.1b 实时扩展指定的大部分接口的函数

libthread_db

包含用于构建多线程程序调试器的有用函数

libutil

包含许多不同 Unix 实用程序中使用的“标准”函数的代码

6.12. 重新调整工具链

现在已经安装了最终的 C 库,是时候再次调整工具链了。 将调整工具链,以便将任何新编译的程序与这些新库链接。 这与第 5 章开始时的“调整”阶段使用的过程相同,但是调整是相反的。 在第 5 章中,链条是从主机的/{,usr/}lib目录引导到新的/tools/lib目录。 现在,该链条将从同一/tools/lib目录引导到 LFS/{,usr/}lib目录。

首先调整链接器。 Binutils 第二次传递的源代码和构建目录被保留用于此目的。 通过在以下位置运行以下命令来安装已调整的链接器binutils-build目录中运行以下命令来安装

make -C ld INSTALL=/tools/bin/install install

注意

如果错过了先前在第 5 章中保留 Binutils 源代码和第二次传递的构建目录的警告,或者如果它们被意外删除或无法访问,请忽略上面的命令。 结果是,下一个软件包 Binutils 将链接到 C 库/tools中,而不是/{,usr/}lib中。 这不是理想的情况,但是,测试表明生成的 Binutils 程序二进制文件应该是相同的。

从现在开始,每个编译的程序都将仅与以下位置的库链接/usr/lib/lib。 需要额外的 INSTALL=/tools/bin/install 选项,因为Makefile文件在第二次传递期间创建,仍然包含对 /usr/bin/install 的引用,该引用尚未安装。 某些主机发行版包含一个ginstall符号链接,该链接在Makefile文件中优先,并且可能导致问题。 上面的命令解决了这个问题。

现在删除 Binutils 源代码和构建目录。

接下来,修改 GCC specs 文件,使其指向新的动态链接器。 一个 perl 命令完成了此操作

perl -pi -e 's@ /tools/lib/ld-linux.so.2@ /lib/ld-linux.so.2@g;' \
    -e 's@\*startfile_prefix_spec:\n@$_/usr/lib/ @g;' \
        `gcc --print-file specs`

最好目视检查 specs 文件,以验证是否实际进行了预期的更改。

重要提示

如果在动态链接器的名称不是ld-linux.so.2,在上面的命令中,用平台动态链接器的名称替换“ld-linux.so.2”。 如果有必要,请回顾5.2 节“工具链技术说明”

注意

此时必须停止并确保已调整的工具链的基本功能(编译和链接)按预期工作。 为此,请执行完整性检查

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /lib'

如果一切正常,则不应有任何错误,并且最后一个命令的输出将是(允许动态链接器名称中的特定于平台的差异)

[Requesting program interpreter: /lib/ld-linux.so.2]

请注意:/lib现在是我们动态链接器的前缀。

如果输出未如上所示或根本未收到,则说明情况严重。 调查并重溯步骤以找出问题所在并加以纠正。 最可能的原因是 specs 文件修改出了问题。 在继续该过程之前,需要解决所有问题。

一切正常后,清除测试文件

rm -v dummy.c a.out

6.13. Binutils-2.15.94.0.2.2

Binutils 软件包包含一个链接器、一个汇编器和其他用于处理目标文件的工具。

预计构建时间: 1.3 SBU
所需磁盘空间: 158 MB
安装依赖于: Bash、Bison、Coreutils、Diffutils、Flex、GCC、Gettext、Glibc、Grep、M4、Make、Perl、Sed 和 Texinfo

6.13.1. 安装 Binutils

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,请在构建 Binutils 时取消设置它们。

验证 PTY 是否在 chroot 环境中正常工作。 通过执行一个简单的测试来检查所有设置是否正确

expect -c "spawn ls"

如果出现以下消息,则 chroot 环境未设置为正确的 PTY 操作

The system has no more ptys.  
Ask your system administrator to create more.

在运行 Binutils 和 GCC 的测试套件之前,需要解决此问题。

Binutils 文档建议在源代码目录之外的专用构建目录中构建 Binutils。

mkdir -v ../binutils-build
cd ../binutils-build

准备编译 Binutils

../binutils-2.15.94.0.2.2/configure --prefix=/usr \
    --enable-shared

编译软件包

make tooldir=/usr

通常,tooldir(最终放置可执行文件的目录)设置为$(exec_prefix)/$(target_alias)。 例如,i686 机器会将此扩展为/usr/i686-pc-linux-gnu。 因为这是一个自定义系统,所以不需要/usr中的特定于目标的目录。$(exec_prefix)/$(target_alias)如果该系统用于交叉编译(例如,在 Intel 机器上编译一个可以在 PowerPC 机器上执行的代码的软件包),则可以使用。

重要提示

本节中 Binutils 的测试套件被认为是至关重要的。 在任何情况下都不要跳过它。

测试结果

make check

安装软件包

make tooldir=/usr install

安装一些软件包需要的libiberty头文件

cp -v ../binutils-2.15.94.0.2.2/include/libiberty.h /usr/include

6.13.2. Binutils 的内容

安装的程序: addr2line、ar、as、c++filt、gprof、ld、nm、objcopy、objdump、ranlib、readelf、size、strings 和 strip
安装的库: libiberty.a, libbfd.[a,so], 和 libopcodes.[a,so]

简短说明

addr2line

将程序地址转换为文件名和行号; 给定一个地址和一个可执行文件的名称,它使用可执行文件中的调试信息来确定与该地址关联的源文件和行号

ar

创建、修改和从存档中提取

as

一个汇编器,将 gcc 的输出汇编成目标文件

c++filt

由链接器使用,以解构 C++ 和 Java 符号,并防止重载函数发生冲突

gprof

显示调用图配置文件数据

ld

一个链接器,将多个目标文件和存档文件组合成一个文件,重新定位其数据并绑定符号引用

nm

列出给定目标文件中出现的符号

objcopy

将一种类型的目标文件转换为另一种类型

objdump

显示有关给定目标文件的信息,并具有控制要显示的特定信息的选项; 显示的信息对于正在编译工具的程序员很有用

ranlib

生成存档内容的索引并将其存储在存档中; 该索引列出了可重定位目标文件存档成员定义的所有符号

readelf

显示有关 ELF 类型二进制文件的信息

size

列出给定目标文件的节大小和总大小

strings

对于每个给定的文件,输出至少具有指定长度(默认为四个)的可打印字符序列; 对于目标文件,默认情况下,它仅打印来自初始化和加载节的字符串,而对于其他类型的文件,它扫描整个文件

strip

从目标文件中丢弃符号

libiberty

包含各种 GNU 程序使用的例程,包括 getoptobstackstrerrorstrtolstrtoul

libbfd

二进制文件描述符库

libopcodes

一个处理操作码的库——处理器指令的“可读文本”版本;它用于构建像 objdump 这样的实用工具。

6.14. GCC-3.4.3

GCC 软件包包含 GNU 编译器集合,其中包括 C 和 C++ 编译器。

大约构建时间: 11.7 SBU
所需磁盘空间: 451 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Findutils、Gawk、Gettext、Glibc、Grep、Make、Perl、Sed 和 Texinfo

6.14.1. GCC的安装

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 GCC 时取消设置它们。

仅应用前一章中也使用的 No-Fixincludes 补丁(而不是 Specs 补丁)

patch -Np1 -i ../gcc-3.4.3-no_fixincludes-1.patch

当与较新版本的 Binutils 结合使用时,GCC 无法编译基本 Linux From Scratch 安装之外的一些软件包(例如,Mozilla 和 kdegraphics)。应用以下补丁来解决此问题

patch -Np1 -i ../gcc-3.4.3-linkonce-1.patch

应用一个 sed 替换,它将抑制安装libiberty.a的版本。libiberty.a而是使用Binutils提供的版本。

sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in

GCC 文档建议在源代码目录之外的专用构建目录中构建 GCC

mkdir -v ../gcc-build
cd ../gcc-build

准备 GCC 进行编译

../gcc-3.4.3/configure --prefix=/usr \
    --libexecdir=/usr/lib --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-clocale=gnu --enable-languages=c,c++

编译软件包

make

重要提示

在本节中,GCC 的测试套件被认为是至关重要的。 无论如何都不要跳过它。

测试结果,但不要因为错误而停止

make -k check

其中一些错误是已知问题,并在上一章中已注明。 第 5.11 节,“GCC-3.4.3 - Pass 2”中的测试套件说明仍然适用。 请务必根据需要参考它们。

安装软件包

make install

一些软件包希望 C 预处理器安装在/lib目录中。 为了支持这些软件包,请创建此符号链接

ln -sv ../usr/bin/cpp /lib

许多软件包使用名称 cc 来调用 C 编译器。 为了满足这些软件包,请创建一个符号链接

ln -sv gcc /usr/bin/cc

注意

此时,强烈建议重复本章前面执行的健全性检查。 回顾第 6.12 节,“重新调整工具链”并重复检查。 如果结果出错,那么最可能的原因是从第 5 章 错误地应用了 GCC Specs 补丁。

6.14.2. GCC 的内容

已安装的程序: c++, cc (链接到 gcc), cpp, g++, gcc, gccbug, 和 gcov
已安装的库: libgcc.a, libgcc_eh.a, libgcc_s.so, libstdc++.[a,so], 和 libsupc++.a

简短描述

cc

C 编译器

cpp

C 预处理器;它被编译器用来展开源文件中的 #include、#define 和类似语句

c++

C++ 编译器

g++

C++ 编译器

gcc

C 编译器

gccbug

一个 shell 脚本,用于帮助创建有用的错误报告

gcov

一个覆盖率测试工具;它用于分析程序,以确定优化将在何处产生最大的效果

libgcc

包含 gcc 的运行时支持

libstdc++

标准 C++ 库

libsupc++

为 C++ 编程语言提供支持例程

6.15. Coreutils-5.2.1

Coreutils 包包含用于显示和设置基本系统特征的实用程序。

预计构建时间: 0.9 SBU
所需磁盘空间: 52.8 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl 和 Sed

6.15.1. Coreutils 的安装

此软件包中的 uname 程序的一个已知问题是 -p 开关始终返回unknown. 以下补丁修复了 Intel 架构的此行为

patch -Np1 -i ../coreutils-5.2.1-uname-2.patch

阻止 Coreutils 安装稍后将由其他软件包安装的二进制文件

patch -Np1 -i ../coreutils-5.2.1-suppress_uptime_kill_su-1.patch

现在准备编译 Coreutils

DEFAULT_POSIX2_VERSION=199209 ./configure --prefix=/usr

编译软件包

make

Coreutils 的测试套件对系统用户和组的存在做了一些假设,这些假设在当前存在的最小环境中无效。 因此,在运行测试之前需要设置其他项目。 如果不运行测试套件,请跳到“安装软件包”。

创建两个虚拟组和一个虚拟用户

echo "dummy1:x:1000:" >> /etc/group
echo "dummy2:x:1001:dummy" >> /etc/group
echo "dummy:x:1000:1000:::/bin/bash" >> /etc/passwd

现在测试套件已准备好运行。 首先,运行旨在以用户 root 身份运行的测试

make NON_ROOT_USERNAME=dummy check-root

然后以 dummy 用户身份运行其余测试

src/su dummy -c "make RUN_EXPENSIVE_TESTS=yes check"

测试完成后,删除虚拟用户和组

sed -i '/dummy/d' /etc/passwd /etc/group

安装软件包

make install

将程序移动到 FHS 指定的位置

mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /bin
mv -v /usr/bin/{false,hostname,ln,ls,mkdir,mknod,mv,pwd,rm} /bin
mv -v /usr/bin/{rmdir,stty,sync,true,uname} /bin
mv -v /usr/bin/chroot /usr/sbin

LFS-Bootscripts 包中的一些脚本依赖于 headsleep。 由于/usr在引导的早期阶段可能不可用,因此这些二进制文件需要位于根分区上

mv -v /usr/bin/{head,sleep} /bin

6.15.2. Coreutils 的内容

已安装的程序: basename, cat, chgrp, chmod, chown, chroot, cksum, comm, cp, csplit, cut, date, dd, df, dir, dircolors, dirname, du, echo, env, expand, expr, factor, false, fmt, fold, groups, head, hostid, hostname, id, install, join, link, ln, logname, ls, md5sum, mkdir, mkfifo, mknod, mv, nice, nl, nohup, od, paste, pathchk, pinky, pr, printenv, printf, ptx, pwd, readlink, rm, rmdir, seq, sha1sum, shred, sleep, sort, split, stat, stty, sum, sync, tac, tail, tee, test, touch, tr, true, tsort, tty, uname, unexpand, uniq, unlink, users, vdir, wc, who, whoami, 和 yes

简短描述

basename

从文件名中删除任何路径和给定的后缀

cat

将文件连接到标准输出

chgrp

更改文件和目录的组所有权

chmod

将每个文件的权限更改为给定的模式;该模式可以是更改的符号表示,也可以是表示新权限的八进制数

chown

更改文件和目录的用户和/或组所有权

chroot

使用指定的目录作为运行命令/目录中运行以下命令来安装

cksum

打印每个指定文件的循环冗余校验 (CRC) 校验和和字节数

comm

比较两个排序的文件,在三列中输出唯一的行和常见的行

cp

复制文件

csplit

将给定的文件分割成几个新文件,根据给定的模式或行号分隔它们,并输出每个新文件的字节数

cut

打印行的一部分,根据给定的字段或位置选择部分

date

以给定的格式显示当前时间,或设置系统日期

dd

使用给定的块大小和计数复制文件,同时可以选择对其执行转换

df

报告所有已挂载文件系统上可用的(和已使用的)磁盘空间量,或者仅报告保存所选文件的文件系统上的磁盘空间量

dir

列出每个给定目录的内容(与 ls 命令相同)

dircolors

输出用于设置LS_COLOR环境变量的命令,以更改 ls 使用的配色方案

dirname

从文件名中删除非目录后缀

du

报告当前目录、每个给定目录(包括所有子目录)或每个给定文件使用的磁盘空间量

echo

显示给定的字符串

env

在修改的环境中运行命令

expand

将制表符转换为空格

expr

计算表达式

factor

打印所有指定整数的质因数

false

什么也不做,不成功;它总是以指示失败的状态代码退出

fmt

重新格式化给定文件中的段落

fold

包装给定文件中的行

groups

报告用户的组成员身份

head

打印每个给定文件的前十行(或给定行数)

hostid

报告主机的数字标识符(十六进制)

hostname

报告或设置主机的名称

id

报告当前用户或指定用户的有效用户 ID、组 ID 和组成员身份

install

复制文件,同时设置其权限模式,如果可能,还设置其所有者和组

join

连接来自两个单独的文件的具有相同连接字段的行

link

使用给定的名称创建到文件的硬链接

ln

在文件之间建立硬链接或软(符号)链接

logname

报告当前用户的登录名

ls

列出每个给定目录的内容

md5sum

报告或检查 Message Digest 5 (MD5) 校验和

mkdir

创建具有给定名称的目录

mkfifo

创建先进先出 (FIFO) 队列,在 UNIX 术语中是“命名管道”,具有给定的名称

mknod

创建具有给定名称的设备节点;设备节点是字符特殊文件、块特殊文件或 FIFO

mv

移动或重命名文件或目录

nice

以修改后的调度优先级运行程序

nl

给给定文件的行编号

nohup

运行不受挂起影响的命令,将其输出重定向到日志文件

od

以八进制和其他格式转储文件

paste

合并给定文件,将按顺序对应的行并排放置,以制表符分隔

pathchk

检查文件名是否有效或可移植

pinky

是一个轻量级的 finger 客户端;它报告有关给定用户的一些信息

pr

对文件进行分页和分栏以进行打印

printenv

打印环境变量

printf

根据给定的格式打印给定的参数,很像 C 语言的 printf 函数

ptx

从给定文件的内容生成置换索引,每个关键字都在其上下文中

pwd

报告当前工作目录的名称

readlink

报告给定符号链接的值

rm

删除文件或目录

rmdir

如果目录为空,则删除目录

seq

打印给定范围内且具有给定增量的数字序列

sha1sum

打印或检查 160 位安全哈希算法 1 (SHA1) 校验和

shred

用复杂的模式重复覆盖给定的文件,使其难以恢复数据

sleep

暂停给定的时间量

sort

对给定文件中的行进行排序

split

按大小或行数将给定文件拆分为多个部分

stat

显示文件或文件系统状态

stty

设置或报告终端线路设置

sum

打印每个给定文件的校验和和块计数

sync

刷新文件系统缓冲区;它强制将更改的块写入磁盘并更新超级块

tac

反向连接给定的文件

tail

打印每个给定文件的最后十行(或给定行数)

tee

从标准输入读取,同时写入标准输出和给定文件

test

比较值并检查文件类型

touch

更改文件时间戳,将给定文件的访问时间和修改时间设置为当前时间;不存在的文件将被创建,长度为零

tr

从标准输入转换、压缩和删除给定的字符

true

什么也不做,成功;它总是以指示成功的状态代码退出

tsort

执行拓扑排序;它根据给定文件中的部分排序写入一个完全有序的列表

tty

报告连接到标准输入的终端的文件名

uname

报告系统信息

unexpand

将空格转换为制表符

uniq

丢弃除一个之外的连续相同行

unlink

删除给定的文件

users

报告当前登录用户的名称

vdir

ls -l 相同

wc

报告每个给定文件的行数、字数和字节数,以及给出多个文件时的总行数

who

报告谁已登录

whoami

报告与当前有效用户 ID 关联的用户名

yes

重复输出“y”或给定的字符串直到被终止

6.16. Zlib-1.2.3

Zlib 软件包包含一些程序使用的压缩和解压缩例程。

大约编译时间: 0.1 SBU
所需磁盘空间: 3.1 MB
安装依赖于: Binutils、Coreutils、GCC、Glibc、Make 和 Sed

6.16.1. Zlib 的安装

注意

如果CFLAGS在环境中指定,则已知 Zlib 会不正确地构建其共享库。 如果使用指定的CFLAGS变量,请务必将 -fPIC 指令添加到CFLAGS在下面的 configure 命令期间使用该变量,然后在之后将其删除。

准备 Zlib 进行编译

./configure --prefix=/usr --shared --libdir=/lib

编译软件包

make

要测试结果,请执行:make check

安装共享库

make install

之前的命令安装了一个.so文件在/lib中。我们将删除它并将其重新链接到/usr/lib:

rm -v /lib/libz.so
ln -sfv ../../lib/libz.so.1.2.3 /usr/lib/libz.so

构建静态库

make clean
./configure --prefix=/usr
make

要再次测试结果,请发出: make check

安装静态库

make install

修复静态库的权限

chmod -v 644 /usr/lib/libz.a

6.16.2. Zlib 的内容

已安装的库: libz.[a,so]

简短描述

libz

包含一些程序使用的压缩和解压缩函数

6.17. Mktemp-1.5

Mktemp 软件包包含用于在 shell 脚本中创建安全临时文件的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 436 KB
安装依赖于: Coreutils、Make 和 Patch

6.17.1. Mktemp 的安装

许多脚本仍然使用已弃用的 tempfile 程序,该程序具有与 mktemp 类似的功能。 补丁 Mktemp 以包含 tempfile 包装器

patch -Np1 -i ../mktemp-1.5-add_tempfile-2.patch

准备 Mktemp 进行编译

./configure --prefix=/usr --with-libc

configure 选项的含义

--with-libc

这会导致 mktemp 程序使用系统 C 库中的 mkstempmkdtemp 函数。

编译软件包

make

安装软件包

make install
make install-tempfile

6.17.2. Mktemp 的内容

已安装的程序: mktemp 和 tempfile

简短描述

mktemp

以安全的方式创建临时文件;它在脚本中使用

tempfile

以比 mktemp 安全性较低的方式创建临时文件; 它为向后兼容性而安装

6.18. Iana-Etc-1.04

Iana-Etc软件包提供网络服务和协议的数据。

大约编译时间: 0.1 SBU
所需磁盘空间: 1.9 MB
安装依赖: Make

6.18.1. Iana-Etc 的安装

以下命令将 IANA 提供的原始数据转换为以下文件的正确格式:/etc/protocols/etc/services数据文件

make

安装软件包

make install

6.18.2. Iana-Etc 的内容

已安装文件: /etc/protocols 和 /etc/services

简短描述

/etc/protocols

描述 TCP/IP 子系统可用的各种 DARPA Internet 协议

/etc/services

提供 Internet 服务的友好文本名称与其底层分配的端口号和协议类型之间的映射

6.19. Findutils-4.2.23

Findutils 包包含用于查找文件的程序。 提供这些程序是为了递归搜索目录树并创建、维护和搜索数据库(通常比递归查找更快,但如果数据库没有最近更新则不可靠)。

大约编译时间: 0.1 SBU
所需磁盘空间: 9.4 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

6.19.1. Findutils 的安装

准备编译 Findutils

./configure --prefix=/usr --libexecdir=/usr/lib/locate \
    --localstatedir=/var/lib/locate

configure 选项的含义

--localstatedir

此选项将 locate 数据库的位置更改为/var/lib/locate,这是符合 FHS 标准的。

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.19.2. Findutils 的内容

已安装程序: bigram, code, find, frcode, locate, updatedb, 和 xargs

简短描述

bigram

以前用于生成 locate 数据库

code

以前用于生成 locate 数据库;它是 frcode 的祖先。

find

在给定的目录树中搜索符合指定标准的文件

frcode

updatedb 调用以压缩文件名列表;它使用前压缩,将数据库大小缩小四到五倍。

locate

搜索文件名数据库并报告包含给定字符串或匹配给定模式的名称

updatedb

更新 locate 数据库;它扫描整个文件系统(包括当前挂载的其他文件系统,除非另有说明),并将找到的每个文件名放入数据库中

xargs

可用于将给定的命令应用于文件列表

6.20. Gawk-3.1.4

Gawk 包包含用于处理文本文件的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 16.4 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

6.20.1. Gawk 的安装

准备编译 Gawk

./configure --prefix=/usr --libexecdir=/usr/lib

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.20.2. Gawk 的内容

已安装程序: awk(链接到 gawk),gawk,gawk-3.1.4,grcat,igawk,pgawk,pgawk-3.1.4 和 pwcat

简短描述

awk

gawk 的链接

gawk

一个用于操作文本文件的程序;它是 awk 的 GNU 实现

gawk-3.1.4

gawk 的硬链接

grcat

转储组数据库/etc/group

igawk

使 gawk 能够包含文件

pgawk

gawk 的分析版本

pgawk-3.1.4

pgawk 的硬链接

pwcat

转储密码数据库/etc/passwd

6.21. Ncurses-5.4

Ncurses 软件包包含用于终端无关处理字符屏幕的库。

预计编译时间: 0.6 SBU
所需磁盘空间: 18.6 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

6.21.1. Ncurses 的安装

准备编译 Ncurses

./configure --prefix=/usr --with-shared --without-debug

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

赋予 Ncurses 库执行权限

chmod -v 755 /usr/lib/*.5.4

修复一个不应执行的库

chmod -v 644 /usr/lib/libncurses++.a

将库移动到/lib目录,它们应该驻留在其中

mv -v /usr/lib/libncurses.so.5* /lib

由于库已移动,因此一些符号链接指向不存在的文件。重新创建这些符号链接

ln -sfv ../../lib/libncurses.so.5 /usr/lib/libncurses.so
ln -sfv libncurses.so /usr/lib/libcurses.so

6.21.2. Ncurses 的内容

已安装程序: captoinfo(链接到 tic),clear,infocmp,infotocap(链接到 tic),reset(链接到 tset),tack,tic,toe,tput 和 tset
已安装库: libcurses.[a,so](链接到 libncurses.[a,so]),libform.[a,so],libmenu.[a,so],libncurses++.a,libncurses.[a,so] 和 libpanel.[a,so]

简短描述

captoinfo

将 termcap 描述转换为 terminfo 描述

clear

如果可能,清除屏幕

infocmp

比较或打印 terminfo 描述

infotocap

将 terminfo 描述转换为 termcap 描述

reset

将终端重新初始化为其默认值

tack

terminfo 操作检查器;它主要用于测试 terminfo 数据库中条目的准确性

tic

terminfo 条目描述编译器,它将 terminfo 文件从源格式转换为 ncurses 库例程所需的二进制格式。terminfo 文件包含有关特定终端的功能的信息

toe

列出所有可用的终端类型,并给出每个终端类型的主名称和描述

tput

使终端相关功能的可用值提供给 shell;它也可以用于重置或初始化终端或报告其长名称

tset

可用于初始化终端

libcurses

是链接到libncurses

libncurses

包含以多种复杂方式在终端屏幕上显示文本的函数;这些函数的一个很好的例子是在内核的 make menuconfig 期间显示的菜单

libform

包含实现表单的函数

libmenu

包含实现菜单的函数

libpanel

包含实现面板的函数

6.22. Readline-5.0

Readline 软件包是一组库,提供命令行编辑和历史记录功能。

大致构建时间: 0.11 SBU
所需磁盘空间: 9.1 MB
安装依赖: Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make、Ncurses 和 Sed

6.22.1. Readline 的安装

以下补丁包括针对 Readline 有时仅在一行上显示 33 个字符然后换到下一行的问题的修复程序。它还包括 Readline 作者推荐的其他修复程序。

patch -Np1 -i ../readline-5.0-fixes-1.patch

准备 Readline 进行编译

./configure --prefix=/usr --libdir=/lib

编译软件包

make SHLIB_XLDFLAGS=-lncurses

make 选项的含义

SHLIB_XLDFLAGS=-lncurses

此选项强制 Readline 链接到libncurses库。

安装软件包

make install

赋予 Readline 的动态库更适当的权限

chmod -v 755 /lib/lib{readline,history}.so*

现在将静态库移动到更适当的位置

mv -v /lib/lib{readline,history}.a /usr/lib

接下来,删除.so中的文件/lib并将它们重新链接到/usr/lib.

rm -v /lib/lib{readline,history}.so
ln -sfv ../../lib/libreadline.so.5 /usr/lib/libreadline.so
ln -sfv ../../lib/libhistory.so.5 /usr/lib/libhistory.so

6.22.2. Readline 的内容

已安装库: libhistory.[a,so] 和 libreadline.[a,so]

简短描述

libhistory

为调用历史记录行提供一致的用户界面

libreadline

有助于需要在命令行界面上提供命令行的离散程序之间用户界面的一致性

6.23. Vim-6.3

Vim 软件包包含一个强大的文本编辑器。

大致构建时间: 0.4 SBU
所需磁盘空间: 38.0 MB
安装依赖: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Ncurses 和 Sed

Vim 的替代方案

如果您更喜欢另一个编辑器,例如 Emacs、Joe 或 Nano,请参阅 http://www.linuxfromscratch.org/blfs/view/svn/postlfs/editors.html 以获取建议的安装说明。

6.23.1. Vim 的安装

首先,解压缩vim-6.3.tar.bz2和(可选)vim-6.3-lang.tar.gz存档到同一目录中。 然后,将vimrc配置文件的默认位置更改为/etc:

echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h

Vim 有两个已知的安全漏洞,这些漏洞已在上游解决。 以下补丁修复了这些问题

patch -Np1 -i ../vim-6.3-security_fix-2.patch

现在准备 Vim 进行编译

./configure --prefix=/usr --enable-multibyte

configure 选项的含义

--enable-multibyte

此可选但强烈推荐的开关启用对编辑多字节字符编码文件的支持。 如果使用具有多字节字符集的语言环境,则需要此选项。 此开关也有助于能够编辑最初在 Linux 发行版(如 Fedora Core)中创建的文本文件,这些文件使用 UTF-8 作为默认字符集。

编译软件包

make

要测试结果,请执行: make test。 但是,此测试套件会将大量二进制数据输出到屏幕,这可能会导致当前终端的设置出现问题。 这可以通过将输出重定向到日志文件来解决。

安装软件包

make install

许多用户习惯于使用 vi 而不是 vim。 为了允许在用户习惯性地输入 vi 时执行 vim,请创建一个符号链接

ln -sv vim /usr/bin/vi

如果要在 LFS 系统上安装 X Window 系统,则可能需要在安装 X 后重新编译 Vim。 Vim 附带一个 GUI 版本的编辑器,该编辑器需要安装 X 和一些额外的库。 有关此过程的更多信息,请参阅 Vim 文档和 BLFS 书籍中的 Vim 安装页面,网址为 http://www.linuxfromscratch.org/blfs/view/svn/postlfs/editors.html#postlfs-editors-vim

6.23.2. 配置 Vim

默认情况下,vim 运行在 vi 不兼容模式。对于过去使用过其他编辑器的用户来说,这可能是全新的。“nocompatible”设置包含在下方,用于突出显示正在使用新行为。它也提醒那些想要更改为“compatible”模式的人,这应该是配置文件中的第一个设置。这是必要的,因为它会更改其他设置,并且重写必须在此设置之后进行。 通过运行以下命令创建一个默认的 vim 配置文件

cat > /etc/vimrc << "EOF"
" Begin /etc/vimrc

set nocompatible
set backspace=2
syntax on
if (&term == "iterm") || (&term == "putty")
  set background=dark
endif

" End /etc/vimrc
EOF

set nocompatible 使 vim 的行为方式比 vi 兼容模式更有用(默认)。删除“no”以保留旧的 vi 行为。 set backspace=2 允许在换行符、自动缩进和插入开头处使用退格键。 syntax on 启用 vim 的语法高亮显示。最后,包含 set background=darkif 语句纠正了 vim 对某些终端模拟器背景颜色的猜测。这为在这些程序的黑色背景上使用高亮显示提供了更好的配色方案。

可以通过运行以下命令获取其他可用选项的文档

vim -c ':options'

6.23.3. Vim 的内容

已安装程序: efm_filter.pl, efm_perl.pl, ex (链接到 vim), less.sh, mve.awk, pltags.pl, ref, rview (链接到 vim), rvim (链接到 vim), shtags.pl, tcltags, vi (链接到 vim), view (链接到 vim), vim, vim132, vim2html.pl, vimdiff (链接到 vim), vimm, vimspell.sh, vimtutor, 和 xxd

简短描述

efm_filter.pl

用于创建可由 vim 读取的错误文件的过滤器

efm_perl.pl

重新格式化 Perl 解释器的错误消息,以便与 vim 的“quickfix”模式一起使用

ex

以 ex 模式启动 vim

less.sh

一个使用 less.vim 启动 vim 的脚本

mve.awk

处理 vim 错误

pltags.pl

为 Perl 代码创建一个标签文件,供 vim 使用

ref

检查参数的拼写

rview

view 的受限版本;不能启动任何 shell 命令,并且 view 不能被暂停

rvim

vim 的受限版本;不能启动任何 shell 命令,并且 vim 不能被暂停

shtags.pl

为 Perl 脚本生成一个标签文件

tcltags

为 TCL 代码生成一个标签文件

view

以只读模式启动 vim

vi

是编辑器

vim

是编辑器

vim132

以 132 列模式启动终端中的 vim

vim2html.pl

将 Vim 文档转换为超文本标记语言 (HTML)

vimdiff

使用 vim 编辑文件的两个或三个版本并显示差异

vimm

在远程终端上启用 DEC 定位器输入模型

vimspell.sh

拼写检查文件并生成在 vim 中突出显示所需的语法语句。 此脚本需要旧的 Unix spell 命令,LFS 和 BLFS 均未提供该命令

vimtutor

教授 vim 的基本键和命令

xxd

创建给定文件的十六进制转储;它也可以反向操作,因此可以用于二进制修补

6.24. M4-1.4.3

M4 软件包包含一个宏处理器。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.8 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Perl 和 Sed

6.24.1. M4 的安装

准备编译 M4

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.24.2. M4 的内容

已安装程序: m4

简短描述

m4

复制给定文件,同时展开它们包含的宏。 这些宏可以是内置的,也可以是用户定义的,并且可以接受任意数量的参数。 除了执行宏扩展之外,m4 还具有用于包含命名文件、运行 Unix 命令、执行整数运算、操作文本、递归等的内置函数。 m4 程序既可以用作编译器的前端,也可以用作独立的宏处理器。

6.25. Bison-2.0

Bison 软件包包含一个解析器生成器。

预计编译时间: 0.6 SBU
所需磁盘空间: 9.9 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、M4、Make 和 Sed

6.25.1. Bison 的安装

准备编译 Bison

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.25.2. Bison 的内容

已安装程序: bison 和 yacc
已安装库: liby.a

简短描述

bison

从一系列规则生成一个程序,用于分析文本文件的结构; Bison 是 Yacc(Yet Another Compiler Compiler)的替代品

yacc

bison 的包装器,适用于仍然调用 yacc 而不是 bison 的程序;它使用 -y 选项调用 bison

liby.a

包含与 Yacc 兼容的 yyerrormain 函数实现的 Yacc 库; 该库通常不是很有用,但 POSIX 要求它

6.26. Less-382

Less 软件包包含一个文本文件查看器。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.3 MB
安装依赖: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Ncurses 和 Sed

6.26.1. Less 的安装

准备 Less 以进行编译

./configure --prefix=/usr --bindir=/bin --sysconfdir=/etc

configure 选项的含义

--sysconfdir=/etc

此选项告诉软件包创建的程序在/etc中查找配置文件。

编译软件包

make

安装软件包

make install

6.26.2. Less 的内容

已安装程序: less, lessecho, 和 lesskey

简短描述

less

文件查看器或分页器; 它显示给定文件的内容,允许用户滚动、查找字符串和跳转到标记

lessecho

需要在 Unix 系统上扩展文件名中的元字符,例如 *?

lesskey

用于指定 less 的按键绑定

6.27. Groff-1.19.1

Groff 软件包包含用于处理和格式化文本的程序。

预计构建时间: 0.5 SBU
所需磁盘空间: 38.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

6.27.1. Groff 的安装

Groff 期望环境变量PAGE包含默认纸张尺寸。 对于美国的用户,PAGE=letter 是合适的。 在其他地方,PAGE=A4 可能更合适。

准备 Groff 以进行编译

PAGE=[paper_size] ./configure --prefix=/usr

编译软件包

make

安装软件包

make install

某些文档程序(例如 xman)如果没有以下符号链接,将无法正常工作

ln -sv soelim /usr/bin/zsoelim
ln -sv eqn /usr/bin/geqn
ln -sv tbl /usr/bin/gtbl

6.27.2. Groff 的内容

已安装程序: addftinfo, afmtodit, eqn, eqn2graph, geqn (链接到 eqn), grn, grodvi, groff, groffer, grog, grolbp, grolj4, grops, grotty, gtbl (链接到 tbl), hpftodit, indxbib, lkbib, lookbib, mmroff, neqn, nroff, pfbtops, pic, pic2graph, post-grohtml, pre-grohtml, refer, soelim, tbl, tfmtodit, troff, 和 zsoelim (链接到 soelim)

简短描述

addftinfo

读取 troff 字体文件并添加一些额外的字体度量信息,这些信息由 groff 系统使用

afmtodit

创建一个字体文件,用于 groffgrops

eqn

将嵌入在 troff 输入文件中的方程描述编译为 troff 可以理解的命令

eqn2graph

将 troff EQN(方程)转换为裁剪后的图像

geqn

eqn 的链接

grn

gremlin 文件的 groff 预处理器

grodvi

一个为 groff 生成 TeX dvi 格式的驱动程序

groff

groff 文档格式化系统的前端; 通常,它运行 troff 程序和一个适用于所选设备的后处理器

groffer

在 X 和 tty 终端上显示 groff 文件和 man 页面

grog

读取文件并猜测打印文件所需的 groff 选项,例如 -e-man-me-mm-ms-p-s-t,并报告包含这些选项的 groff 命令。

grolbp

是用于 Canon CAPSL 打印机(LBP-4 和 LBP-8 系列激光打印机)的 groff 驱动程序。

grolj4

是一个 groff 驱动程序,可生成适用于 HP LaserJet 4 打印机的 PCL5 格式的输出。

grops

将 GNU troff 的输出转换为 PostScript。

grotty

将 GNU troff 的输出转换为适合类似打字机设备的格式。

gtbl

tbl 的链接。

hpftodit

从 HP 标记的字体度量文件为 groff -Tlj4 创建字体文件。

indxbib

为书目数据库创建一个反向索引,并使用指定的文件,用于 refer, lookbib, 和 lkbib

lkbib

在书目数据库中搜索包含指定关键字的引用,并报告找到的任何引用。

lookbib

在标准错误上打印提示(除非标准输入不是终端),从标准输入读取包含一组关键字的行,在指定文件的书目数据库中搜索包含这些关键字的引用,在标准输出上打印找到的任何引用,并重复此过程,直到输入结束。

mmroff

groff 的一个简单预处理器。

neqn

格式化等式,以便用于美国信息交换标准代码(ASCII)输出。

nroff

是一个脚本,它使用 groff 模拟 nroff 命令。

pfbtops

转换 PostScript 字体,.pfb格式转换为 ASCII。

pic

将嵌入在 troff 或 TeX 输入文件中的图片描述编译成 TeX 或 troff 可理解的命令。

pic2graph

将 PIC 图转换为裁剪后的图像。

post-grohtml

将 GNU troff 的输出转换为 HTML。

pre-grohtml

将 GNU troff 的输出转换为 HTML。

refer

将文件的内容复制到标准输出,但 .[.] 之间的行被解释为引用,而 .R1.R2 之间的行被解释为处理引用的命令。

soelim

读取文件,并将形式为 .so file 的行替换为提到的 file 的内容。

tbl

将嵌入在 troff 输入文件中的表格描述编译成 troff 可理解的命令。

tfmtodit

groff -Tdvi 创建字体文件。

troff

与 Unix troff 高度兼容;通常应使用 groff 命令调用它,该命令还将以适当的顺序和适当的选项运行预处理器和后处理器。

zsoelim

soelim 的链接。

6.28. Sed-4.1.4

Sed 包包含一个流编辑器。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.4 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Texinfo

6.28.1. Sed 的安装

默认情况下,Sed 将其 HTML 文档安装在/usr/share/doc. 将其更改为/usr/share/doc/sed-4.1.4,方法是应用以下 sed

sed -i 's@/doc@&/sed-4.1.4@' doc/Makefile.in

准备编译 Sed

./configure --prefix=/usr --bindir=/bin

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.28.2. Sed 的内容

已安装的程序: sed

简短描述

sed

以单次传递方式过滤和转换文本文件。

6.29. Flex-2.5.31

Flex 软件包包含一个实用程序,用于生成识别文本中模式的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 22.5 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、M4、Make 和 Sed

6.29.1. Flex 的安装

Flex 包含几个已知错误。使用以下补丁修复这些错误。

patch -Np1 -i ../flex-2.5.31-debian_fixes-3.patch

GNU autotools 检测到 Flex 源代码已被先前的补丁修改,并尝试相应地更新 man 页面。这在许多系统上无法正常工作,并且默认页面很好,因此请确保它不会被重新生成。

touch doc/flex.1

准备编译 Flex。

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

有一些软件包希望在lex库中找到它。/usr/lib. 创建一个符号链接来解决这个问题。

ln -sv libfl.a /usr/lib/libl.a

一些程序尚不知道 flex,并尝试运行其前身 lex。为了支持这些程序,创建一个名为lex的包装脚本,该脚本调用flexlex 仿真模式下。

cat > /usr/bin/lex << "EOF"
#!/bin/sh
# Begin /usr/bin/lex

exec /usr/bin/flex -l "$@"

# End /usr/bin/lex
EOF
chmod -v 755 /usr/bin/lex

6.29.2. Flex 的内容

已安装的程序: flex 和 lex
已安装的库: libfl.a

简短描述

flex

一种用于生成识别文本中模式的程序的工具;它允许灵活地指定查找模式的规则,从而无需开发专门的程序。

lex

一个在 lex 仿真模式下运行 flex 的脚本。

libfl.a

flex

6.30. Gettext-0.14.3

Gettext 包包含用于国际化和本地化的实用程序。 这些实用程序允许使用 NLS(本机语言支持)编译程序,从而使它们能够以用户的母语输出消息。

预计编译时间: 1.2 SBU
所需的磁盘空间: 65.1 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

6.30.1. Gettext 的安装

准备编译 Gettext

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check。这需要很长时间,大约 7 个 SBUs。

安装软件包

make install

6.30.2. Gettext 的内容

已安装的程序: autopoint、config.charset、config.rpath、envsubst、gettext、gettextize、hostname、msgattrib、msgcat、msgcmp、msgcomm、msgconv、msgen、msgexec、msgfilter、msgfmt、msggrep、msginit、msgmerge、msgunfmt、msguniq、ngettext 和 xgettext
已安装的库: libasprintf.[a,so]、libgettextlib.so、libgettextpo.[a,so] 和 libgettextsrc.so

简短描述

autopoint

将标准的 Gettext 基础架构文件复制到源包中。

config.charset

输出字符编码别名的系统相关表。

config.rpath

输出一组系统相关的变量,描述如何设置可执行文件中共享库的运行时搜索路径。

envsubst

替换 shell 格式字符串中的环境变量。

gettext

通过在消息目录中查找翻译,将自然语言消息翻译成用户的语言。

gettextize

将所有标准的 Gettext 文件复制到软件包的给定顶级目录中,以开始对其进行国际化。

hostname

以各种形式显示网络主机名。

msgattrib

根据翻译目录的消息的属性过滤消息,并操作这些属性。

msgcat

连接并合并给定的.po文件。

msgcmp

比较两个.po文件,以检查两者是否包含同一组 msgid 字符串。

msgcomm

查找给定文件中共有的消息。.po文件。

msgconv

将翻译目录转换为不同的字符编码。

msgen

创建英语翻译目录。

msgexec

将命令应用于翻译目录的所有翻译。

msgfilter

将过滤器应用于翻译目录的所有翻译。

msgfmt

从翻译目录生成二进制消息目录。

msggrep

提取翻译目录中与给定模式匹配或属于某些给定源文件的所有消息。

msginit

创建一个新的.po文件,使用来自用户环境的值初始化元信息。

msgmerge

将两个原始翻译合并到一个文件中。

msgunfmt

将二进制消息目录反编译为原始翻译文本。

msguniq

统一翻译目录中的重复翻译。

ngettext

显示文本消息的本地语言翻译,该消息的语法形式取决于一个数字。

xgettext

从给定的源文件中提取可翻译的消息行,以生成第一个翻译模板。

libasprintf

定义了 autosprintf 类,该类使 C 格式化输出例程可在 C++ 程序中使用,以便与 <string> 字符串和 <iostream> 流一起使用。

libgettextlib

一个私有库,包含各种 Gettext 程序使用的通用例程;这些例程不打算供通用使用。

libgettextpo

用于编写处理以下内容的专用程序.po.po 文件;当 Gettext 附带的标准应用程序(例如 msgcommmsgcmpmsgattribmsgen)不足以满足需求时,将使用此库。

libgettextsrc

一个私有库,包含各种 Gettext 程序使用的通用例程;这些例程不打算供通用使用。

6.31. Inetutils-1.4.2

Inetutils 包包含用于基本网络的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.7 MB
安装依赖: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Ncurses 和 Sed

6.31.1. 安装 Inetutils

Inetutils 在 Linux 2.6 内核系列中存在问题。通过应用以下补丁来解决这些问题

patch -Np1 -i ../inetutils-1.4.2-kernel_headers-1.patch

Inetutils 附带的所有程序都不会被安装。但是,Inetutils 构建系统将坚持安装所有 man 手册。以下补丁将纠正这种情况

patch -Np1 -i ../inetutils-1.4.2-no_server_man_pages-1.patch

准备编译 Inetutils

./configure --prefix=/usr --libexecdir=/usr/sbin \
    --sysconfdir=/etc --localstatedir=/var \
    --disable-logger --disable-syslogd \
    --disable-whois --disable-servers

configure 选项的含义

--disable-logger

此选项阻止 Inetutils 安装 logger 程序,该程序由脚本用于将消息传递到系统日志守护程序。不要安装它,因为 Util-linux 稍后会安装一个更好的版本。

--disable-syslogd

此选项阻止 Inetutils 安装系统日志守护程序,该守护程序与 Sysklogd 包一起安装。

--disable-whois

此选项禁用 Inetutils whois 客户端的构建,该客户端已过时。BLFS 书中有关于更好的 whois 客户端的说明。

--disable-servers

这将禁用作为 Inetutils 包一部分包含的各种网络服务器的安装。这些服务器被认为不适合基本的 LFS 系统。有些服务器本质上是不安全的,并且仅在受信任的网络上才被认为是安全的。有关更多信息,请访问 http://www.linuxfromscratch.org/blfs/view/svn/basicnet/inetutils.html。请注意,许多这些服务器都有更好的替代品。

编译软件包

make

安装软件包

make install

ping 程序移动到其符合 FHS 的位置

mv -v /usr/bin/ping /bin

6.31.2. Inetutils 的内容

已安装的程序: ftp、ping、rcp、rlogin、rsh、talk、telnet 和 tftp

简短描述

ftp

是文件传输协议程序

ping

发送回显请求数据包并报告回复所需的时间

rcp

执行远程文件复制

rlogin

执行远程登录

rsh

运行远程 shell

talk

用于与另一个用户聊天

telnet

TELNET 协议的接口

tftp

一个简单的文件传输程序

6.32. IPRoute2-2.6.11-050330

IPRoute2 包包含用于基于基本和高级 IPV4 的网络的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 4.3 MB
安装依赖于: GCC、Glibc、Make、Linux-Headers 和 Sed

6.32.1. 安装 IPRoute2

此软件包中包含的 arpd 二进制文件依赖于 Berkeley DB。因为 arpd 不是基本 Linux 系统上的一个非常常见的需求,请通过应用下面的 sed 命令来删除对 Berkeley DB 的依赖。如果需要 arpd 二进制文件,可以在 BLFS Book 中找到编译 Berkeley DB 的说明,网址为 http://www.linuxfromscratch.org/blfs/view/svn/server/databases.html#db

sed -i '/^TARGETS/s@arpd@@g' misc/Makefile

准备编译 IPRoute2

./configure 

编译软件包

make SBINDIR=/sbin

make 选项的含义

SBINDIR=/sbin

这确保了 IPRoute2 二进制文件将被安装到/sbin。 这是根据 FHS 的正确位置,因为 LFS-Bootscripts 包使用了一些 IPRoute2 二进制文件。

安装软件包

make SBINDIR=/sbin install

6.32.2. IPRoute2 的内容

已安装的程序: ctstat(链接到 lnstat)、ifcfg、ifstat、ip、lnstat、nstat、routef、routel、rtacct、rtmon、rtpr、rtstat(链接到 lnstat)、ss 和 tc。

简短描述

ctstat

连接状态实用程序

ifcfg

ip 命令的 shell 脚本包装器

ifstat

显示接口统计信息,包括每个接口发送和接收的数据包数量

ip

主可执行文件。它有几个不同的功能

ip link [device] 允许用户查看设备的状态并进行更改

ip addr 允许用户查看地址及其属性,添加新地址和删除旧地址

ip neighbor 允许用户查看邻居绑定及其属性,添加新邻居条目和删除旧邻居条目

ip rule 允许用户查看路由策略并更改它们

ip route 允许用户查看路由表并更改路由表规则

ip tunnel 允许用户查看 IP 隧道及其属性,并更改它们

ip maddr 允许用户查看多播地址及其属性,并更改它们

ip mroute 允许用户设置、更改或删除多播路由

ip monitor 允许用户持续监控设备、地址和路由的状态

lnstat

提供 Linux 网络统计信息。 它是旧的 rtstat 程序的通用且功能更完整的替代品

nstat

显示网络统计信息

routef

ip route 的一个组件。 这是用于刷新路由表的

routel

ip route 的一个组件。 这是用于列出路由表的

rtacct

显示内容/proc/net/rt_acct

rtmon

路由监控实用程序

rtpr

ip -o 的输出转换回可读形式

rtstat

路由状态实用程序

ss

类似于 netstat 命令;显示活动连接

tc

流量控制可执行文件;这是用于服务质量 (QOS) 和服务类别 (COS) 实现的

tc qdisc 允许用户设置排队规则

tc class 允许用户根据排队规则调度设置类

tc estimator 允许用户估计网络流量进入网络

tc filter 允许用户设置 QOS/COS 数据包过滤

tc policy 允许用户设置 QOS/COS 策略

6.33. Perl-5.8.7

Perl 软件包包含 Practical Extraction and Report Language。

大致构建时间: 4.1 SBU
所需磁盘空间: 140 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make 和 Sed

6.33.1. 安装 Perl

为了完全控制 Perl 的设置方式,请运行交互式 Configure 脚本并手动选择构建此软件包的方式。 如果它自动检测到的默认值是合适的,请使用以下命令准备编译 Perl

./configure.gnu --prefix=/usr -Dpager="/bin/less -isR"

configure 选项的含义

-Dpager="/bin/less -isR"

这纠正了 perldoc 调用 less 程序的方式中的错误。

编译软件包

make

要运行测试套件,首先创建一个基本的/etc/hosts文件,几个测试需要该文件来解析网络名称 localhost

echo "127.0.0.1 localhost $(hostname)" > /etc/hosts

现在运行测试,如果需要

make test

安装软件包

make install

6.33.2. Perl 的内容

已安装的程序: a2p、c2ph、dprofpp、enc2xs、find2perl、h2ph、h2xs、libnetcfg、perl、perl5.8.7(链接到 perl)、perlbug、perlcc、perldoc、perlivp、piconv、pl2pm、pod2html、pod2latex、pod2man、pod2text、pod2usage、podchecker、podselect、psed(链接到 s2p)、pstruct(链接到 c2ph)、s2p、splain 和 xsubpp
已安装的库: 数百个,无法在此处全部列出

简短描述

a2p

将 awk 翻译为 Perl

c2ph

转储从 cc -g -S 生成的 C 结构体

dprofpp

显示 Perl 性能剖析数据

en2cxs

从 Unicode 字符映射或 Tcl 编码文件构建 Encode 模块的 Perl 扩展

find2perl

find 命令翻译为 Perl

h2ph

转换.hC 头文件为.phPerl 头文件

h2xs

转换.hC 头文件到 Perl 扩展

libnetcfg

可用于配置libnet

perl

将 C、sedawksh 的一些最佳特性组合成一种多功能的语言

perl5.8.7

一个指向 perl 的硬链接

perlbug

用于生成关于 Perl 或其附带模块的错误报告,并将它们通过邮件发送

perlcc

从 Perl 程序生成可执行文件

perldoc

显示嵌入在 Perl 安装树或 Perl 脚本中的 pod 格式的文档片段

perlivp

Perl 安装验证程序;它可用于验证 Perl 及其库是否已正确安装

piconv

字符编码转换器 iconv 的 Perl 版本

pl2pm

用于转换 Perl4 的粗糙工具.pl文件为 Perl5.pm模块

pod2html

将文件从 pod 格式转换为 HTML 格式

pod2latex

将文件从 pod 格式转换为 LaTeX 格式

pod2man

将 pod 数据转换为格式化的 *roff 输入

pod2text

将 pod 数据转换为格式化的 ASCII 文本

pod2usage

从文件中的嵌入式 pod 文档打印使用信息

podchecker

检查 pod 格式文档文件的语法

podselect

显示 pod 文档的选定部分

psed

流编辑器 sed 的 Perl 版本

pstruct

转储从 cc -g -S stabs 生成的 C 结构体

s2p

sed 脚本翻译为 Perl

splain

用于强制 Perl 中的详细警告诊断

xsubpp

将 Perl XS 代码转换为 C 代码

6.34. Texinfo-4.8

Texinfo 软件包包含用于读取、编写和转换 info 页面的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 14.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Ncurses 和 Sed

6.34.1. Texinfo 的安装

Texinfo 允许本地用户通过对临时文件的符号链接攻击覆盖任意文件。应用以下补丁来修复此问题

patch -Np1 -i ../texinfo-4.8-tempfile_fix-1.patch

准备编译 Texinfo

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

(可选)安装属于 TeX 安装的组件

make TEXMF=/usr/share/texmf install-tex

make 参数的含义

TEXMF=/usr/share/texmf

TEXMFmakefile 变量保存 TeX 树根目录的位置,例如,如果稍后将安装 TeX 包。

Info 文档系统使用纯文本文件来保存其菜单条目列表。 该文件位于/usr/share/info/dir。 遗憾的是,由于各种软件包的 Makefile 中偶尔出现的问题,它有时会与系统上安装的 info 页面失去同步。 如果/usr/share/info/dir文件需要重新创建,以下可选命令将完成该任务

cd /usr/share/info
rm dir
for f in *
do install-info $f dir 2>/dev/null
done

6.34.2. Texinfo 的内容

已安装的程序: info、infokey、install-info、makeinfo、texi2dvi、texi2pdf 和 texindex

简短描述

info

用于读取 info 页面,该页面类似于 man 页面,但通常比仅仅解释所有可用的命令行选项更深入。 例如,比较 man bisoninfo bison

infokey

将包含 Info 自定义项的源文件编译为二进制格式

install-info

用于安装 info 页面; 它更新 info 索引文件中的条目

makeinfo

将给定的 Texinfo 源文档转换为 info 页面、纯文本或 HTML

texi2dvi

用于将给定的 Texinfo 文档格式化为可打印的设备无关文件

texi2pdf

用于将给定的 Texinfo 文档格式化为可移植文档格式 (PDF) 文件

texindex

用于对 Texinfo 索引文件进行排序

6.35. Autoconf-2.59

Autoconf 包包含用于生成可以自动配置源代码的 shell 脚本的程序。

预计构建时间: 0.5 SBU
所需磁盘空间: 8.5 MB
安装依赖于: Bash、Coreutils、Diffutils、Grep、M4、Make、Perl 和 Sed

6.35.1. Autoconf 的安装

准备 Autoconf 进行编译

./configure --prefix=/usr

编译软件包

make

要测试结果,请发出: make check。这需要很长时间,大约 2 个 SBU。

安装软件包

make install

6.35.2. Autoconf 的内容

已安装的程序: autoconf、autoheader、autom4te、autoreconf、autoscan、autoupdate 和 ifnames

简短描述

autoconf

生成 shell 脚本,这些脚本自动配置软件源代码包以适应多种 Unix 类系统。 它生成的配置脚本是独立的 - 运行它们不需要 autoconf 程序。

autoheader

一种用于创建 C #define 语句的模板文件的工具,供 configure 使用

autom4te

M4 宏处理器的包装器

autoreconf

自动按正确的顺序运行 autoconfautoheaderaclocalautomakegettextizelibtoolize,以在更改 autoconfautomake 模板文件时节省时间

autoscan

帮助创建configure.in软件程序的文件; 它检查目录树中的源文件,搜索常见的可移植性问题,并创建一个configure.scan文件,该文件用作程序的初步configure.in文件

autoupdate

修改一个configure.in文件,该文件仍然通过旧名称调用 autoconf 宏来使用当前的宏名称

ifnames

在编写configure.in软件程序的 files 时提供帮助; 它打印程序在 C 预处理器条件中使用的标识符。 如果一个程序已经设置好了一些可移植性,那么这个程序可以帮助确定 configure 需要检查什么。 它还可以填补 autoscan 生成的configure.in文件中的空白

6.36. Automake-1.9.5

Automake 包包含用于生成与 Autoconf 一起使用的 Makefile 的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 8.8 MB
安装依赖于: Autoconf、Bash、Coreutils、Diffutils、Grep、M4、Make、Perl 和 Sed

6.36.1. Automake 的安装

准备 Automake 进行编译

./configure --prefix=/usr

编译软件包

make

要测试结果,请发出: make check。这需要很长时间,大约 5 个 SBU。

安装软件包

make install

6.36.2. Automake 的内容

已安装的程序: acinstall、aclocal、aclocal-1.9.5、automake、automake-1.9.5、compile、config.guess、config.sub、depcomp、elisp-comp、install-sh、mdate-sh、missing、mkinstalldirs、py-compile、symlink-tree 和 ylwrap

简短描述

acinstall

一个安装 aclocal 样式的 M4 文件的脚本

aclocal

生成aclocal.m4基于以下内容的文件configure.in文件。

aclocal-1.9.5

指向 aclocal 的硬链接

automake

一种用于自动生成Makefile.in来自Makefile.am文件的工具。 要创建程序的所有Makefile.in文件,请在顶层目录中运行此程序。 通过扫描configure.in文件,它会自动找到每个合适的Makefile.am文件并生成相应的Makefile.in文件

automake-1.9.5

指向 automake 的硬链接

compile

编译器的包装器

config.guess

一个尝试猜测给定构建、主机或目标体系结构的规范三元组的脚本

config.sub

一个配置验证子例程脚本

depcomp

用于编译程序的脚本,除了所需的输出外,还会生成依赖关系信息

elisp-comp

字节编译 Emacs Lisp 代码

install-sh

用于安装程序、脚本或数据文件的脚本

mdate-sh

用于打印文件或目录的修改时间的脚本

missing

在安装期间充当缺失的 GNU 程序的通用存根的脚本

mkinstalldirs

用于创建目录树的脚本

py-compile

编译 Python 程序

symlink-tree

用于创建目录树的符号链接树的脚本

ylwrap

lexyacc 的包装器

6.37. Bash-3.0

Bash 软件包包含 Bourne-Again SHell。

预计编译时间: 1.2 SBU
所需磁盘空间: 20.6 MB
安装依赖于: Binutils、Coreutils、Diffutils、Gawk、GCC、Glibc、Grep、Make、Ncurses 和 Sed。

6.37.1. Bash 的安装

如果您下载了 Bash 文档 tarball 并且希望安装 HTML 文档,请执行以下命令

tar -xvf ../bash-doc-3.0.tar.gz &&
sed -i "s|htmldir = @htmldir@|htmldir = /usr/share/doc/bash-3.0|" \
    Makefile.in

以下补丁修复了各种问题,包括 Bash 有时只在一行上显示 33 个字符,然后换到下一行的问题

patch -Np1 -i ../bash-3.0-fixes-3.patch

当针对较新版本的 Glibc 编译时,Bash 也会出现问题。 以下补丁解决了这个问题

patch -Np1 -i ../bash-3.0-avoid_WCONTINUED-1.patch

准备编译 Bash

./configure --prefix=/usr --bindir=/bin \
    --without-bash-malloc --with-installed-readline

configure 选项的含义

--with-installed-readline

此选项告诉 Bash 使用readline系统上已安装的库,而不是使用自己的 readline 版本。

编译软件包

make

要测试结果,请执行: make tests

安装软件包

make install

运行新编译的 bash 程序(替换当前正在执行的程序)

exec /bin/bash --login +h

注意

使用的参数使 bash 进程成为交互式登录 shell,并继续禁用哈希,以便在新程序可用时找到它们。

6.37.2. Bash 的内容

已安装的程序: bash、bashbug 和 sh(链接到 bash)

简短描述

bash

一种广泛使用的命令解释器;它在执行给定的命令行之前对该命令行执行多种类型的扩展和替换,从而使该解释器成为强大的工具

bashbug

一个 shell 脚本,用于帮助用户编写和邮寄关于 bash 的标准格式的错误报告

sh

指向 bash 程序的符号链接;当作为 sh 调用时,bash 尝试尽可能地模拟 sh 的历史版本的启动行为,同时符合 POSIX 标准

6.38. File-4.13

File 包包含一个用于确定给定文件或文件类型的实用程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 6.2 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Sed 和 Zlib

6.38.1. File 的安装

准备 File 以进行编译

./configure --prefix=/usr

编译软件包

make

安装软件包

make install

6.38.2. File 的内容

已安装的程序: file
已安装的库: libmagic.[a,so]

简短描述

file

尝试对每个给定的文件进行分类;它通过执行几个测试来做到这一点 - 文件系统测试、魔数测试和语言测试

libmagic

包含魔数识别的例程,由 file 程序使用

6.39. Libtool-1.5.14

Libtool 包包含 GNU 通用库支持脚本。它将使用共享库的复杂性包装在一个一致的、可移植的接口中。

预计构建时间: 1.5 SBU
所需磁盘空间: 19.7 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

6.39.1. Libtool 的安装

准备 Libtool 以进行编译

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.39.2. Libtool 的内容

已安装的程序: libtool 和 libtoolize
已安装的库: libltdl.[a,so]

简短描述

libtool

提供通用的库构建支持服务

libtoolize

提供了一种向软件包添加 libtool 支持的标准方法

libltdl

隐藏了 dlopening 库的各种困难

6.40. Bzip2-1.0.3

Bzip2 包包含用于压缩和解压缩文件的程序。 使用 bzip2 压缩文本文件比使用传统的 gzip 压缩百分比更高。

大约编译时间: 0.1 SBU
所需磁盘空间: 3.9 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc 和 Make

6.40.1. Bzip2 的安装

应用一个补丁来安装这个软件包的文档

patch -Np1 -i ../bzip2-1.0.3-install_docs-1.patch

bzgrep 命令不会转义传递给它的文件名中的 '|' 和 '&'。 这允许使用运行 bzgrep 的用户的权限执行任意命令。 应用以下补丁来解决这个问题

patch -Np1 -i ../bzip2-1.0.3-bzgrep_security-1.patch

准备 Bzip2 以进行编译,使用

make -f Makefile-libbz2_so
make clean

-f 标志将导致 Bzip2 使用不同的Makefile文件来构建,在本例中为Makefile-libbz2_so文件,它创建一个动态libbz2.so库并将 Bzip2 实用程序链接到它。

编译并测试软件包

make

如果重新安装 Bzip2,请先执行 rm -vf /usr/bin/bz*,否则以下 make install 将会失败。

安装程序

make install

将共享的 bzip2 二进制文件安装到/bin目录中,创建一些必要的符号链接,并进行清理

cp -v bzip2-shared /bin/bzip2
cp -av libbz2.so* /lib
ln -sv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.so
rm -v /usr/bin/{bunzip2,bzcat,bzip2}
ln -sv bzip2 /bin/bunzip2
ln -sv bzip2 /bin/bzcat

6.40.2. Bzip2 的内容

已安装的程序: bunzip2(链接到 bzip2)、bzcat(链接到 bzip2)、bzcmp、bzdiff、bzegrep、bzfgrep、bzgrep、bzip2、bzip2recover、bzless 和 bzmore
已安装的库: libbz2.[a,so]

简短描述

bunzip2

解压缩 bzipped 文件

bzcat

解压缩到标准输出

bzcmp

在 bzipped 文件上运行 cmp

bzdiff

在 bzipped 文件上运行 diff

bzgrep

在 bzipped 文件上运行 grep

bzegrep

在 bzipped 文件上运行 egrep

bzfgrep

在 bzipped 文件上运行 fgrep

bzip2

使用 Burrows-Wheeler 块排序文本压缩算法和 Huffman 编码压缩文件;压缩率优于使用 “Lempel-Ziv” 算法(如 gzip)的更传统的压缩器所获得的压缩率

bzip2recover

尝试从损坏的 bzipped 文件中恢复数据

bzless

在 bzipped 文件上运行 less

bzmore

在 bzipped 文件上运行 more

libbz2*

使用 Burrows-Wheeler 算法实现无损块排序数据压缩的库

6.41. Diffutils-2.8.1

Diffutils 包包含显示文件或目录之间差异的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 5.6 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

6.41.1. Diffutils 的安装

准备编译 Diffutils

./configure --prefix=/usr

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

6.41.2. Diffutils 的内容

已安装的程序: cmp、diff、diff3 和 sdiff

简短描述

cmp

比较两个文件并报告它们是否不同或在哪些字节中不同

diff

比较两个文件或目录并报告文件中哪些行不同

diff3

逐行比较三个文件

sdiff

合并两个文件并交互式地输出结果

6.42. Kbd-1.12

Kbd 包包含键盘表文件和键盘实用程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 11.8 MB
安装取决于: Bash、Binutils、Bison、Coreutils、Diffutils、Flex、GCC、Gettext、Glibc、Grep、Gzip、M4、Make 和 Sed

6.42.1. Kbd 的安装

准备 Kbd 以进行编译

./configure

编译软件包

make

安装软件包

make install

6.42.2. Kbd 的内容

已安装的程序: chvt、deallocvt、dumpkeys、fgconsole、getkeycodes、getunimap、kbd_mode、kbdrate、loadkeys、loadunimap、mapscrn、openvt、psfaddtable(链接到 psfxtable)、psfgettable(链接到 psfxtable)、psfstriptable(链接到 psfxtable)、psfxtable、resizecons、setfont、setkeycodes、setleds、setlogcons、setmetamode、setvesablank、showconsolefont、showkey、unicode_start 和 unicode_stop

简短描述

chvt

更改前台虚拟终端

deallocvt

释放未使用的虚拟终端

dumpkeys

转储键盘翻译表

fgconsole

打印当前激活虚拟终端的编号

getkeycodes

打印内核扫描码到键码的映射表

getunimap

打印当前使用的 Unicode 到字体的映射表

kbd_mode

报告或设置键盘模式

kbdrate

设置键盘重复率和延迟率

loadkeys

加载键盘转换表

loadunimap

加载内核 Unicode 到字体的映射表

mapscrn

一个过时的程序,用于将用户定义的输出字符映射表加载到控制台驱动程序中;现在这由 setfont 完成

openvt

在新虚拟终端 (VT) 上启动程序

psfaddtable

一个指向 psfxtable 的链接

psfgettable

一个指向 psfxtable 的链接

psfstriptable

一个指向 psfxtable 的链接

psfxtable

处理控制台字体的 Unicode 字符表

resizecons

更改内核关于控制台大小的认知

setfont

更改控制台上的增强图形适配器 (EGA) 和视频图形阵列 (VGA) 字体

setkeycodes

加载内核扫描码到键码的映射表条目;如果键盘上有不寻常的按键,这将非常有用

setleds

设置键盘标志和发光二极管 (LED)

setlogcons

将内核消息发送到控制台

setmetamode

定义键盘 Meta 键处理

setvesablank

允许用户调整内置硬件屏幕保护程序(空白屏幕)

showconsolefont

显示当前 EGA/VGA 控制台屏幕字体

showkey

报告键盘上按键的扫描码、键码和 ASCII 码

unicode_start

将键盘和控制台置于 UNICODE 模式。 永远不要在 LFS 上使用它,因为应用程序未配置为支持 UNICODE。

unicode_stop

将键盘和控制台从 UNICODE 模式恢复

6.43. E2fsprogs-1.37

E2fsprogs 软件包包含用于处理ext2文件系统的实用程序。 它还支持ext3日志文件系统。

预计编译时间: 0.6 SBU
所需磁盘空间: 40.0 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、Gawk、GCC、Gettext、Glibc、Grep、Make、Sed 和 Texinfo

6.43.1. 安装 E2fsprogs

修复 E2fsprogs 测试套件中的编译错误

sed -i -e 's/-DTEST/$(ALL_CFLAGS) &/' lib/e2p/Makefile.in

建议在源树的子目录中构建 E2fsprogs

mkdir -v build
cd build

准备 E2fsprogs 进行编译

../configure --prefix=/usr --with-root-prefix="" \
    --enable-elf-shlibs --disable-evms

configure 选项的含义

--with-root-prefix=""

某些程序(例如 e2fsck 程序)被认为是必要的程序。 例如,当/usr未挂载时,这些程序仍然需要可用。 它们属于像这样的目录/lib/sbin。 如果未将此选项传递给 E2fsprogs 的 configure,则这些程序将安装到/usr目录中。

--enable-elf-shlibs

这会创建此软件包中的某些程序使用的共享库。

--disable-evms

这会禁用 Enterprise Volume Management System (EVMS) 插件的构建。 此插件不是最新的 EVMS 内部接口,并且 EVMS 不作为基本 LFS 系统的一部分安装,因此不需要该插件。 有关 EVMS 的更多信息,请访问 EVMS 网站 http://evms.sourceforge.net/

编译软件包

make

要测试结果,请执行:make check

安装二进制文件和文档

make install

安装共享库

make install-libs

6.43.2. E2fsprogs 的内容

已安装的程序: badblocks、blkid、chattr、compile_et、debugfs、dumpe2fs、e2fsck、e2image、e2label、findfs、fsck、fsck.ext2、fsck.ext3、logsave、lsattr、mk_cmds、mke2fs、mkfs.ext2、mkfs.ext3、mklost+found、resize2fs、tune2fs 和 uuidgen。
已安装的库: libblkid.[a,so]、libcom_err.[a,so]、libe2p.[a,so]、libext2fs.[a,so]、libss.[a,so] 和 libuuid.[a,so]

简短描述

badblocks

搜索设备(通常是磁盘分区)中的坏块

blkid

一个命令行实用程序,用于定位和打印块设备属性

chattr

更改文件系统上的文件属性ext2更改文件系统,这是ext3文件系统的日志版本ext2文件系统

compile_et

一个错误表编译器;它将错误代码名称和消息的表转换为 C 源文件,适合与com_err

debugfs

一个文件系统调试器;它可用于检查和更改ext2文件系统的状态

dumpe2fs

打印给定设备上文件系统的超级块和块组信息

e2fsck

用于检查,并可选择修复ext2文件系统和ext3文件系统

e2image

用于将关键ext2文件系统数据保存到文件

e2label

显示或更改给定设备上文件系统的文件系统标签ext2文件系统

findfs

按标签或通用唯一标识符 (UUID) 查找文件系统

fsck

用于检查,并可选择修复文件系统

fsck.ext2

默认检查ext2文件系统

fsck.ext3

默认检查ext3文件系统

logsave

将命令的输出保存在日志文件中

lsattr

列出第二个扩展文件系统上文件的属性

mk_cmds

将命令名称和帮助消息的表转换为 C 源文件,适合与libss子系统库

mke2fs

在给定设备上创建 ext2 或 ext3 文件系统

mkfs.ext2

默认情况下创建ext2文件系统

mkfs.ext3

默认情况下创建ext3文件系统

mklost+found

用于在lost+found目录上创建ext2文件系统;它为此目录预先分配磁盘块,以减轻 e2fsck 的任务

resize2fs

可用于扩大或缩小ext2文件系统的状态

tune2fs

调整ext2文件系统的状态

uuidgen

创建新的 UUID。 可以合理地认为,每个新的 UUID 在过去和未来,在本地系统和其他系统上创建的所有 UUID 中都是唯一的

libblkid

包含设备识别和令牌提取的例程

libcom_err

通用错误显示例程

libe2p

dumpe2fschattrlsattr 使用

libext2fs

包含例程以使用户级程序能够操作ext2文件系统的状态

libss

debugfs 使用

libuuid

包含用于为可能超出本地系统访问的对象生成唯一标识符的例程

6.44. Grep-2.5.1a

Grep 包包含用于搜索文件的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 4.5 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Make、Sed 和 Texinfo

6.44.1. 安装 Grep

准备编译 Grep

./configure --prefix=/usr --bindir=/bin

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.44.2. Grep 的内容

已安装的程序: egrep (链接到 grep)、fgrep (链接到 grep) 和 grep

简短描述

egrep

打印与扩展正则表达式匹配的行

fgrep

打印与固定字符串列表匹配的行

grep

打印与基本正则表达式匹配的行

6.45. GRUB-0.96

GRUB 软件包包含 GRand Unified Bootloader。

预计构建时间: 0.2 SBU
所需磁盘空间: 10.0 MB
安装依赖: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make、Ncurses 和 Sed

6.45.1. 安装 GRUB

已知此软件包在其默认优化标志(包括 -march-mcpu 选项)被更改时会出现问题。如果定义了任何覆盖默认优化的环境变量,例如CFLAGSCXXFLAGS,在构建 GRUB 时取消设置它们。

准备 GRUB 进行编译

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

请注意,测试结果将始终显示错误“ufs2_stage1_5 太大。”这是由于编译器问题,但可以忽略,除非您计划从 UFS 分区启动。 这些分区通常仅由 Sun 工作站使用。

安装软件包

make install
mkdir -v /boot/grub
cp -v /usr/lib/grub/i386-pc/stage{1,2} /boot/grub

替换i386-pc替换为适合所用硬件的任何目录。

i386-pc目录包含许多*stage1_5文件,不同的文件适用于不同的文件系统。 查看可用文件并将相应的文件复制到/boot/grub目录。 大多数用户将复制e2fs_stage1_5和/或reiserfs_stage1_5文件中包含相关条目。

6.45.2. GRUB 的内容

已安装的程序: grub、grub-install、grub-md5-crypt、grub-terminfo 和 mbchk

简短描述

grub

Grand Unified Bootloader 的命令 Shell

grub-install

在指定设备上安装 GRUB

grub-md5-crypt

以 MD5 格式加密密码

grub-terminfo

从 terminfo 名称生成 terminfo 命令;当使用未知的终端时可以使用

mbchk

检查多引导内核的格式

6.46. Gzip-1.3.5

Gzip 包包含用于压缩和解压缩文件的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.2 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

6.46.1. Gzip 的安装

Gzip 有 2 个已知的安全漏洞。以下补丁解决了这两个问题

patch -Np1 -i ../gzip-1.3.5-security_fixes-1.patch

准备编译 Gzip

./configure --prefix=/usr

gzexe 脚本将 gzip 二进制文件的位置硬编码到其中。由于二进制文件的位置稍后会更改,因此以下命令可确保将新位置放置到脚本中

sed -i 's@"BINDIR"@/bin@g' gzexe.in

编译软件包

make

安装软件包

make install

gzip 程序移动到/bin目录,并创建一些常用的到它的符号链接

mv -v /usr/bin/gzip /bin
rm -v /usr/bin/{gunzip,zcat}
ln -sv gzip /bin/gunzip
ln -sv gzip /bin/zcat
ln -sv gzip /bin/compress
ln -sv gunzip /bin/uncompress

6.46.2. Gzip 的内容

已安装的程序: compress (链接到 gzip), gunzip (链接到 gzip), gzexe, gzip, uncompress (链接到 gunzip), zcat (链接到 gzip), zcmp, zdiff, zegrep, zfgrep, zforce, zgrep, zless, zmore, 和 znew

简短描述

compress

压缩和解压缩文件

gunzip

解压缩 gzipped 文件

gzexe

创建自解压缩可执行文件

gzip

使用 Lempel-Ziv (LZ77) 编码压缩给定文件

uncompress

解压缩压缩文件

zcat

将给定的 gzipped 文件解压缩到标准输出

zcmp

在 gzipped 文件上运行 cmp

zdiff

在 gzipped 文件上运行 diff

zegrep

在 gzipped 文件上运行 egrep

zfgrep

在 gzipped 文件上运行 fgrep

zforce

强制.gz扩展名应用于所有给定的 gzipped 文件,以便 gzip 不会再次压缩它们;当文件名在文件传输过程中被截断时,这可能很有用

zgrep

在 gzipped 文件上运行 grep

zless

在 gzipped 文件上运行 less

zmore

在 gzipped 文件上运行 more

znew

将文件从 compress 格式重新压缩为 gzip 格式—.Z更改为.gz

6.47. Hotplug-2004_09_23

Hotplug 包包含一些脚本,这些脚本对内核生成的 hotplug 事件作出反应。 这些事件对应于内核状态中在sysfs文件系统中可见的每次更改,例如,硬件的添加和删除。 此软件包还检测启动期间的现有硬件,并将相关模块插入到正在运行的内核中。

大约编译时间: 0.01 SBU
所需磁盘空间: 460 KB
安装依赖于: Bash, Coreutils, Find, Gawk, 和 Make

6.47.1. Hotplug 的安装

安装 Hotplug 包

make install

复制 “install” 目标省略的文件。

cp -v etc/hotplug/pnp.distmap /etc/hotplug

删除 Hotplug 安装的 init 脚本,因为我们将使用 LFS-Bootscripts 包中包含的脚本

rm -rfv /etc/init.d

LFS-Bootscripts 包尚不支持网络设备热插拔。 因此,请删除网络热插拔代理

rm -fv /etc/hotplug/net.agent

创建一个目录,用于存储可由 hotplug 加载的固件

mkdir -v /lib/firmware

6.47.2. Hotplug 的内容

已安装的程序: hotplug
已安装的脚本: /etc/hotplug/*.rc, /etc/hotplug/*.agent
已安装的文件: /etc/hotplug/hotplug.functions, /etc/hotplug/blacklist, /etc/hotplug/{pci,usb}, /etc/hotplug/usb.usermap, /etc/hotplug.d, 和 /var/log/hotplug/events

简短描述

hotplug

当内核的内部状态发生变化时(例如,添加新设备或删除现有设备),Linux 内核默认调用此脚本

/etc/hotplug/*.rc

这些脚本用于冷插拔,即检测系统启动期间已存在的硬件并对其进行操作。 它们由hotplugLFS-Bootscripts 包中包含的 initscript 调用。 *.rc 脚本尝试恢复在系统启动期间丢失的 hotplug 事件,例如,因为根文件系统未由内核挂载

/etc/hotplug/*.agent

这些脚本由 hotplug 调用,以响应内核生成的不同类型的 hotplug 事件。 它们的行动是插入相应的内核模块并调用任何用户提供的脚本

/etc/hotplug/blacklist

此文件包含不应由 Hotplug 脚本插入到内核中的模块的列表

/etc/hotplug/hotplug.functions

此文件包含 Hotplug 包中其他脚本使用的常用函数

/etc/hotplug/{pci,usb}

这些目录包含用户编写的 hotplug 事件处理程序

/etc/hotplug/usb.usermap

此文件包含一些规则,这些规则根据 USB 设备的供应商 ID 和其他属性确定为每个 USB 设备调用哪些用户定义的处理程序

/etc/hotplug.d

此目录包含对接收 hotplug 事件感兴趣的程序(或指向它们的符号链接)。 例如,Udev 在安装期间将其符号链接放置在此处

/lib/firmware

此目录包含需要先加载固件才能使用的设备的固件

/var/log/hotplug/events

此文件包含自启动以来 hotplug 调用的所有事件

6.48. Man-1.5p

Man 包包含用于查找和查看 man 页面的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.9 MB
安装依赖于: Bash, Binutils, Coreutils, Gawk, GCC, Glibc, Grep, Make, 和 Sed

6.48.1. Man 的安装

需要对 Man 的源代码进行两项调整。

第一个是 sed 替换,以将 -R 开关添加到PAGER变量,以便 Less 正确处理转义序列

sed -i 's@-is@&R@g' configure

第二个也是 sed 替换,以注释掉man.conf文件中的 “MANPATH /usr/man” 行,以防止在使用 whatis 等程序时出现冗余结果

sed -i 's@MANPATH./usr/man@#&@g' src/man.conf.in

准备 Man 进行编译

./configure -confdir=/etc

configure 选项的含义

-confdir=/etc

这告诉 man 程序在man.conf配置文件的/etc目录中。

编译软件包

make

安装软件包

make install

注意

如果您将在不支持文本属性(如颜色和粗体)的终端上工作,则可以通过编辑man.conf文件并将 -c 选项添加到NROFF变量中来禁用选择图形再现 (SGR) 转义序列。 如果您为一个计算机使用多种终端类型,则最好为不支持 SGR 的终端选择性地添加GROFF_NO_SGR环境变量。

如果区域设置的字符集使用 8 位字符,请搜索/etc/man.conf中以 “NROFF” 开头的行,并验证它是否与以下内容匹配

              NROFF  /usr/bin/nroff -Tlatin1 -mandoc

注意,即使“latin1”不是本地设置的字符集,也应该使用它。原因是,根据规范,如果没有一些奇怪的转义代码,groff无法排版国际标准化组织 (ISO) 8859-1 以外的字符。格式化 man 页面时,groff 认为它们是 ISO 8859-1 编码,此 -Tlatin1 开关告诉 groff 对输出使用相同的编码。由于 groff 不对输入字符进行重新编码,因此格式化结果实际上与输入编码相同,因此可以用作寻呼机的输入。

这并不能解决非 ISO 8859-1 本地设置中本地化 man 页面的 man2dvi 程序无法工作的问题。此外,它不适用于多字节字符集。第一个问题目前没有解决方案。第二个问题不需担心,因为 LFS 安装不支持多字节字符集。

有关 man 和 info 页面压缩的其他信息,请参阅 BLFS 书籍,网址为 http://www.linuxfromscratch.org/blfs/view/cvs/postlfs/compressdoc.html

6.48.2. Man 的内容

已安装的程序: apropos、makewhatis、man、man2dvi、man2html 和 whatis

简短描述

apropos

搜索 whatis 数据库,并显示包含给定字符串的系统命令的简短描述

makewhatis

构建 whatis 数据库;它读取所有 man 页面的MANPATH并在 whatis 数据库中为每个页面写入名称和简短描述

man

格式化并显示请求的在线 man 页面

man2dvi

将 man 页面转换为 dvi 格式

man2html

将 man 页面转换为 HTML

whatis

搜索 whatis 数据库,并显示包含给定关键字(作为单独的单词)的系统命令的简短描述

6.49. Make-3.80

Make 包包含用于编译软件包的程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 7.1 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep 和 Sed

6.49.1. 安装 Make

准备编译 Make

./configure --prefix=/usr

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.49.2. Make 的内容

已安装的程序: make

简短描述

make

自动确定需要(重新)编译的软件包的哪些部分,然后发出相关命令

6.50. Module-Init-Tools-3.1

Module-Init-Tools 软件包包含用于处理 Linux 内核(大于或等于 2.5.47 版本)中的内核模块的程序。

大约编译时间: 0.1 SBU
所需的磁盘空间: 4.9 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、Flex、GCC、Glibc、Grep、M4、Make 和 Sed

6.50.1. 安装 Module-Init-Tools

Module-Init-Tools 尝试重写它的modprobe.conf在构建过程中生成 man 页面。这是不必要的,并且还依赖于 docbook2man — 它未安装在 LFS 中。运行以下命令以避免这种情况

touch modprobe.conf.5

如果您希望运行 Module-Init-Tools 的测试套件,您需要下载单独的测试套件 tarball。发出以下命令来执行测试(请注意,需要 make distclean 命令来清理源树,因为源作为测试过程的一部分被重新编译)

tar -xvf ../module-init-tools-testsuite-3.1.tar.bz2 --strip-path=1 &&
./configure &&
make check &&
make distclean

准备编译 Module-Init-Tools

./configure --prefix="" --enable-zlib

configure 选项的含义

--enable-zlib

这允许 Module-Init-Tools 软件包处理压缩的内核模块。

编译软件包

make

安装软件包

make install

6.50.2. Module-Init-Tools 的内容

已安装的程序: depmod、insmod、insmod.static、lsmod(链接到 insmod)、modinfo、modprobe(链接到 insmod)和 rmmod(链接到 insmod)

简短描述

depmod

基于在现有模块集中找到的符号创建依赖文件;此依赖文件由 modprobe 用于自动加载所需的模块

insmod

在运行中的内核中安装可加载模块

insmod.static

insmod 的静态编译版本

lsmod

列出当前已加载的模块

modinfo

检查与内核模块关联的对象文件,并显示它可以收集的任何信息

modprobe

使用由 depmod 创建的依赖文件,自动加载相关模块

rmmod

从运行中的内核卸载模块

6.51. Patch-2.5.4

Patch 软件包包含一个程序,用于通过应用通常由 diff 程序创建的“patch”文件来修改或创建文件。

大约编译时间: 0.1 SBU
所需磁盘空间: 1.5 MB
安装取决于: Bash、Binutils、Coreutils、Diffutils、GCC、Glibc、Grep、Make 和 Sed

6.51.1. 安装 Patch

准备编译 Patch。预处理器标志 -D_GNU_SOURCE 仅在 PowerPC 平台上需要。它可以从其他架构中省略

CPPFLAGS=-D_GNU_SOURCE ./configure --prefix=/usr

编译软件包

make

此软件包没有测试套件。

安装软件包

make install

6.51.2. Patch 的内容

已安装的程序: patch

简短描述

patch

根据补丁文件修改文件。补丁文件通常是用 diff 程序创建的差异列表。通过将这些差异应用于原始文件,patch 创建修补版本。

6.52. Procps-3.2.5

Procps 软件包包含用于监视进程的程序。

大约编译时间: 0.1 SBU
所需磁盘空间: 2.3 MB
安装依赖于: Bash、Binutils、Coreutils、GCC、Glibc、Make 和 Ncurses

6.52.1. 安装 Procps

编译软件包

make

安装软件包

make install

6.52.2. Procps 的内容

已安装的程序: free、kill、pgrep、pkill、pmap、ps、skill、snice、sysctl、tload、top、uptime、vmstat、w 和 watch
已安装的库: libproc.so

简短描述

free

报告系统中可用和已用内存的数量(包括物理内存和交换内存)

kill

向进程发送信号

pgrep

根据进程的名称和其他属性查找进程

pkill

根据进程的名称和其他属性向进程发送信号

pmap

报告给定进程的内存映射

ps

列出当前正在运行的进程

skill

向符合给定标准的进程发送信号

snice

更改符合给定标准的进程的调度优先级

sysctl

在运行时修改内核参数

tload

打印当前系统负载平均值的图形

top

显示 CPU 密集型进程的列表;它提供对处理器活动的实时持续观察

uptime

报告系统已运行多长时间、有多少用户已登录以及系统负载平均值

vmstat

报告虚拟内存统计信息,提供有关进程、内存、分页、块输入/输出 (IO)、陷阱和 CPU 活动的信息

w

显示哪些用户当前已登录、在何处以及从何时开始

watch

重复运行给定的命令,显示其输出的第一个屏幕;这允许用户观察输出随时间的变化

libproc

包含此软件包中大多数程序使用的函数

6.53. Psmisc-21.6

Psmisc 软件包包含用于显示有关运行进程的信息的程序。

大约编译时间: 0.1 SBU
所需的磁盘空间: 1.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Ncurses 和 Sed

6.53.1. 安装 Psmisc

准备编译 Psmisc

./configure --prefix=/usr --exec-prefix=""

configure 选项的含义

--exec-prefix=""

这确保 Psmisc 二进制文件将安装到/bin而不是/usr/bin。 这是根据 FHS 的正确位置,因为 LFS-Bootscripts 软件包使用了一些 Psmisc 二进制文件。

编译软件包

make

安装软件包

make install

没有理由让 pstreepstree.x11 程序保留在/bin。因此,将它们移动到/usr/bin:

mv -v /bin/pstree* /usr/bin

默认情况下,Psmisc 的 pidof 程序不会安装。这通常不是问题,因为它稍后会在 Sysvinit 包中安装,该包提供了一个更好的 pidof 程序。如果特定系统不使用 Sysvinit,请通过创建以下符号链接来完成 Psmisc 的安装。

ln -sv killall /bin/pidof

6.53.2. Psmisc 的内容

已安装的程序: fuser, killall, pstree, and pstree.x11 (链接到 pstree)

简短描述

fuser

报告使用给定文件或文件系统的进程的进程 ID (PID)

killall

按名称终止进程; 它向运行任何给定命令的所有进程发送信号

pstree

将正在运行的进程显示为树

pstree.x11

pstree 相同,只是它在退出前等待确认

6.54. Shadow-4.0.9

Shadow 包包含用于以安全方式处理密码的程序。

大致构建时间: 0.4 SBU
所需的磁盘空间: 13.7 MB
安装依赖于: Bash、Binutils、Bison、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

6.54.1. Shadow 的安装

注意

如果您想强制使用强密码,请参考 http://www.linuxfromscratch.org/blfs/view/svn/postlfs/cracklib.html 在构建 Shadow 之前安装 Cracklib。 然后将 --with-libcrack 添加到下面的 configure 命令中。

准备编译 Shadow

./configure --libdir=/lib --enable-shared

禁用 groups 程序及其手册页的安装,因为 Coreutils 提供了一个更好的版本

sed -i 's/groups$(EXEEXT) //' src/Makefile
sed -i '/groups/d' man/Makefile

编译软件包

make

安装软件包

make install

Shadow 使用两个文件来配置系统的身份验证设置。 安装这两个配置文件

cp -v etc/{limits,login.access} /etc

不要使用默认的 crypt 方法,而是使用更安全的 MD5 密码加密方法,该方法还允许密码超过 8 个字符。 还需要更改过时的/var/spool/mailShadow 默认使用的用户邮箱位置到/var/mail当前使用的位置。 这两个都可以通过在将相关配置文件复制到目标位置时更改它来实现

注意

如果您使用 Cracklib 支持构建了 Shadow,请将以下内容插入到下面给出的 sed

-e 's@DICTPATH.*@DICTPATH\t/lib/cracklib/pw_dict@'
sed -e's@#MD5_CRYPT_ENAB.no@MD5_CRYPT_ENAB yes@' \
    -e 's@/var/spool/mail@/var/mail@' \
    etc/login.defs.linux > /etc/login.defs

将放错位置的程序移动到其正确的位置

mv -v /usr/bin/passwd /bin

将 Shadow 的库移动到更合适的位置

mv -v /lib/libshadow.*a /usr/lib
rm -v /lib/libshadow.so
ln -sfv ../../lib/libshadow.so.0 /usr/lib/libshadow.so

useradd 程序的 -D 选项需要/etc/default目录才能正常工作

mkdir -v /etc/default

6.54.2. 配置 Shadow

该软件包包含添加、修改和删除用户和组的实用程序; 设置和更改他们的密码; 并执行其他管理任务。 有关 密码隐藏 含义的完整说明,请参见doc/HOWTO解压缩的源代码树中的文件。 如果使用 Shadow 支持,请记住,需要验证密码的程序(显示管理器、FTP 程序、pop3 守护程序等)必须符合 Shadow 标准。 也就是说,他们需要能够使用隐藏密码。

要启用隐藏密码,请运行以下命令

pwconv

要启用隐藏组密码,请运行

grpconv

在正常情况下,密码尚未创建。 但是,如果稍后返回本节以启用隐藏,请使用 passwd 命令重置任何当前用户密码,或使用 gpasswd 命令重置任何组密码。

6.54.3. 设置 root 密码

选择用户 root 的密码并通过运行以下命令进行设置

passwd root

6.54.4. Shadow 的内容

已安装的程序: chage, chfn, chpasswd, chsh, expiry, faillog, gpasswd, groupadd, groupdel, groupmod, grpck, grpconv, grpunconv, lastlog, login, logoutd, mkpasswd, newgrp, newusers, passwd, pwck, pwconv, pwunconv, sg (链接到 newgrp), useradd, userdel, usermod, vigr (链接到 vipw), 和 vipw
已安装的库: libshadow.[a,so]

简短描述

chage

用于更改强制密码更改之间的最大天数

chfn

用于更改用户的全名和其他信息

chpasswd

用于更新整个系列用户帐户的密码

chsh

用于更改用户的默认登录 shell

expiry

检查并执行当前的密码过期策略

faillog

用于检查登录失败的日志,设置帐户被阻止前的最大失败次数,或重置失败计数

gpasswd

用于向组添加和删除成员和管理员

groupadd

使用给定的名称创建组

groupdel

删除具有给定名称的组

groupmod

用于修改给定组的名称或 GID

grpck

验证组文件的完整性/etc/group/etc/gshadow

grpconv

从普通组文件创建或更新隐藏组文件

grpunconv

更新/etc/group/etc/gshadow然后删除后者

lastlog

报告所有用户或给定用户的最近登录

login

由系统用于让用户登录

logoutd

是一个守护进程,用于强制执行对登录时间和端口的限制

mkpasswd

生成随机密码

newgrp

用于在登录会话期间更改当前 GID

newusers

用于创建或更新整个系列的用户帐户

passwd

用于更改用户或组帐户的密码

pwck

验证密码文件的完整性/etc/passwd/etc/shadow

pwconv

从普通密码文件创建或更新隐藏密码文件

pwunconv

更新/etc/passwd/etc/shadow然后删除后者

sg

在用户的 GID 设置为给定组的 GID 时执行给定的命令

su

使用替换用户和组 ID 运行 shell

useradd

使用给定的名称创建一个新用户,或更新默认的新用户信息

userdel

删除给定的用户帐户

usermod

用于修改给定用户的登录名、用户标识 (UID)、shell、初始组、主目录等。

vigr

编辑/etc/group或者/etc/gshadow文件。

vipw

编辑/etc/passwd或者/etc/shadow文件。

libshadow

包含此程序包中大多数程序使用的函数

6.55. Sysklogd-1.4.1

Sysklogd 包包含用于记录系统消息的程序,例如内核在发生异常情况时给出的消息。

大约编译时间: 0.1 SBU
所需的磁盘空间: 704 KB
安装依赖于: Binutils、Coreutils、GCC、Glibc、Make

6.55.1. Sysklogd 的安装

以下补丁修复了各种问题,包括使用 Linux 2.6 系列内核构建 Sysklogd 的问题

patch -Np1 -i ../sysklogd-1.4.1-fixes-1.patch

编译软件包

make

安装软件包

make install

6.55.2. 配置 Sysklogd

创建一个新的/etc/syslog.conf通过运行以下命令创建文件

cat > /etc/syslog.conf << "EOF"
# Begin /etc/syslog.conf

auth,authpriv.* -/var/log/auth.log
*.*;auth,authpriv.none -/var/log/sys.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
*.emerg *

# log the bootscript output:
local2.* -/var/log/boot.log

# End /etc/syslog.conf
EOF

6.55.3. Sysklogd 的内容

已安装的程序: klogd 和 syslogd

简短描述

klogd

一个用于拦截和记录内核消息的系统守护进程

syslogd

记录系统程序提供的用于记录的消息。 每个记录的消息至少包含一个日期戳和一个主机名,通常还包含程序的名称,但这取决于日志记录守护程序的可信度

6.56. Sysvinit-2.86

Sysvinit 包包含用于控制系统的启动、运行和关闭的程序。

大约编译时间: 0.1 SBU
所需的磁盘空间: 1012 KB
安装依赖于: Binutils、Coreutils、GCC、Glibc 和 Make

6.56.1. Sysvinit 的安装

当运行级别改变时(例如,当停止系统时),init 会向由 init 自身启动且不应在新运行级别中运行的那些进程发送终止信号。 在执行此操作时,init 输出诸如“发送进程 TERM 信号”之类的消息,这似乎暗示它正在向所有当前正在运行的进程发送这些信号。 为了避免这种误解,请修改源代码,以便这些消息读起来像“向由 init 启动的进程发送 TERM 信号

sed -i 's@Sending processes@& started by init@g' \
    src/init.c

编译软件包

make -C src

安装软件包

make -C src install

6.56.2. 配置 Sysvinit

创建一个新文件/etc/inittab通过运行以下命令

cat > /etc/inittab << "EOF"
# Begin /etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc sysinit

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty -I '\033(K' tty1 9600
2:2345:respawn:/sbin/agetty -I '\033(K' tty2 9600
3:2345:respawn:/sbin/agetty -I '\033(K' tty3 9600
4:2345:respawn:/sbin/agetty -I '\033(K' tty4 9600
5:2345:respawn:/sbin/agetty -I '\033(K' tty5 9600
6:2345:respawn:/sbin/agetty -I '\033(K' tty6 9600

# End /etc/inittab
EOF

-I '\033(K' 选项告诉 agetty 在执行任何其他操作之前,向终端发送此转义序列。此转义序列将控制台字符集切换为用户自定义的字符集,该字符集可以通过运行 setfont 程序进行修改。来自 LFS-Bootscripts 包的 console initscript 在系统启动期间调用 setfont 程序。对于使用非 ISO 8859-1 屏幕字体的人来说,发送此转义序列是必要的,但它不会影响以英语为母语的人。

6.56.3. Sysvinit 的内容

已安装的程序: halt, init, killall5, last, lastb (链接到 last), mesg, pidof (链接到 killall5), poweroff (链接到 halt), reboot (链接到 halt), runlevel, shutdown, sulogin, telinit (链接到 init), utmpdump, 和 wall

简短描述

halt

通常使用 -h 选项调用 shutdown,除非已经在运行级别 0 中,然后它会告诉内核停止系统;它会在文件中记录/var/log/wtmp系统正在被关闭

init

内核初始化硬件后启动的第一个进程,它接管启动过程并启动它被指示的所有进程

killall5

向所有进程发送信号,除了它自己会话中的进程,因此它不会杀死运行调用它的脚本的 shell

last

显示哪些用户上次登录(和注销),回溯搜索/var/log/wtmp文件;它还显示系统启动、关闭和运行级别更改

lastb

显示失败的登录尝试,如记录在/var/log/btmp

mesg

控制其他用户是否可以向当前用户的终端发送消息

mountpoint

检查目录是否为挂载点

pidof

报告给定程序的 PID

poweroff

告诉内核停止系统并关闭计算机(参见 halt

reboot

告诉内核重启系统(参见 halt

runlevel

报告上一个和当前的运行级别,如在/var/run/utmp

shutdown

以安全的方式关闭系统,向所有进程发出信号并通知所有登录用户

sulogin

允许 root 登录;当系统进入单用户模式时,它通常由 init 调用

telinit

告诉 init 要切换到的运行级别

utmpdump

以更友好的格式显示给定登录文件的内容

wall

向所有登录用户写入消息

6.57. Tar-1.15.1

Tar 软件包包含一个归档程序。

预计构建时间: 0.2 SBU
所需磁盘空间: 12.7 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make 和 Sed

6.57.1. Tar 的安装

-S 选项与大于 4 GB 的文件一起使用时,Tar 存在一个错误。以下补丁正确地修复了这个问题

patch -Np1 -i ../tar-1.15.1-sparse_fix-1.patch

准备编译 Tar

./configure --prefix=/usr --bindir=/bin --libexecdir=/usr/sbin

编译软件包

make

要测试结果,请执行:make check

安装软件包

make install

6.57.2. Tar 的内容

已安装的程序: rmt 和 tar

简短描述

rmt

通过进程间通信连接远程操作磁带驱动器

tar

创建、从档案中提取文件并列出档案的内容,也称为 tarball

6.58. Udev-056

Udev 包包含用于动态创建设备节点的程序。

大约编译时间: 0.1 SBU
所需的磁盘空间: 6.7 MB
安装依赖于: Coreutils 和 Make

6.58.1. Udev 的安装

编译软件包

make udevdir=/dev
udevdir=/dev

这告诉 udev 在哪个目录中创建设备节点。

要测试结果,执行:make test

安装软件包

make DESTDIR=/ udevdir=/dev install

make 选项的含义

DESTDIR=/

这可以防止 Udev 构建过程杀死可能在主机系统上运行的任何 udevd 进程。

默认情况下,Udev 的配置远非理想,因此请在此处安装配置文件

cp -v ../udev-config-4.rules /etc/udev/rules.d/25-lfs.rules

运行 udevstart 程序以创建我们完整的设备节点补充。

/sbin/udevstart

6.58.2. Udev 的内容

已安装的程序: udev, udevd, udevsend, udevstart, udevinfo, 和 udevtest
已安装的目录: /etc/udev

简短描述

udev

/dev中创建设备节点或重命名网络接口(不在 LFS 中),以响应热插拔事件

udevd

一个守护进程,在将热插拔事件提交到 udev 之前对其进行重新排序,从而避免各种竞争条件

udevsend

将热插拔事件传递给 udevd

udevstart

/dev对应于直接编译到内核中的驱动程序;它通过模拟内核可能在调用此程序之前丢弃的热插拔事件(例如,因为根文件系统尚未挂载)并将此类合成热插拔事件提交到 udev 来执行该任务

udevinfo

允许用户查询 udev 数据库,以获取有关系统上当前存在的任何设备的信息;它还提供了一种查询sysfs树中的任何设备以帮助创建 udev 规则的方法

udevtest

为给定的设备模拟 udev 运行,并打印出真实的 udev 将创建的节点名称,或者(不在 LFS 中)重命名的网络接口的名称

/etc/udev

包含 udev 配置文件、设备权限和设备命名规则

6.59. Util-linux-2.12q

Util-linux 软件包包含各种实用程序。 其中包括用于处理文件系统、控制台、分区和消息的实用程序。

预计构建时间: 0.2 SBU
所需的磁盘空间: 11.6 MB
安装依赖于: Bash、Binutils、Coreutils、Diffutils、GCC、Gettext、Glibc、Grep、Make、Ncurses、Sed 和 Zlib

6.59.1. FHS 合规性说明

FHS 建议使用/var/lib/hwclock目录而不是通常的/etc目录作为adjtime文件的位置。为了使 hwclock 程序符合 FHS,请运行以下命令

sed -i 's@etc/adjtime@var/lib/hwclock/adjtime@g' \
    hwclock/hwclock.c
mkdir -p /var/lib/hwclock

6.59.2. Util-linux 的安装

Util-linux 无法针对较新版本的 Linux-Libc-Headers 进行编译。以下补丁正确地修复了这个问题

patch -Np1 -i ../util-linux-2.12q-cramfs-1.patch

Util-linux 存在一个安全漏洞,可能允许用户在没有nosuid选项的情况下重新挂载卷。 以下补丁修复了这个问题

patch -Np1 -i ../util-linux-2.12q-umount_fix-1.patch

准备编译 Util-linux

./configure

编译软件包

make HAVE_KILL=yes HAVE_SLN=yes

make 参数的含义

HAVE_KILL=yes

这可以防止 kill 程序(已由 Procps 安装)被再次构建和安装。

HAVE_SLN=yes

这可以防止 sln 程序(Glibc 已经安装的 ln 的静态链接版本)被再次构建和安装。

此软件包没有测试套件。

安装包并将 logger 二进制文件移动到/bin因为 LFS-Bootscripts 包需要它

make HAVE_KILL=yes HAVE_SLN=yes install
mv /usr/bin/logger /bin

6.59.3. Util-linux 的内容

已安装的程序: agetty, arch, blockdev, cal, cfdisk, chkdupexe, col, colcrt, colrm, column, ctrlaltdel, cytune, ddate, dmesg, elvtune, fdformat, fdisk, fsck.cramfs, fsck.minix, getopt, hexdump, hwclock, ipcrm, ipcs, isosize, line, logger, look, losetup, mcookie, mkfs, mkfs.bfs, mkfs.cramfs, mkfs.minix, mkswap, more, mount, namei, pg, pivot_root, ramsize (链接到 rdev), raw, rdev, readprofile, rename, renice, rev, rootflags (链接到 rdev), script, setfdprm, setsid, setterm, sfdisk, swapdev, swapoff (链接到 swapon), swapon, tunelp, ul, umount, vidmode (链接到 rdev), whereis, 和 write

简短描述

agetty

打开一个 tty 端口,提示输入登录名,然后调用 login 程序

arch

报告机器的架构

blockdev

允许用户从命令行调用块设备 ioctl

cal

显示一个简单的日历

cfdisk

操作给定设备的分区表

chkdupexe

查找重复的可执行文件

col

过滤掉反向换行

colcrt

为缺少某些功能的终端过滤 nroff 输出,例如 overstriking 和 half-lines

colrm

过滤掉给定的列

column

将给定文件格式化为多列

ctrlaltdel

将 Ctrl+Alt+Del 键组合的功能设置为硬复位或软复位

cytune

调整 Cyclades 卡的串行线驱动程序的参数

ddate

给出 Discordian 日期或将给定的 Gregorian 日期转换为 Discordian 日期

dmesg

转储内核启动信息

elvtune

调整块设备的性能和交互性

fdformat

对软盘进行低级格式化

fdisk

操作给定设备的分区表

fsck.cramfs

对给定设备上的 Cramfs 文件系统执行一致性检查

fsck.minix

对给定设备上的 Minix 文件系统执行一致性检查

getopt

解析给定命令行中的选项

hexdump

以十六进制或另一种给定格式转储给定的文件

hwclock

读取或设置系统的硬件时钟,也称为实时时钟 (RTC) 或基本输入/输出系统 (BIOS) 时钟

ipcrm

删除给定的进程间通信 (IPC) 资源

ipcs

提供 IPC 状态信息

isosize

报告 iso9660 文件系统的大小

line

复制单行

logger

将给定的消息输入到系统日志中

look

显示以给定字符串开头的行

losetup

设置和控制循环设备

mcookie

xauth 生成 magic cookie(128 位随机十六进制数)

mkfs

在设备(通常是硬盘分区)上构建文件系统

mkfs.bfs

创建 Santa Cruz Operations (SCO) bfs 文件系统

mkfs.cramfs

创建 cramfs 文件系统

mkfs.minix

创建 Minix 文件系统

mkswap

初始化给定的设备或文件以用作交换区

more

一个每次翻页显示文本的过滤器

mount

将给定设备上的文件系统连接到文件系统树中的指定目录

namei

显示给定路径名中的符号链接

pg

一次一屏幕地显示文本文件

pivot_root

使给定的文件系统成为当前进程的新根文件系统

ramsize

设置可引导映像中 RAM 磁盘的大小

raw

用于将 Linux 原始字符设备绑定到块设备

rdev

查询和设置可引导映像中的根设备等

readprofile

读取内核分析信息

rename

重命名给定的文件,用另一个字符串替换给定的字符串

renice

更改正在运行的进程的优先级

rev

反转给定文件的行

rootflags

在可引导映像中设置 rootflags

script

制作终端会话的脚本

setfdprm

设置用户提供的软盘参数

setsid

在新会话中运行给定的程序

setterm

设置终端属性

sfdisk

磁盘分区表操作器

swapdev

在可引导映像中设置交换设备

swapoff

禁用设备和文件以进行分页和交换

swapon

启用设备和文件以进行分页和交换,并列出当前正在使用的设备和文件

tunelp

调整行式打印机的参数

ul

一个用于将下划线转换为转义序列的过滤器,指示正在使用的终端的下划线

umount

从系统的文件树中断开文件系统

vidmode

在可引导映像中设置视频模式

whereis

报告给定命令的二进制文件、源文件和 man 页面所在的位置

write

向给定的用户发送消息,如果该用户尚未禁用接收此类消息

6.60. 关于调试符号

默认情况下,大多数程序和库在编译时都包含调试符号(使用 gcc-g 选项)。 这意味着当调试包含调试信息的程序或库时,调试器不仅可以提供内存地址,还可以提供例程和变量的名称。

但是,包含这些调试符号会显着扩大程序或库的体积。 以下是一个例子,说明了这些符号占用的空间量

  • 带有调试符号的 bash 二进制文件:1200 KB

  • 不带调试符号的 bash 二进制文件:480 KB

  • 带有调试符号的 Glibc 和 GCC 文件(/lib/usr/lib):87 MB

  • 不带调试符号的 Glibc 和 GCC 文件:16 MB

大小可能因使用的编译器和 C 库而异,但比较带有和不带有调试符号的程序时,差异通常是 2 到 5 倍。

因为大多数用户永远不会在其系统软件上使用调试器,因此可以通过删除这些符号来回收大量磁盘空间。 下一节将介绍如何从程序和库中剥离所有调试符号。 有关系统优化的更多信息,请访问 http://www.linuxfromscratch.org/hints/downloads/files/optimization.txt

6.61. 再次剥离

如果目标用户不是程序员,并且不打算对系统软件进行任何调试,则可以通过从二进制文件和库中删除调试符号来减少大约 200 MB 的系统大小。 除了无法再完全调试该软件之外,这不会造成任何不便。

大多数使用下面提到的命令的人都不会遇到任何困难。 但是,很容易发生拼写错误并使新系统无法使用,因此在运行 strip 命令之前,最好备份当前情况。

在执行剥离之前,请特别注意确保要剥离的二进制文件没有正在运行。 如果不确定用户是否使用第 6.3 节“进入 Chroot 环境”中给出的命令进入了 chroot,请先从 chroot 中退出

logout

然后使用以下命令重新进入

chroot $LFS /tools/bin/env -i \
    HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
    PATH=/bin:/usr/bin:/sbin:/usr/sbin \
    /tools/bin/bash --login

现在可以安全地剥离二进制文件和库

/tools/bin/find /{,usr/}{bin,lib,sbin} -type f \
   -exec /tools/bin/strip --strip-debug '{}' ';'

将会报告大量文件的文件格式无法识别。 可以安全地忽略这些警告。 这些警告表明这些文件是脚本而不是二进制文件。

如果磁盘空间非常紧张,则可以在/{,usr/}{bin,sbin}中使用 --strip-all 选项来获取更多兆字节。 不要在库上使用此选项——它们会被破坏。

6.62. 清理

从现在开始,在退出后重新进入 chroot 环境时,请使用以下修改后的 chroot 命令

chroot "$LFS" /usr/bin/env -i \
    HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
    PATH=/bin:/usr/bin:/sbin:/usr/sbin \
    /bin/bash --login

原因是/tools中的程序不再需要。 由于不再需要它们,因此您可以根据需要删除/tools目录,或者将其打包并保存起来以构建另一个最终系统。

注意

删除/tools还将删除用于运行工具链测试的 Tcl、Expect 和 DejaGNU 的临时副本。 如果您以后需要这些程序,则需要重新编译和重新安装它们。 BLFS 书籍包含有关此操作的说明(请参阅 http://www.linuxfromscratch.org/blfs/)。

第 7. 章 设置系统引导脚本

7.1. 简介

本章详细介绍如何安装和配置 LFS-Bootscripts 软件包。 这些脚本中的大多数都可以在不修改的情况下工作,但一些脚本需要额外的配置文件,因为它们处理的是依赖于硬件的信息。

本书中使用 System-V 样式的 init 脚本,因为它们被广泛使用。 有关其他选项,请访问 http://www.linuxfromscratch.org/hints/downloads/files/bsd-init.txt 获取详细的 BSD 样式 init 设置提示。 在 LFS 邮件列表中搜索“depinit”也会提供更多选择。

如果使用替代样式的 init 脚本,请跳过本章并转到第 8 章

7.2. LFS-Bootscripts-3.2.1

LFS-Bootscripts 软件包包含一组在启动/关闭时启动/停止 LFS 系统的脚本。

大约编译时间: 0.1 SBU
所需的磁盘空间: 0.3 MB
安装取决于: Bash 和 Coreutils

7.2.1. 安装 LFS-Bootscripts

安装软件包

make install

7.2.2. LFS-Bootscripts 的内容

已安装的脚本: checkfs, cleanfs, console, functions, halt, hotplug, ifdown, ifup, localnet, mountfs, mountkernfs, network, rc, reboot, sendsignals, setclock, static, swap, sysklogd, template 和 udev

简短描述

checkfs

在挂载文件系统之前,检查文件系统的完整性(日志和基于网络的文件系统除外)

cleanfs

删除重启后不应保留的文件,例如位于以下目录中的文件:/var/run//var/lock/; 它重新创建/var/run/utmp并删除可能存在的/etc/nologin, /fastboot/forcefsck文件。

console

为所需的键盘布局加载正确的键盘映射表;它还会设置屏幕字体

functions

包含常用函数,例如错误和状态检查,这些函数被多个启动脚本使用

halt

停止系统

hotplug

加载系统设备的模块

ifdown

协助网络脚本停止网络设备

ifup

协助网络脚本启动网络设备

localnet

设置系统的主机名和本地环回设备

mountfs

挂载所有文件系统,除了标记为 noauto 或基于网络的文件系统

mountkernfs

挂载虚拟内核文件系统,例如proc

network

设置网络接口,例如网卡,并设置默认网关(如果适用)

rc

主运行级别控制脚本;它负责按顺序逐个运行所有其他启动脚本,顺序由正在处理的符号链接的名称决定

reboot

重启系统

sendsignals

确保在系统重启或停止之前终止每个进程

setclock

如果硬件时钟未设置为 UTC 时间,则将内核时钟重置为本地时间

static

提供将静态 Internet 协议 (IP) 地址分配给网络接口所需的功能

swap

启用和禁用交换文件和分区

sysklogd

启动和停止系统和内核日志守护程序

template

用于为其他守护程序创建自定义启动脚本的模板

udev

准备/dev目录并启动 Udev

7.3. 这些启动脚本如何工作?

Linux 使用一种名为 SysVinit 的特殊启动机制,它基于运行级别的概念。 不同系统的运行级别可能差异很大,因此不能因为在某个特定的 Linux 发行版中正常工作,就认为它们在 LFS 中也应该以相同的方式工作。 LFS 有自己做事的方式,但它尊重普遍接受的标准。

SysVinit(从现在起简称为“init”)使用运行级别方案。 有七个运行级别(编号为 0 到 6)(实际上,还有更多运行级别,但它们用于特殊情况,通常不使用。 请参见init(8)了解更多详细信息),每个运行级别对应于计算机启动时应执行的操作。 默认运行级别为 3。以下是不同运行级别的描述,正如它们所实现的

0: 停止计算机
1: 单用户模式
2: 没有联网的多用户模式
3: 具有联网的多用户模式
4: 保留用于自定义,否则与 3 相同
5: 与 4 相同,通常用于 GUI 登录(如 X 的 xdm 或 KDE 的 kdm
6: 重启计算机

用于更改运行级别的命令是 init [运行级别],其中 [运行级别] 是目标运行级别。 例如,要重启计算机,用户可以发出 init 6 命令,该命令是 reboot 命令的别名。 同样,init 0halt 命令的别名。

下有许多目录/etc/rc.d看起来像rc?.d(其中 ? 是运行级别的编号)和rcsysinit.d,都包含许多符号链接。 有些以 K 开头,另一些以 S 开头,并且它们都以两个数字紧随其后。 K 表示停止(kill)服务,S 表示启动服务。 这些数字决定了脚本的运行顺序,从 00 到 99—数字越小,执行得越早。 当 init 切换到另一个运行级别时,根据选择的运行级别,将启动或停止相应的服务。

真正的脚本位于/etc/rc.d/init.d。 它们执行实际工作,所有符号链接都指向它们。 停止链接和启动链接指向/etc/rc.d/init.d中的同一个脚本。 这是因为可以使用不同的参数(例如 startstoprestartreloadstatus)调用这些脚本。 遇到 K 链接时,将使用 stop 参数运行相应的脚本。 遇到 S 链接时,将使用 start 参数运行相应的脚本。

此解释有一个例外。 在rc0.drc6.d目录中以 S 开头的链接不会导致任何启动。 将使用参数 stop 调用它们来停止某些内容。 这背后的逻辑是,当用户要重启或停止系统时,不需要启动任何内容。 系统只需要停止。

以下是对参数使脚本执行的操作的描述

start

服务已启动。

stop

服务已停止。

restart

服务已停止,然后再次启动。

reload

服务的配置已更新。 这在修改了服务的配置文件后使用,而无需重新启动服务。

status

告知服务是否正在运行以及使用哪个 PID。

随意修改启动过程的工作方式(毕竟,这是您自己的 LFS 系统)。 此处给出的文件是它如何完成的一个示例。

7.4. LFS 系统上的设备和模块处理

第 6 章中,我们安装了 Udev 软件包。 在我们深入研究其工作原理的细节之前,有必要简要回顾一下以前的设备处理方法。

通常,Linux 系统传统上使用静态设备创建方法,该方法在/dev下创建大量设备节点(有时实际上是数千个节点),而不管相应的硬件设备是否实际存在。 这通常通过 MAKEDEV 脚本完成,该脚本包含对 mknod 程序的多次调用,其中包含世界上可能存在的每个设备的相关的设备主编号和次编号。 使用 Udev 方法,只有内核检测到的设备才会创建设备节点。 因为每次系统启动时都会创建这些设备节点,所以它们将存储在tmpfs文件系统上(完全驻留在系统内存中的虚拟文件系统)。 设备节点不需要太多空间,因此使用的内存可以忽略不计。

7.4.1. 历史

2000 年 2 月,一个名为devfs的新文件系统合并到 2.3.46 内核中,并在 2.4 系列的稳定内核中可用。 尽管它存在于内核源代码本身中,但这种动态创建设备的方法从未得到核心内核开发人员的广泛支持。

采用的方法的主要问题devfs是它处理设备检测、创建和命名的方式。 最后一个问题,即设备节点命名,也许是最关键的。 人们普遍认为,如果允许配置设备名称,则设备命名策略应由系统管理员决定,而不是由任何特定开发人员强加给他们。 的devfs文件系统还存在其设计中固有的竞争条件,如果没有对内核进行重大修改,则无法修复。 由于最近缺乏维护,它也被标记为已弃用。

随着不稳定的 2.5 内核树的开发,后来发布为 2.6 系列的稳定内核,一个新的虚拟文件系统名为sysfs出现了。 的工作sysfs是将系统硬件配置的视图导出到用户空间进程。 有了这种用户空间可见的表示形式,看到用户空间替代devfs的可能性变得更加现实。

7.4.2. Udev 实现

sysfs文件系统在上面已简要提及。 人们可能想知道sysfs如何知道系统上存在的设备以及应该为它们使用什么设备编号。 直接编译到内核中的驱动程序会在内核检测到它们时,将它们的对象注册到sysfs。 对于编译为模块的驱动程序,此注册将在加载模块时发生。 一旦sysfs文件系统被挂载(在/sys上),内置驱动程序注册到sysfs的数据可用于用户空间进程和 udev 进行设备节点创建。

在 Linux 启动时,S10udev init 脚本负责创建这些设备节点。该脚本首先注册 /sbin/udevsend 作为热插拔事件处理程序。热插拔事件(如下所述)通常不会在此阶段生成,但会注册 udev 以防万一它们确实发生。然后,udevstart 程序会遍历/sys文件系统,并在/dev下创建与描述匹配的设备。例如,/sys/class/tty/vcs/dev包含字符串 “7:0”。udevstart 使用此字符串来创建/dev/vcs,主设备号为 7,次设备号为 0。在/dev目录下创建的节点的名称和权限是根据/etc/udev/rules.d/目录中的文件中指定的规则配置的。这些文件的编号方式与 LFS-Bootscripts 包类似。如果 udev 无法找到它正在创建的设备的规则,它会将权限默认设置为 660,所有者设置为 root:root

完成上述阶段后,所有已存在且具有编译到内核中的驱动程序的设备都将可供使用。 这就引出了具有模块化驱动程序的设备。

之前,我们提到了“热插拔事件处理程序”的概念。当内核检测到新的设备连接时,内核会生成一个热插拔事件,并查看文件/proc/sys/kernel/hotplug以确定处理设备连接的用户空间程序。 udev 启动脚本将 udevsend 注册为此处理程序。生成这些热插拔事件时,内核会告诉 udev 检查/sys文件系统以获取有关此新设备的信息,并创建该设备的/dev条目。

这就引出了 udev 存在的一个问题,以及devfs之前存在的类似问题。它通常被称为“鸡和蛋”问题。大多数 Linux 发行版通过/etc/modules.conf中的条目来处理模块加载。访问设备节点会导致加载相应的内核模块。对于 udev,此方法不起作用,因为设备节点在模块加载之前不存在。为了解决这个问题,LFS-Bootscripts 包中添加了 S05modules 启动脚本,以及/etc/sysconfig/modules文件。通过将模块名称添加到模块文件中,这些模块将在计算机启动时加载。这允许 udev 检测设备并创建相应的设备节点。

请注意,在较慢的机器上或对于创建大量设备节点的驱动程序,创建设备的过程可能需要几秒钟才能完成。这意味着某些设备节点可能无法立即访问。

7.4.3. 处理热插拔/动态设备

当您插入设备时,例如通用串行总线 (USB) MP3 播放器,内核会识别出该设备现在已连接,并生成一个热插拔事件。如果驱动程序已加载(无论是编译到内核中还是通过 S05modules 启动脚本加载),则将调用 udev 来根据sysfs中可用的数据创建相关的设备节点。/sys.

如果刚插入的设备的驱动程序可用作模块但当前未加载,则 Hotplug 包将加载相应的模块,并通过为其创建设备节点来使该设备可用。

7.4.4. 创建设备的问题

自动创建设备节点时,存在一些已知问题

1) 内核驱动程序可能不会将其数据导出到sysfs.

这在来自内核树外部的第三方驱动程序中最常见。Udev 将无法自动创建此类驱动程序的设备节点。使用/etc/sysconfig/createfiles配置文件手动创建设备。查阅devices.txt内核文档中的文件或该驱动程序的文档以查找正确的主/次设备号。

2) 需要非硬件设备。这在高级 Linux 音频架构 (ALSA) 项目的开放声音系统 (OSS) 兼容性模块中最常见。可以通过以下两种方式之一处理这些类型的设备

  • 将模块名称添加到/etc/sysconfig/modules

  • /etc/modprobe.conf中使用 “install” 行。 这告诉 modprobe 命令 “加载此模块时,同时加载此其他模块。” 例如

    install snd-pcm modprobe -i snd-pcm ; modprobe \
        snd-pcm-oss ; true

    这将导致系统在任何请求加载驱动程序 snd-pcm 时,同时加载 snd-pcmsnd-pcm-oss 模块。

7.5. 配置 setclock 脚本

setclock 脚本从硬件时钟读取时间,硬件时钟也称为 BIOS 或互补金属氧化物半导体 (CMOS) 时钟。如果硬件时钟设置为 UTC,则此脚本将使用/etc/localtime文件将硬件时钟的时间转换为本地时间(该文件告诉 hwclock 程序用户所在的时区)。无法检测硬件时钟是否设置为 UTC,因此需要手动配置。

如果您不记得硬件时钟是否设置为 UTC,请运行 hwclock --localtime --show 命令来找出答案。这将显示根据硬件时钟的当前时间。如果此时间与您的手表显示的时间匹配,则表示硬件时钟设置为本地时间。如果 hwclock 的输出不是本地时间,则很可能将其设置为 UTC 时间。通过为时区加或减去适当的小时数来验证这一点。例如,如果您当前位于 MST 时区,也称为 GMT -0700,则将七个小时添加到本地时间。

UTC变量的值更改为 0(零),如果硬件时钟 设置为 UTC 时间。

创建一个新文件/etc/sysconfig/clock通过运行以下命令

cat > /etc/sysconfig/clock << "EOF"
# Begin /etc/sysconfig/clock

UTC=1

# End /etc/sysconfig/clock
EOF

http://www.linuxfromscratch.org/hints/downloads/files/time.txt 中可以找到一个很好的提示,解释如何在 LFS 上处理时间。它解释了时区、UTC 和TZ环境变量等问题。

7.6. 配置 Linux 控制台

本节讨论如何配置设置键盘映射和控制台字体的 console 启动脚本。如果不会使用非 ASCII 字符(例如,英镑符号和欧元字符),并且键盘是美国键盘,请跳过本节。如果没有配置文件,console 启动脚本将不执行任何操作。

console 脚本读取/etc/sysconfig/console文件以获取配置信息。决定将使用哪个键盘映射和屏幕字体。各种特定于语言的 HOWTO 也可以对此有所帮助(请参阅 http://www.tldp.org/HOWTO/HOWTO-INDEX/other-lang.html。一个预制的/etc/sysconfig/console文件,其中包含 LFS-Bootscripts 包安装的几个国家的已知设置,因此如果支持该国家/地区,则可以取消注释相关的部分。如果仍然不确定,请查看/usr/share/kbd目录以获取有效的键盘映射和屏幕字体。阅读loadkeys(1)setfont(8)以确定这些程序的正确参数。确定后,使用以下命令创建配置文件

cat >/etc/sysconfig/console <<"EOF"
KEYMAP="[arguments for loadkeys]"
FONT="[arguments for setfont]"
EOF

例如,对于想要使用欧元字符(可以通过按 AltGr+E 访问)的西班牙用户,以下设置是正确的

cat >/etc/sysconfig/console <<"EOF"
KEYMAP="es euro2"
FONT="lat9-16 -u iso01"
EOF

注意

只有对于 ISO 8859-15 字符集,上面的 FONT行才是正确的。如果使用 ISO 8859-1,因此使用英镑符号而不是欧元,则正确的只有对于 ISO 8859-15 字符集,上面的 FONT行将是

FONT="lat1-16"

如果未设置KEYMAP或者只有对于 ISO 8859-15 字符集,上面的 FONT变量,则 console init 脚本将不会运行相应的程序。

在某些键盘映射中,退格键和删除键发送的字符与内核中内置的默认键盘映射中的字符不同。这会混淆某些应用程序。例如,当按下退格键时,Emacs 会显示其帮助(而不是删除光标之前的字符)。要检查正在使用的键盘映射是否受到影响(这仅适用于 i386 键盘映射)

zgrep '\W14\W' [/path/to/your/keymap]

如果键码 14 是退格键而不是删除键,请创建以下键盘映射代码段来解决此问题

mkdir -pv /etc/kbd && cat > /etc/kbd/bs-sends-del <<"EOF"
                  keycode  14 = Delete Delete Delete Delete
              alt keycode  14 = Meta_Delete
        altgr alt keycode  14 = Meta_Delete
                  keycode 111 = Remove
    altgr control keycode 111 = Boot
      control alt keycode 111 = Boot
altgr control alt keycode 111 = Boot
EOF

告诉 console 脚本在主键盘映射之后加载此代码段

cat >>/etc/sysconfig/console <<"EOF"
KEYMAP_CORRECTIONS="/etc/kbd/bs-sends-del"
EOF

要将键盘映射直接编译到内核中,而不是每次都从 console 启动脚本中设置它,请按照 第 8.3 节,“Linux-2.6.11.12” 中给出的说明进行操作。这样做可以确保键盘始终按预期工作,即使在启动到维护模式时(通过将 init=/bin/sh 传递给内核),因为在这种情况下不会运行 console 启动脚本。此外,内核不会自动设置屏幕字体。这不应该造成太多问题,因为 ASCII 字符将被正确处理,并且用户不太可能在维护模式下依赖非 ASCII 字符。

由于内核将设置键盘映射,因此可以省略KEYMAP配置文件中的/etc/sysconfig/console变量。如果需要,也可以将其保留在原位,而不会产生任何后果。如果运行多个不同的内核,很难确保键盘映射已编译到每个内核中,则保留它可能是有益的。

7.7. 配置 sysklogd 脚本

sysklogd脚本使用 -m 0 选项调用 syslogd 程序。此选项关闭 syslogd 默认每 20 分钟写入日志文件的周期性时间戳标记。如果想打开此周期性时间戳标记,请编辑sysklogd脚本并进行相应的更改。有关详细信息,请参阅 man syslogd

7.8. 创建 /etc/inputrc 文件

inputrc文件处理特定情况下的键盘映射。此文件是 Bash 和大多数其他 shell 使用的 Readline(与输入相关的库)使用的启动文件。

大多数人不需要特定于用户的键盘映射,因此以下命令会创建一个全局/etc/inputrc供所有登录用户使用。如果您之后决定需要按用户覆盖默认设置,可以创建一个.inputrc文件,放在用户的主目录下,其中包含修改后的映射。

要了解更多关于如何编辑inputrc文件的信息,请参考 info bash 中的 Readline Init File 章节。info readline 也是一个很好的信息来源。

以下是一个通用的全局inputrc,以及解释各种选项作用的注释。请注意,注释不能与命令在同一行。使用以下命令创建该文件:

cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>

# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off

# Enable 8bit input
set meta-flag On
set input-meta On

# Turns off 8th bit stripping
set convert-meta Off

# Keep the 8th bit for display
set output-meta On

# none, visible or audible
set bell-style none

# All of the following map the escape sequence of the
# value contained inside the 1st argument to the
# readline specific functions

"\eOd": backward-word
"\eOc": forward-word

# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert

# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line

# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line

# End /etc/inputrc
EOF

7.9. Bash Shell 启动文件

Shell 程序 /bin/bash (以下简称 “shell”) 使用一系列启动文件来帮助创建运行环境。每个文件都有特定的用途,并且可能会以不同的方式影响登录和交互环境。/etc目录中的文件提供全局设置。如果主目录中存在等效文件,它可能会覆盖全局设置。

在成功登录后,使用 /bin/login 启动一个交互式登录 shell,并通过读取/etc/passwd文件来实现。交互式非登录 shell 在命令行启动(例如,[提示符]$/bin/bash)。非交互式 shell 通常在 shell 脚本运行时出现。它是非交互式的,因为它正在处理脚本,而不是等待用户在命令之间输入。

要了解更多信息,请参阅 info bash 中的 Bash Startup Files and Interactive Shells 章节。

文件/etc/profile~/.bash_profile在将 shell 作为交互式登录 shell 调用时读取。

以下的基本/etc/profile设置了一些本地语言支持所需的环境变量。正确设置它们可以实现:

  • 程序输出翻译成当地语言

  • 将字符正确分类为字母、数字和其他类别。这是 bash 在非英语环境中正确接受命令行中的非 ASCII 字符所必需的

  • 该国家/地区的正确字母排序

  • 合适的默认纸张尺寸

  • 货币、时间和日期值的正确格式

此脚本还设置了INPUTRC环境变量,使 Bash 和 Readline 使用之前创建的/etc/inputrc文件。

将下面的 [ll] 替换为所需语言的两位字母代码(例如,“en”),并将 [CC] 替换为相应国家/地区的两位字母代码(例如,“GB”)。[charmap] 应该替换为您选择的语言环境的规范字符映射。

可以通过运行以下命令获取 Glibc 支持的所有语言环境的列表:

locale -a

语言环境可以有许多同义词,例如,“ISO-8859-1” 也被称为 “iso8859-1” 和 “iso88591”。某些应用程序无法正确处理各种同义词,因此选择特定语言环境的规范名称是最安全的。要确定规范名称,请运行以下命令,其中 [locale name]locale -a 为您首选语言环境提供的输出(在我们的示例中为 “en_GB.iso88591”)。

LC_ALL=[locale name] locale charmap

对于 “en_GB.iso88591” 语言环境,上述命令将打印:

ISO-8859-1

这将导致最终的语言环境设置为 “en_GB.ISO-8859-1”。重要的是,在使用启发式方法找到的语言环境添加到 Bash 启动文件之前,对其进行测试。

LC_ALL=[locale name] locale country
LC_ALL=[locale name] locale language
LC_ALL=[locale name] locale charmap
LC_ALL=[locale name] locale int_curr_symbol
LC_ALL=[locale name] locale int_prefix

上面的命令应该打印国家和语言名称,语言环境使用的字符编码,当地货币以及在拨打电话号码之前拨打的用于进入该国家/地区的前缀。 如果上面的任何命令失败并显示类似于下面显示的消息,则表示您的语言环境要么未在第 6 章中安装,要么不受 Glibc 的默认安装支持。

locale: Cannot set LC_* to default locale: No such file or directory

如果发生这种情况,您应该使用 localedef 命令安装所需的语言环境,或考虑选择其他语言环境。以下说明假定 Glibc 没有此类错误消息。

LFS 之外的一些软件包也可能缺乏对您选择的语言环境的支持。一个例子是 X 库(X Window System 的一部分),它输出以下错误消息:

Warning: locale not supported by Xlib, locale set to C

有时可以通过删除语言环境规范的字符映射部分来解决此问题,只要这不会更改 Glibc 与语言环境关联的字符映射(可以通过在两个语言环境中运行 locale charmap 命令来检查)。例如,必须将 “de_DE.ISO-8859-15@euro” 更改为 “de_DE@euro”,才能使 Xlib 识别此语言环境。

如果语言环境名称不符合他们的期望,其他软件包也可能无法正常工作(但不一定会显示任何错误消息)。在这些情况下,调查其他 Linux 发行版如何支持您的语言环境可能会提供一些有用的信息。

确定正确的语言环境设置后,创建/etc/profile文件

cat > /etc/profile << "EOF"
# Begin /etc/profile

export LANG=[ll]_[CC].[charmap]
export INPUTRC=/etc/inputrc

# End /etc/profile
EOF

注意

C”(默认)和 “en_US”(推荐给美国英语用户)语言环境是不同的。

设置键盘布局、屏幕字体和与语言环境相关的环境变量是支持使用普通单字节编码和从左到右书写方向的语言环境所需的唯一国际化步骤。更复杂的情况(包括基于 UTF-8 的语言环境)需要额外的步骤和额外的补丁,因为许多应用程序在这些条件下往往无法正常工作。LFS 书籍中不包含这些步骤和补丁,LFS 尚不支持此类语言环境。

7.10. 配置 localnet 脚本

localnet 脚本的部分工作是设置系统的主机名。这需要在/etc/sysconfig/network文件中使用这些名称。

通过运行以下命令来创建/etc/sysconfig/network文件中配置,并通过运行以下命令输入主机名:

echo "HOSTNAME=[lfs]" > /etc/sysconfig/network

[lfs] 需要替换为分配给计算机的名称。 请勿在此处输入完全限定域名 (FQDN)。该信息将放在下一节的/etc/hosts文件中。

7.11. 创建 /etc/hosts 文件

如果要配置网卡,请确定将在/etc/hosts文件中使用的 IP 地址、FQDN 和可能的别名。 语法是:

            <IP address> myhost.example.org aliases

除非计算机对 Internet 可见(即,存在已注册的域和有效的已分配 IP 地址块 - 大多数用户没有此权限),否则请确保 IP 地址位于专用网络 IP 地址范围内。有效范围是:

    Class Networks
        A     10.0.0.0
        B     172.16.0.0 through 172.31.0.255
        C     192.168.0.0 through 192.168.255.255

有效的 IP 地址可以是 192.168.1.1。 此 IP 的有效 FQDN 可以是 www.linuxfromscratch.org(不推荐,因为这是一个有效的已注册域地址,可能会导致域名服务器问题)。

即使不使用网卡,仍然需要 FQDN。 这是某些程序正常运行所必需的。

通过运行以下命令来创建/etc/hosts通过运行

cat > /etc/hosts << "EOF"
# Begin /etc/hosts (network card version)

127.0.0.1 localhost
[192.168.1.1] [<HOSTNAME>.example.org] [HOSTNAME]

# End /etc/hosts (network card version)
EOF

对于特定用户或要求,需要更改 [192.168.1.1][<HOSTNAME>.example.org] 值(如果由网络/系统管理员分配了 IP 地址,并且该计算机将连接到现有网络)。

如果不配置网卡,请创建/etc/hosts通过运行

cat > /etc/hosts << "EOF"
# Begin /etc/hosts (no network card version)

127.0.0.1 [<HOSTNAME>.example.org] [HOSTNAME] localhost

# End /etc/hosts (no network card version)
EOF

7.12. 配置网络脚本

本节仅适用于要配置网卡的情况。

如果不使用网卡,则可能无需创建任何与网卡相关的配置文件。如果是这种情况,请删除所有运行级别目录(network)中的/etc/rc.d/rc*.d).

7.12.1. 创建网络接口配置文件

网络脚本启动和停止哪些接口取决于/etc/sysconfig/network-devices层次结构中的文件和目录。 此目录应包含要配置的每个接口的子目录,例如ifconfig.xyz,其中 “xyz” 是网络接口名称。在此目录中将是定义此接口属性的文件,例如其 IP 地址、子网掩码等。

以下命令创建一个示例ipv4文件,用于 eth0 设备。

cd /etc/sysconfig/network-devices &&
mkdir -v ifconfig.eth0 &&
cat > ifconfig.eth0/ipv4 << "EOF"
ONBOOT=yes
SERVICE=ipv4-static
IP=192.168.1.1
GATEWAY=192.168.1.2
PREFIX=24
BROADCAST=192.168.1.255
EOF

必须在每个文件中更改这些变量的值,以匹配正确的设置。如果ONBOOT变量设置为 “yes”,则网络脚本将在系统启动期间启动网络接口卡 (NIC)。如果设置为除 “yes” 之外的任何内容,则网络脚本将忽略 NIC 并且不会启动。

SERVICE变量定义用于获取 IP 地址的方法。 LFS-Bootscripts 软件包具有模块化的 IP 分配格式,并且在/etc/sysconfig/network-devices/services目录中创建其他文件允许其他 IP 分配方法。这通常用于动态主机配置协议 (DHCP),这在 BLFS 书籍中进行了介绍。

GATEWAY变量应包含默认网关 IP 地址(如果存在)。如果没有,则完全注释掉该变量。

PREFIX变量需要包含子网中使用的位数。IP 地址中的每个八位字节为 8 位。如果子网的子网掩码为 255.255.255.0,则它使用前三个八位字节(24 位)来指定网络号。如果子网掩码为 255.255.255.240,则它将使用前 28 位。长于 24 位的网络前缀通常由 DSL 和基于电缆的 Internet 服务提供商 (ISP) 使用。在此示例中 (PREFIX=24),子网掩码为 255.255.255.0。根据您的特定子网调整PREFIX变量。

7.12.2. 创建 /etc/resolv.conf 文件

如果系统要连接到 Internet,则需要一些域名服务 (DNS) 名称解析方法,才能将 Internet 域名解析为 IP 地址,反之亦然。最好通过将 DNS 服务器的 IP 地址(可从 ISP 或网络管理员处获得)放入/etc/resolv.conf来实现。通过运行以下命令创建文件:

cat > /etc/resolv.conf << "EOF"
# Begin /etc/resolv.conf

domain {[Your Domain Name]}
nameserver [IP address of your primary nameserver]
nameserver [IP address of your secondary nameserver]

# End /etc/resolv.conf
EOF

[名称服务器的 IP 地址] 替换为最适合设置的 DNS 的 IP 地址。 通常会有多个条目(要求有辅助服务器用于回退功能)。 如果您只需要或想要一个 DNS 服务器,请从文件中删除第二个 nameserver 行。 IP 地址也可以是本地网络上的路由器。

第 8 章. 使 LFS 系统可启动

8.1. 简介

现在是时候使 LFS 系统可启动了。 本章讨论创建fstab文件,为新的 LFS 系统构建内核,并安装 GRUB 引导加载程序,以便可以在启动时选择 LFS 系统进行引导。

8.2. 创建 /etc/fstab 文件

/etc/fstab文件被一些程序用来确定默认情况下文件系统应挂载在何处、按什么顺序挂载,以及哪些文件系统必须在挂载之前进行检查(以确保完整性)。创建一个新的文件系统表,如下所示

cat > /etc/fstab << "EOF"
# Begin /etc/fstab

# file system  mount-point  type   options         dump  fsck
#                                                        order

/dev/[xxx]     /            [fff]  defaults        1     1
/dev/[yyy]     swap         swap   pri=1           0     0
proc           /proc        proc   defaults        0     0
sysfs          /sys         sysfs  defaults        0     0
devpts         /dev/pts     devpts gid=4,mode=620  0     0
shm            /dev/shm     tmpfs  defaults        0     0
# End /etc/fstab
EOF

[xxx][yyy][fff] 替换为适合系统的值,例如:hda2, hda5ext2。有关此文件中六个字段的详细信息,请参阅 man 5 fstab

使用日志文件系统时,行尾的 1 1 应替换为 0 0,因为此类分区不需要转储或检查。

/dev/shm的挂载点tmpfs包含是为了允许启用 POSIX 共享内存。内核必须内置支持才能使其工作(有关此的更多信息将在下一节中介绍)。请注意,目前只有很少的软件使用 POSIX 共享内存。因此,请考虑/dev/shm挂载点是可选的。有关更多信息,请参阅Documentation/filesystems/tmpfs.txt在内核源代码树中。

还可以将其他行添加到/etc/fstab文件中。一个例子是 USB 设备的行

            usbfs        /proc/bus/usb usbfs   devgid=14,devmode=0660 0 0 

只有在内核中配置了“对主机端 USB 的支持”和“USB 设备文件系统”时,此选项才有效。如果“对主机端 USB 的支持”被编译为模块,则usbcore必须在/etc/sysconfig/modules.

8.3. Linux-2.6.11.12

Linux 软件包包含 Linux 内核。

预计构建时间: 4.20 SBU
所需磁盘空间: 181 MB
安装依赖于: Bash、Binutils、Coreutils、Findutils、GCC、Glibc、Grep、Gzip、Make、Modutils、Perl 和 Sed

8.3.1. 安装内核

构建内核涉及几个步骤:配置、编译和安装。阅读README内核源代码树中的文件,了解本书配置内核的替代方法。

运行以下命令准备编译

make mrproper

这可确保内核树绝对干净。内核团队建议在每次内核编译之前发出此命令。请勿依赖于解压后源代码树的干净程度。

如果在第 7.6 节,“配置 Linux 控制台”中,决定将键盘映射编译到内核中,请发出以下命令

loadkeys -m /usr/share/kbd/keymaps/[path to  keymap] > \
    drivers/char/defkeymap.c

例如,如果使用荷兰语键盘,请使用/usr/share/kbd/keymaps/i386/qwerty/nl.map.gz.

通过菜单驱动的界面配置内核。BLFS 在 http://www.linuxfromscratch.org/blfs/view/svn/longindex.html#kernel-config-index 上提供了一些关于 LFS 之外的软件包的特定内核配置要求的信息。

make menuconfig

或者,在某些情况下,make oldconfig 可能更合适。参见README文件获取更多信息。

如果需要,可以通过复制内核配置文件来跳过内核配置,.config,从主机系统(假设可用)到解包的linux-2.6.11.12目录。但是,我们不建议使用此选项。通常最好浏览所有配置菜单并从头开始创建内核配置。

注意

NPTL 要求使用 GCC-3.x 或更高版本(在本例中为 3.4.3)编译内核。不建议使用 GCC-2.95.x 编译内核,因为这会导致 Glibc 测试套件失败。通常,由于 LFS 不构建 GCC-2.95.x,因此不会提及这一点。不幸的是,内核文档已过时,仍然声称 GCC-2.95.3 是推荐的编译器。

编译内核镜像和模块

make

如果使用内核模块,则可能需要/etc/modprobe.conf文件。有关模块和内核配置的信息位于linux-2.6.11.12/Documentation目录中的内核文档中。另外,modprobe.conf(5)可能也很有趣。

在阅读与内核模块相关的其他文档时要非常小心,因为它通常仅适用于 2.4.x 内核。据我们所知,没有记录特定于 Hotplug 和 Udev 的内核配置问题。问题在于,只有在 Hotplug 或用户编写的脚本将相应模块插入内核时,Udev 才会创建设备节点,并且并非所有模块都可以被 Hotplug 检测到。请注意,/etc/modprobe.conf文件中的以下语句不适用于 Udev

alias char-major-XXX some-module

由于 Hotplug、Udev 和模块的复杂性,我们强烈建议从完全非模块化的内核配置开始,尤其是在第一次使用 Udev 时。

如果内核配置使用模块,则安装模块

make modules_install

内核编译完成后,需要执行其他步骤才能完成安装。一些文件需要复制到/boot目录中。

内核镜像的路径可能会因使用的平台而异。以下命令假设使用 x86 架构

cp -v arch/i386/boot/bzImage /boot/lfskernel-2.6.11.12

System.map是内核的符号文件。它映射了内核 API 中每个函数的函数入口点,以及正在运行的内核的内核数据结构的地址。发出以下命令以安装映射文件

cp -v System.map /boot/System.map-2.6.11.12

内核配置文件.config由上面的 make menuconfig 步骤生成,包含刚刚编译的内核的所有配置选项。保留此文件以供将来参考是个好主意

cp -v .config /boot/config-2.6.11.12

重要的是要注意,内核源代码目录中的文件不归 root 所有。每当一个软件包以用户 root 的身份解包时(就像我们在 chroot 中所做的那样),这些文件的用户和组 ID 都是它们在打包者计算机上的 ID。对于要安装的任何其他软件包,这通常不是问题,因为源代码树在安装后会被删除。但是,Linux 源代码树通常会保留很长时间。因此,打包者使用的任何用户 ID 都有可能分配给机器上的某个人。然后,该人将具有对内核源代码的写入访问权限。

如果要保留内核源代码树,请对linux-2.6.11.12目录运行 chown -R 0:0,以确保所有文件都归用户 root 所有。

警告

一些内核文档建议创建一个从/usr/src/linux指向内核源代码目录的符号链接。这特定于 2.6 系列之前的内核,并且绝不能在 LFS 系统上创建,因为它可能会导致您希望在基本 LFS 系统完成后构建的软件包出现问题。

此外,系统include目录中的标头应该始终是 Glibc 编译所依据的标头,即来自 Linux-Libc-Headers 软件包的标头,因此绝不应该被内核标头替换。

8.3.2. Linux 的内容

已安装的文件: config-2.6.11.12、lfskernel-2.6.11.12 和 System.map-2.6.11.12

简短描述

config-2.6.11.12

包含内核的所有配置选择

lfskernel-2.6.11.12

Linux 系统的引擎。打开计算机时,内核是操作系统加载的第一部分。它检测并初始化计算机硬件的所有组件,然后将这些组件作为文件树提供给软件,并将单个 CPU 变成能够同时运行多个程序的任务处理机器

System.map-2.6.11.12

地址和符号的列表;它映射了内核中所有函数和数据结构的入口点和地址

8.4. 使 LFS 系统可引导

您闪亮的新 LFS 系统几乎完成。最后要做的事情之一是确保系统可以正确引导。以下说明仅适用于 IA-32 架构的计算机,即主流 PC。有关其他架构的“引导加载”的信息应可在这些架构的常用资源特定位置找到。

引导加载可能是一个复杂的领域,因此需要一些警告。熟悉当前的引导加载程序以及需要可引导的硬盘驱动器上的任何其他操作系统。确保准备好紧急引导磁盘,以便在计算机变得无法使用(无法引导)时“拯救”计算机。

之前,我们编译并安装了 GRUB 引导加载程序软件,以准备此步骤。该过程涉及将一些特殊的 GRUB 文件写入硬盘驱动器上的特定位置。我们强烈建议创建一个 GRUB 引导软盘作为备份。插入空白软盘并运行以下命令

dd if=/boot/grub/stage1 of=/dev/fd0 bs=512 count=1
dd if=/boot/grub/stage2 of=/dev/fd0 bs=512 seek=1

取出软盘并将其存放在安全的地方。现在,运行 grub shell

grub

GRUB 使用自己的驱动器和分区命名结构,格式为 (hdn,m),其中 n 是硬盘驱动器号,m 是分区号,两者都从零开始。例如,分区hda1对于 GRUB 来说是 (hd0,0),而hdb3(hd1,2)。与 Linux 相比,GRUB 不认为 CD-ROM 驱动器是硬盘驱动器。例如,如果使用 CD 在hdb上,并在hdc上有第二个硬盘驱动器,则第二个硬盘驱动器仍然是 (hd1)

使用以上信息,确定根分区(或引导分区,如果使用单独的分区)的适当指示符。对于以下示例,假设根分区(或单独的引导分区)是hda4.

告诉 GRUB 在哪里搜索其stage{1,2}文件。可以在任何地方使用 Tab 键使 GRUB 显示替代项

root (hd0,3)

警告

以下命令将会覆盖当前的引导加载器。 如果您不希望这样做,例如,如果使用第三方引导管理器来管理主引导记录(MBR),请不要运行该命令。 在这种情况下,将GRUB安装到LFS分区的“引导扇区”中更有意义。 在这种情况下,接下来的命令将变为setup (hd0,3)

告诉GRUB将其自身安装到hda:

setup (hd0)

如果一切顺利,GRUB将报告在/boot/grub中找到它的文件。 这就是全部了。 退出grub shell。

quit

创建一个“菜单列表”文件,用于定义GRUB的引导菜单

cat > /boot/grub/menu.lst << "EOF"
# Begin /boot/grub/menu.lst

# By default boot the first menu entry.
default 0

# Allow 30 seconds before booting the default.
timeout 30

# Use prettier colors.
color green/black light-green/black

# The first entry is for LFS.
title LFS 6.1.1
root (hd0,3)
kernel /boot/lfskernel-2.6.11.12 root=/dev/hda4
EOF

如果需要,为宿主机发行版添加一个条目。 它可能看起来像这样

cat >> /boot/grub/menu.lst << "EOF"
title Red Hat
root (hd0,2)
kernel /boot/kernel-2.6.5 root=/dev/hda3
initrd /boot/initrd-2.6.5
EOF

如果双启动Windows,以下条目将允许启动它

cat >> /boot/grub/menu.lst << "EOF"
title Windows
rootnoverify (hd0,0)
chainloader +1
EOF

如果info grub没有提供所有必要的材料,有关GRUB的更多信息位于其网站:https://gnu.ac.cn/software/grub/

FHS 规定GRUB的menu.lst文件应该被符号链接到/etc/grub/menu.lst。 为了满足此要求,请执行以下命令

mkdir -v /etc/grub &&
ln -sv /boot/grub/menu.lst /etc/grub

第 9. 章 结束

9.1. 结束

做得好! 全新的 LFS 系统已经安装完成!祝贺您成功构建了全新的定制 Linux 系统。

创建一个/etc/lfs-release文件可能是一个好主意。 通过拥有此文件,您可以(如果您需要在某个时候寻求帮助,我们也一样)非常容易地找出系统上安装的 LFS 版本。 通过运行以下命令来创建此文件

echo 6.1.1 > /etc/lfs-release

9.2. 被计数

既然您已经完成了本书,您想被视为 LFS 用户吗? 前往http://www.linuxfromscratch.org/cgi-bin/lfscounter.cgi,输入您的姓名和您使用的第一个 LFS 版本,注册成为 LFS 用户。

现在让我们重新启动进入LFS。

9.3. 重启系统

现在所有的软件都已安装,是时候重新启动您的计算机了。 但是,您应该意识到一些事情。 您在本书中创建的系统非常基本,并且很可能没有您能够继续前进的功能。 通过在当前 chroot 环境中安装 BLFS 书中的一些额外软件包,您可以让自己处于更好的位置,以便在重新启动到新的 LFS 安装后继续前进。 安装文本模式网络浏览器(例如 Lynx),您可以轻松地在一个虚拟终端中查看 BLFS 书籍,同时在另一个虚拟终端中构建软件包。 GPM 软件包还允许您在虚拟终端中执行复制/粘贴操作。 最后,如果您处于静态 IP 配置无法满足您的网络要求的情况,那么此时安装 Dhcpcd 或 PPP 等软件包也可能很有用。

现在我们已经说了这些,让我们开始第一次启动我们闪亮的新 LFS 安装! 首先退出 chroot 环境

logout

然后卸载虚拟文件系统

umount -v $LFS/dev/pts
umount -v $LFS/dev/shm
umount -v $LFS/dev
umount -v $LFS/proc
umount -v $LFS/sys

卸载LFS文件系统本身

umount -v $LFS

如果创建了多个分区,请在卸载主分区之前卸载其他分区,如下所示

umount -v $LFS/usr
umount -v $LFS/home
umount -v $LFS

现在,使用以下命令重新启动系统

shutdown -r now

假设 GRUB 引导加载程序已按照前面所述设置,则菜单设置为自动启动 LFS 6.1.1

重新启动完成后,LFS 系统即可使用,并且可以添加更多软件以满足您的需求。

9.4. 现在怎么办?

感谢您阅读这本 LFS 书。 我们希望您发现这本书对您有所帮助,并且对系统创建过程有了更多的了解。

既然 LFS 系统已经安装,您可能想知道“接下来做什么?” 为了回答这个问题,我们为您编制了一份资源列表。

  • 维护

    定期报告所有软件的错误和安全公告。 由于 LFS 系统是从源代码编译的,因此您有责任及时了解此类报告。 有几个在线资源可以跟踪此类报告,其中一些如下所示

    • Freshmeat.net (http://freshmeat.net/)

      Freshmeat 可以通过电子邮件通知您系统上安装的软件包的新版本。

    • CERT(计算机紧急情况响应小组)

      CERT 有一个邮件列表,用于发布有关各种操作系统和应用程序的安全警报。 订阅信息可在 http://www.us-cert.gov/cas/signup.html 获取。

    • Bugtraq

      Bugtraq 是一个完全公开的计算机安全邮件列表。 它发布新发现的安全问题,偶尔还会发布潜在的修复程序。 订阅信息可在 http://www.securityfocus.com/archive 获取。

  • 超越 Linux From Scratch

    超越 Linux From Scratch 一书涵盖了 LFS 书籍范围之外的各种软件的安装过程。 BLFS 项目位于 http://www.linuxfromscratch.org/blfs/

  • LFS 提示

    LFS 提示是 LFS 社区志愿者提交的教育文档集合。 这些提示可在 http://www.linuxfromscratch.org/hints/list.html 获取。

  • 邮件列表

    如果您需要帮助、想要了解最新动态、想要为项目做贡献等等,您可以订阅几个 LFS 邮件列表。 有关更多信息,请参阅第 1 章 - 邮件列表

  • Linux 文档项目

    Linux 文档项目 (TLDP) 的目标是协作处理所有 Linux 文档问题。 TLDP 包含大量 HOWTO、指南和手册页。 它位于 http://www.tldp.org/

第 IV 部分. 附录

附录 A. 缩写和术语

ABI

应用程序二进制接口

ALFS

自动 Linux From Scratch

ALSA

高级 Linux 声音架构

API

应用程序编程接口

ASCII

美国信息交换标准代码

BIOS

基本输入/输出系统

BLFS

超越 Linux From Scratch

BSD

伯克利软件发行版

chroot

更改根目录

CMOS

互补金属氧化物半导体

COS

服务类别

CPU

中央处理器

CRC

循环冗余校验

CVS

并发版本系统

DHCP

动态主机配置协议

DNS

域名服务

EGA

增强图形适配器

ELF

可执行和可链接格式

EOF

文件结束

EQN

方程式

EVMS

企业卷管理系统

ext2

第二扩展文件系统

FAQ

常见问题解答

FHS

文件系统层次结构标准

FIFO

先进先出

FQDN

完全限定域名

FTP

文件传输协议

GB

吉字节

GCC

GNU 编译器集合

GID

组标识符

GMT

格林威治标准时间

GPG

GNU Privacy Guard

HTML

超文本标记语言

IDE

集成驱动器电子设备

IEEE

电气与电子工程师协会

IO

输入/输出

IP

互联网协议

IPC

进程间通信

IRC

互联网中继聊天

ISO

国际标准化组织

ISP

互联网服务提供商

KB

千字节

LED

发光二极管

LFS

Linux From Scratch(从零开始构建Linux)

LSB

Linux 标准库

MB

兆字节

MBR

主引导记录

MD5

消息摘要 5

NIC

网络接口卡

NLS

本机语言支持

NNTP

网络新闻传输协议

NPTL

本机 POSIX 线程库

OSS

开放声音系统

PCH

预编译标头

PCRE

Perl 兼容正则表达式

PID

进程标识符

PLFS

纯 Linux From Scratch

PTY

伪终端

QA

质量保证

QOS

服务质量

RAM

随机存取存储器

RPC

远程过程调用

RTC

实时时钟

SBU

标准构建单元

SCO

圣克鲁斯运营公司

SGR

选择图形呈现

SHA1

安全散列算法 1

SMP

对称多处理器

TLDP

Linux 文档项目

TFTP

简单文件传输协议

TLS

线程本地存储

UID

用户标识符

umask

用户文件创建掩码

USB

通用串行总线

UTC

协调世界时

UUID

通用唯一标识符

VC

虚拟控制台

VGA

视频图形阵列

VT

虚拟终端

附录 B. 致谢

我们要感谢以下人员和组织对 Linux From Scratch 项目的贡献。

  • Gerard Beekmans <gerard AT linuxfromscratch D0T org> – LFS 创建者, LFS 项目负责人

  • Matthew Burgess <matthew AT linuxfromscratch D0T org> – LFS 项目负责人, LFS 技术作家/编辑, LFS 发布经理

  • Archaic <archaic AT linuxfromscratch D0T org> – LFS 技术文档编写者/编辑,HLFS 项目领导者,BLFS 编辑,提示和补丁项目维护者

  • Nathan Coulson <nathan AT linuxfromscratch D0T org> – LFS-Bootscripts 维护者

  • Bruce Dubbs <bdubbs AT linuxfromscratch D0T org> – BLFS 项目领导者

  • Manuel Canales Esparcia <manuel AT linuxfromscratch D0T org> – LFS/BLFS/HLFS XML 和 XSL 维护者

  • Jim Gifford <jim AT linuxfromscratch D0T org> – LFS 技术文档编写者,补丁项目领导者

  • Jeremy Huntwork <jhuntwork AT linuxfromscratch D0T org> – LFS 技术文档编写者,LFS LiveCD 维护者,ALFS 项目领导者

  • Anderson Lizardo <lizardo AT linuxfromscratch D0T org> – 网站后端脚本维护者

  • Ryan Oliver <ryan AT linuxfromscratch D0T org> – LFS 工具链维护者

  • James Robertson <jwrober AT linuxfromscratch D0T org> – Bugzilla 维护者

  • Tushar Teredesai <tushar AT linuxfromscratch D0T org> – BLFS 书籍编辑,提示和补丁项目领导者

  • 无数 LFS 和 BLFS 邮件列表中的其他人员,他们通过提供建议、测试书籍以及提交错误报告、说明和安装各种软件包的经验,为本书的完成做出了贡献。

翻译者

镜像站点维护者

北美镜像

  • Scott Kveton <scott AT osuosl D0T org> – lfs.oregonstate.edu 镜像

  • Mikhail Pastukhov <miha AT xuy D0T biz> – lfs.130th.net 镜像

  • William Astle <lost AT l-w D0T net> – ca.linuxfromscratch.org 镜像

  • Jeremy Polen <jpolen AT rackspace D0T com> – us2.linuxfromscratch.org 镜像

  • Tim Jackson <tim AT idge D0T net> – linuxfromscratch.idge.net 镜像

  • Jeremy Utley <jeremy AT linux-phreak D0T net> – lfs.linux-phreak.net 镜像

南美镜像

欧洲镜像

  • Barna Koczka <barna AT siker D0T hu> – hu.linuxfromscratch.org 镜像

  • UK Mirror Service – linuxfromscratch.mirror.ac.uk 镜像

  • Martin Voss <Martin D0T Voss AT ada D0T de> – lfs.linux-matrix.net 镜像

  • Guido Passet <guido AT primerelay D0T net> – nl.linuxfromscratch.org 镜像

  • Bastiaan Jacques <baafie AT planet D0T nl> – lfs.pagefault.net 镜像

  • Roel Neefs <lfs-mirror AT linuxfromscratch D0T rave D0T org> – linuxfromscratch.rave.org 镜像

  • Justin Knierim <justin AT jrknierim D0T de> – www.lfs-matrix.de 镜像

  • Stephan Brendel <stevie AT stevie20 D0T de> – lfs.netservice-neuss.de 镜像

  • Antonin Sprinzl <Antonin D0T Sprinzl AT tuwien D0T ac D0T at> – at.linuxfromscratch.org 镜像

  • Fredrik Danerklint <fredan-lfs AT fredan D0T org> – se.linuxfromscratch.org 镜像

  • Parisian sysadmins <archive AT doc D0T cs D0T univ-paris8 D0T fr> – www2.fr.linuxfromscratch.org 镜像

  • Alexander Velin <velin AT zadnik D0T org> – bg.linuxfromscratch.org 镜像

  • Dirk Webster <dirk AT securewebservices D0T co D0T uk> – lfs.securewebservices.co.uk 镜像

  • Thomas Skyt <thomas AT sofagang D0T dk> – dk.linuxfromscratch.org 镜像

  • Simon Nicoll <sime AT dot-sime D0T com> – uk.linuxfromscratch.org 镜像

亚洲镜像

  • Pui Yong <pyng AT spam D0T averse D0T net> – sg.linuxfromscratch.org 镜像

  • Stuart Harris <stuart AT althalus D0T me D0T uk> – lfs.mirror.intermedia.com.sg 镜像

澳大利亚镜像

  • Jason Andrade <jason AT dstc D0T edu D0T au> – au.linuxfromscratch.org 镜像

前项目团队成员

  • Christine Barczak <theladyskye AT linuxfromscratch D0T org> – LFS 书籍编辑

  • Timothy Bauscher

  • Robert Briggs

  • Ian Chilton

  • Jeroen Coumans <jeroen AT linuxfromscratch D0T org> – 网站开发者,FAQ 维护者

  • Alex Groenewoud – LFS 技术文档编写者

  • Marc Heerdink

  • Mark Hymers

  • Seth W. Klein – FAQ 维护者

  • Nicholas Leippe <nicholas AT linuxfromscratch D0T org> – Wiki 维护者

  • Simon Perreault

  • Scot Mc Pherson <scot AT linuxfromscratch D0T org> – LFS NNTP 网关维护者

  • Alexander Patrakov <semzx AT newmail D0T ru> – LFS 技术文档编写者

  • Greg Schafer <gschafer AT zip D0T com D0T au> – LFS 技术文档编写者

  • Jesse Tie-Ten-Quee – LFS 技术文档编写者

  • Jeremy Utley <jeremy AT linuxfromscratch D0T org> – LFS 技术文档编写者,Bugzilla 维护者,LFS-Bootscripts 维护者

  • Zack Winkles <zwinkles AT gmail D0T com> – LFS 技术文档编写者

非常感谢我们的捐助者

  • Dean Benson <dean AT vipersoft D0T co D0T uk> 为多次捐款

  • Hagen Herrschaft <hrx AT hrxnet D0T de> 捐赠了一个 2.2 GHz P4 系统,现在以 Lorien 的名义运行

  • VA Software 代表 Linux.com 捐赠了一台 VA Linux 420(之前的 StartX SP2)工作站

  • Mark Stone 捐赠了 Belgarath,linuxfromscratch.org 服务器

索引

软件包

程序

其他