Skip to the content.

8.Installing basic system software


8.1 Introduction


在本章中,我们将真正开始构造 LFS 系统。

软件的安装过程是简单直接的。尽管很多时候可以把安装说明写得更短、更通用,我们还是选择为每个包提供完整的安装流程,以尽量减小出错的可能。学习 Linux 系统工作原理的关键就是要知道每个包的作用,以及您 (或者系统) 为什么需要它。

我们不推荐在编译中使用自定义优化。自定义优化可以使程序跑得稍微快一点,但也可能在编译或运行的过程中带来问题。如果一个软件包在打开自定义优化时无法编译,试着关闭优化再编译它。即使一个软件包在使用自定义优化时可以编译,由于源代码和编译工具的复杂相互作用,仍然存在编译不正确的风险。另外请注意,除本书明确说明外,设定 -march-mtune 是未经验证的。它们可能在工具链软件包 (Binutils、GCC 和 Glibc) 中引发问题。自定义编译优化带来的微小性能增益往往不值得冒上述风险。我们建议第一次构建 LFS 的读者不要使用自定义的优化选项。

另一方面,我们保持软件包默认配置启用的优化选项。另外,我们有时显式启用软件包提供但未作为默认的优化配置。软件包维护者已经测试了这些配置并认为它们是安全的,因此它们不太可能导致构建失败。通常来说,默认配置已经启用 -O2-O3,因此在不使用任何自定义优化的情况下,得到的系统仍然会运行得很快,同时保持稳定。

在提供安装过程的说明之前,每个页面都提供了软件包的基本信息,包括其内容的简要描述,以及构建过程大概需要的时间和磁盘空间。在安装指令之后,有一个包含该软件包提供的所有程序和库的清单 (以及对它们的简要描述)。

注意

对于拥有可用的测试套件的软件包,第8章中给出的 SBU 值和需要的磁盘空间包含了运行测试套件需要的时间和磁盘空间。如无特殊说明,SBU 值根据仅使用四个 CPU 核心 (-j4) 进行操作时测得的时间计算。

8.1.1 关于库

一般来说,LFS 作者不鼓励构建和安装静态库。在现代 Linux 系统中,多数静态库已经失去存在的意义。另外,将静态库链接到程序中可能是有害的。如果需要更新这个库以解决安全问题,所有使用该静态库的程序都要重新链接到新版本的库。程序对静态库的使用并不总是显然的,甚至可能无法查明有哪些程序需要重新链接 (以及如何重新链接)。

本章给出的安装过程删除或者禁止安装多数静态库。一般来说,传递 --disable-static 选项给 configure 即可达成目的。然而,某些情况下需要使用其他手段。在极个别情况下,特别是对于 Glibc 和 GCC,静态库在一般软件包的构建过程中仍然很关键,就不能禁用静态库。

关于库的更详细讨论,可以参阅 BLFS 手册中的 Libraries: Static or shared? 一节。

8.2 Package Management


经常有人请求将软件包管理加入 LFS 手册。包管理器跟踪文件的安装过程,简化移除或升级软件包的工作。一个好的包管理器还会特殊处理配置文件,以在重新安装或升级软件包时保留用户配置。在您开始想入非非前,不 —— 本节不会讨论或者推荐任何一个特定的包管理器。本节对软件包管理的流行技术及其工作原理进行综述。对您来说,完美的包管理器可能是其中的某个技术,也可能是几个技术的结合。本节还会简要介绍在升级软件包时可能遇到的问题。

LFS 或 BLFS 不介绍任何包管理器的原因包括:

已经有人写了一些关于软件包管理这一主题的短文。您可以访问 Hints Project 并看一看是否有符合您的需求的方案。

8.2.1 升级问题

使用包管理器可以在软件包新版本发布后容易地完成升级。一般来说,使用 LFS 或者 BLFS 手册给出的构建方法即可升级软件包。下面是您在升级时必须注意的重点,特别是升级正在运行的系统时。

grep -l  -e 'libfoo.*deleted' /proc/*/maps |
   tr -cd 0-9\\n | xargs -r ps u
如果正在使用 OpenSSH 访问系统,且它链接到了被更新的库,则需要重启 sshd 服务,登出并重新登录,然后再次运行上述 ps 命令,确认没有进程使用被删除的库文件。

8.2.2 软件包管理技术

以下是几种常见的软件包管理方案。在决定使用某种包管理器前,请研读这些方案,特别是要了解每种方案的不足。

8.2.2.1 这都在我的脑袋里!

没错,这是一种包管理技术。有些人不需要包管理器,因为他们十分了解软件包,知道每个软件包安装了什么文件。有的用户则计划每次有软件包发生变动时就重新构建系统,所以不需要管理软件包。

8.2.2.2 安装到独立目录

这是一种最简单的软件包管理方式,它不需要控制软件包安装的专用程序。每个软件包都被安装在单独的目录中。例如,软件包 foo-1.1 将会被安装在 /usr/pkg/foo-1.1,然后创建一个符号链接 /usr/pkg/foo 指向 /usr/pkg/foo-1.1。在安装新版本 foo-1.2 的时候,把它安装到 /usr/pkg/foo-1.2,然后把之前的符号链接替换为指向新版本的符号链接。

PATH、LD_LIBRARY_PATH、MANPATH、INFOPATHCPPFLAGS 等环境变量需要被扩充,以包含 /usr/pkg/foo。一旦安装了比较多的软件包,这种模式就会变得无法管理。

8.2.2.3 符号链接风格的软件包管理

这是前一种软件包管理技术的变种。和前一种方式一样,将各个软件包同样安装在独立的目录中。但不是使用软件包的名称建立符号链接,而是将软件包中的每个文件符号链接到 /usr 目录树中对应的位置。这样就不需要修改环境变量。虽然这些符号链接可以由用户自己创建,但已经有许多包管理器能够自动化这一过程。一些流行的包管理器如 Stow、Epkg、Graft 和 Depot 使用这种管理方式。

需要欺骗安装脚本,使得软件包认为它处于 /usr 中,尽管它实际上被安装在 /usr/pkg 目录结构中。这种安装过程往往是超出常规的。例如,考虑安装软件包 libfoo-1.1。下面的方法可能不能正确安装该软件包:

./configure --prefix=/usr/pkg/libfoo/1.1
make
make install

尽管安装过程本身可以顺利进行,但依赖于它的软件包可能不会像您期望的那样链接 libfoo 库。如果要编译一个依赖于 libfoo 的软件包,您可能发现它链接到了 /usr/pkg/libfoo/1.1/lib/libfoo.so.1 而不是您期望的 /usr/lib/libfoo.so.1。正确的做法是使用 DESTDIR 环境变量转移安装位置。就像下面这样做:

./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install

多数软件包可以这样安装,但有些不能。对于那些不兼容的软件包,您要么亲自动手安装,要么更简单地把一些出问题的软件包安装在 /opt 中。

8.2.2.4 基于时间戳的方案

在这种方案中,安装一个软件包之前,创建一个时间戳文件。在安装后,用一行简单的 find 命令,加上正确的参数,就能生成安装日志,包含在时间戳文件创建以后安装的所有文件。有一个采用这个方案的包管理器叫做 install-log。

尽管这种方式很简单,但它有两个缺点。如果在安装过程中,某些文件没有以当前时间作为时间戳安装,它们就不能被包管理器跟踪。另外,只有每次只安装一个软件包时才能使用这种技术。如果在两个控制台中同时安装两个不同的软件包,它们的安装日志就不可靠了。

8.2.2.5 追踪安装脚本

在这种方案中,安装脚本执行的命令被记录下来。有两种技巧可以用于记录:

在安装前设置 LD_PRELOAD 环境变量,将其指向一个库以在安装过程中预加载它。在安装过程中,这个库附加在 cp、install、mv 等可执行文件上,跟踪修改文件系统的系统调用。如果要使用这种方法,所有需要跟踪的可执行文件必须是动态链接的,且没有设定 suid 和 sgid 位。预加载动态库可能在安装过程中导致不希望的副作用。因此,最好在实际使用前进行一些测试,以确保包管理器不会造成破坏,并且记录了所有应该记录的文件。

第二种技巧是使用 strace,它能够记录安装脚本执行过程中的所有系统调用。

8.2.2.6 创建软件包档案

在这种方案中,软件包被伪装安装到一个独立的目录树中,就像软链接风格的软件包管理那样。在安装后,使用被安装的文件创建一个软件包档案。它可以被用来在本地机器甚至其他机器上安装该软件包。

大多数商业发行版的包管理器采用这种策略。例如 RPM (值得一提的是,它被 Linux Standard Base 规则所要求)、pkg-utils、Debian 的 apt,以及 Gentoo 的 Portage 系统等。LFS Hint 中的一篇短文描述了如何为 LFS 系统适用这种管理方式:https://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt

创建包含依赖关系信息的软件包文件十分复杂,超出了 LFS 的范畴。

Slackware 使用一个基于 tar 的系统创建软件包档案。和更复杂的包管理器不同,该系统有意地没有涉及软件包依赖关系。如果想了解 Slackware 包管理器的详细信息,阅读 https://www.slackbook.org/html/package-management.html

8.2.2.7 基于用户的软件包管理

这种架构是 LFS 特有的,由 Matthias Benkmann 提出,可以在 Hints Project 查阅。在该架构中,每个软件包都由一个单独的用户安装到标准位置。只要检查文件所有者,就能找出属于一个软件包的所有文件。它的优缺点十分复杂,无法在本节讨论。如果想详细了解,请访问 https://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt 阅读。

8.2.3 在多个系统上部署 LFS

LFS 系统的一项优势是,没有依赖于磁盘系统中文件位置的文件。将构建好的 LFS 系统复制到另一台具有相同硬件架构的计算机很简单,只要用 tar 命令把包含根目录的 LFS 分区打包 (未压缩的情况下,一个基本的 LFS 系统需要 900 MB),然后通过网络或者 CD-ROM 复制到新的系统上,再展开即可。之后,个别配置文件需要修改。可能需要更新的配置文件有:/etc/hosts,/etc/fstab,/etc/passwd,/etc/group,/etc/shadow,/etc/ld.so.conf,/etc/sysconfig/rc.site,/etc/sysconfig/network,以及 /etc/sysconfig/ifconfig.eth0

由于系统硬件和内核配置的区别,可能需要为新系统重新配置并构建内核。

注意

有一些报告反映称,在架构相近但不完全一致的计算机之间拷贝 LFS 系统时出现问题。例如,Intel 系统使用的指令集和 AMD 处理器不完全相同,且较新的处理器可能提供旧处理器没有的指令。

最后,按照第 10.4 节 “使用 GRUB 设定引导过程”中的说明,为新系统配置引导加载器。

8.3 Man-pages-6.03


Man-pages 软件包包含 2,400 多个 man 页面。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 32 MB

8.3.1 安装 Man-pages

执行以下命令安装 Man-pages:

make prefix=/usr install

8.3.2 Man-pages 的内容

安装的文件: 若干 man 页面

简要描述

man 页面 描述 C 语言函数、重要的设备文件以及主要配置文件

8.4 Iana-Etc-20230202


Iana-Etc 软件包包含网络服务和协议的数据。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 4.8 MB

8.4.1 安装 Iana-Etc

对于该软件包,我们只需要将文件复制到正确的位置:

cp services protocols /etc

8.4.2 Iana-Etc 的内容

安装的文件: /etc/protocols 和 /etc/services

简要描述

/etc/protocols      描述 TCP/IP 子系统中可用的各种 DARPA Internet 协议

/etc/services       提供 Internet 服务的可读文本名称、底层的分配端口号以及 协议类型之间的对应关系

8.5 Glibc-2.37


Glibc 软件包包含主要的 C 语言库。它提供用于分配内存、检索目录、打开和关闭文件、读写文件、字符串处理、模式匹配、算术等用途的基本子程序。

估计构建时间: 11 SBU

需要硬盘空间: 2.9 GB

8.5.1 安装 Glibc

一些 Glibc 程序使用与 FHS 不兼容的 /var/db 目录存放它们的运行时数据。应用一个补丁,使得这些程序在 FHS 兼容的位置存放运行时数据:

patch -Np1 -i ../glibc-2.37-fhs-1.patch

修复上游发现的安全问题:

sed '/width -=/s/workend - string/number_length/' \
    -i stdio-common/vfprintf-process-arg.c

Glibc 文档推荐在一个新建的目录中构建 Glibc:

mkdir -v build
cd       build

确保将 ldconfig 和 sln 工具安装到 /usr/sbin 目录中:

echo "rootsbindir=/usr/sbin" > configparms

准备编译 Glibc:

../configure --prefix=/usr                            \
             --disable-werror                         \
             --enable-kernel=3.2                      \
             --enable-stack-protector=strong          \
             --with-headers=/usr/include              \
             libc_cv_slibdir=/usr/lib

配置选项的含义:

–disable-werror

该选项禁用 GCC 的 -Werror 选项。这对于运行测试套件来说是必须的。

–enable-kernel=3.2

该选项告诉构建系统 Glibc 可能被与 3.2 这样老版本的内核一起使用。这样,Glibc 会生成代码,在后续版本引入的系统调用不可用时绕过它们。

–enable-stack-protector=strong

该选项通过加入额外代码,对栈溢出攻击等导致的缓冲区溢出进行检查,以提高系统安全性。

–with-headers=/usr/include

该选项指定构建系统搜索内核 API 头文件的位置。

libc_cv_slibdir=/usr/lib

这个变量纠正库文件安装位置。我们不希望使用 lib64 目录。

编译该软件包:

make

重要: 我们认为,在本节中,Glibc 的测试套件十分关键。在任何情况下都不要跳过它。

通常来说,可能会有极少数测试不能通过,下面列出的失败结果一般可以安全地忽略。执行以下命令进行测试:

make check

您可能看到一些失败结果。Glibc 的测试套件和宿主系统之间有某种依赖关系。在 5000 多项测试中,如果只有几项测试失败,一般可以忽略它们。下面列出在一些版本的 LFS 上发现的,最常见的问题:

在安装 Glibc 时,它会抱怨文件 /etc/ld.so.conf 不存在。尽管这是一条无害的消息,执行以下命令即可防止这个警告:

touch /etc/ld.so.conf

修改 Makefile,跳过一个在 LFS 的不完整环境中会失败的完整性检查:

sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile

安装该软件包:

make install

改正 ldd 脚本中硬编码的可执行文件加载器路径:

sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/ldd

安装 nscd 的配置文件和运行时目录:

cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd

下面,安装一些 locale,它们可以使得系统用不同语言响应用户请求。这些 locale 都不是必须的,但是如果缺少了它们中的某些,在运行一些软件包的测试套件时,可能跳过重要的测试。

可以用 localedef 程序安装单独的 locale。例如,下面的第二个 localedef 命令将 /usr/share/i18n/locales/cs_CZ 中的字符集无关 locale 定义和 /usr/share/i18n/charmaps/UTF-8.gz 中的字符映射定义组合起来,并附加到 /usr/lib/locale/locale-archive 文件。以下命令将会安装能够覆盖测试所需的最小 locale 集合:

mkdir -pv /usr/lib/locale
localedef -i POSIX -f UTF-8 C.UTF-8 2> /dev/null || true
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i el_GR -f ISO-8859-7 el_GR
localedef -i en_GB -f ISO-8859-1 en_GB
localedef -i en_GB -f UTF-8 en_GB.UTF-8
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 en_US -f UTF-8 en_US.UTF-8
localedef -i es_ES -f ISO-8859-15 es_ES@euro
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 fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i is_IS -f ISO-8859-1 is_IS
localedef -i is_IS -f UTF-8 is_IS.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f ISO-8859-15 it_IT@euro
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
localedef -i nl_NL@euro -f ISO-8859-15 nl_NL@euro
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i se_NO -f UTF-8 se_NO.UTF-8
localedef -i ta_IN -f UTF-8 ta_IN.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
localedef -i zh_HK -f BIG5-HKSCS zh_HK.BIG5-HKSCS
localedef -i zh_TW -f UTF-8 zh_TW.UTF-8

另外,安装适合您自己国家、语言和字符集的 locale。

或者,也可以执行这个需要很长时间的命令,直接安装 glibc-2.37/localedata/SUPPORTED 中列出的所有 locale (包括上面列出的所有 locale,以及其他很多):

make localedata/install-locales

如果需要,再使用 localedef 命令创建和安装 glibc-2.37/localedata/SUPPORTED 中没有列出的 locale。例如,本章中后续的一些测试可能需要安装两个 locale:

localedef -i POSIX -f UTF-8 C.UTF-8 2> /dev/null || true
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true

注意: 目前 glibc 在解析国际化域名时使用 libidn2。这形成了一个运行时依赖关系。如果需要使用解析国际化域名的功能,参阅 BLFS libidn2 页面安装 libidn2。

8.5.2 配置 Glibc

8.5.2.1 创建 nsswitch.conf

由于 Glibc 的默认值在网络环境下不能很好地工作,需要创建配置文件 /etc/nsswitch.conf

执行以下命令创建新的 /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
8.5.2.2 添加时区数据

输入以下命令,安装并设置时区数据:

tar -xf ../../tzdata2022g.tar.gz

ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}

for tz in etcetera southamerica northamerica europe africa antarctica  \
          asia australasia backward; do
    zic -L /dev/null   -d $ZONEINFO       ${tz}
    zic -L /dev/null   -d $ZONEINFO/posix ${tz}
    zic -L leapseconds -d $ZONEINFO/right ${tz}
done

cp -v zone.tab zone1970.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO

zic 命令的含义:

zic -L /dev/null …

该命令创建没有闰秒的 POSIX 时区。一般的惯例是将它们安装在 zoneinfozoneinfo/posix 两个目录中。必须将 POSIX 时区安装到 zoneinfo,否则若干测试套件会报告错误。在嵌入式系统上,如果存储空间十分紧张,而且您永远不会更新时区信息,您可以不使用 posix 目录,以节约 1.9 MB,但个别程序或测试套件可能会失败。

zic -L leapseconds …

该命令创建正确的,包含闰秒的时区。在嵌入式系统上,如果存储空间十分紧张,而且您永远不会更新时区信息,也不关心系统时间是否正确,您可以跳过 right 目录,以节约 1.9 MB。

zic … -p …

该命令创建 posixrule 文件。我们使用纽约时区,因为 POSIX 要求与美国一致的夏令时规则。

一种确定本地时区的方法是运行脚本:

tzselect

在回答关于当前位置的若干问题后,脚本会输出对应时区的名字 (例如America/Edmonton)。在 /usr/share/zoneinfo 中还有一些该脚本不能识别,但可以使用的时区,如 Canada/Eastern 或者 EST5EDT。

确定时区后,执行以下命令,创建 /etc/localtime

ln -sfv /usr/share/zoneinfo/<xxx> /etc/localtime

将 ** 替换成选定时区的名称 (例如 Canada/Eastern)。

8.5.2.3 配置动态加载器

默认情况下,动态加载器 (/lib/ld-linux.so.2) 在 /usr/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

EOF

如果希望的话,动态加载器也可以搜索一个目录,并将其中的文件包含在 ld.so.conf 中。通常包含文件目录中的文件只有一行,指定一个期望的库文件目录。如果需要这项功能,执行以下命令:

cat >> /etc/ld.so.conf << "EOF"
# Add an include directory
include /etc/ld.so.conf.d/*.conf

EOF
mkdir -pv /etc/ld.so.conf.d

8.5.3 Glibc 的内容

安装的程序: gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, ld.so (到 ld-linux-x86-64.so.2 或 ld-linux.so.2 的符号链接), locale, localedef, makedb, mtrace, nscd, pcprofiledump, pldd, sln, sotruss, sprof, tzselect, xtrace, zdump, 以及 zic

安装的库: ld-linux-x86-64.so.2, ld-linux.so.2, libBrokenLocale.{a,so}, libanl.{a,so}, libc.{a,so}, libc_nonshared.a, libc_malloc_debug.so, libcrypt.{a,so}, libdl.{a,so.2}, libg.a, libm.{a,so}, libmcheck.a, libmemusage.so, libmvec.{a,so}, libnsl.so.1, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libpcprofile.so, libpthread.{a,so.0}, libresolv.{a,so}, librt.{a,so.1}, libthread_db.so, 以及 libutil.{a,so.1}

安装的目录: /usr/include/arpa, /usr/include/bits, /usr/include/gnu, /usr/include/net, /usr/include/netash, /usr/include/netatalk, /usr/include/netax25, /usr/include/neteconet, /usr/include/netinet, /usr/include/netipx, /usr/include/netiucv, /usr/include/netpacket, /usr/include/netrom, /usr/include/netrose, /usr/include/nfs, /usr/include/protocols, /usr/include/rpc, /usr/include/sys, /usr/lib/audit, /usr/lib/gconv, /usr/lib/locale, /usr/libexec/getconf, /usr/share/i18n, /usr/share/zoneinfo, /var/cache/nscd, 以及 /var/lib/nss_db

简要描述

gencat 生成消息目录

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

getent 从管理数据库取得条目

iconv 转换给定文件的字符集

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

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

ldd 报告给定程序或共享库依赖于哪些共享库

lddlibc4 辅助 ldd 处理目标文件。它在 x86_64 等较新的架构上不存在

locale 给出当前 locale 的一些信息

localedef 编译 locale 规范

makedb 从文本输入创建简单的数据库

mtrace 读取并解析内存跟踪文件,以人类可读的形式输出内存跟踪信息

nscd 一个缓存最常见命名服务请求的守护进程

pcprofiledump 显示基于程序计数器的性能剖析数据

pldd 列出正在运行的进程使用的共享库

sln 静态链接的 ln 程序

sotruss 跟踪特定命令对共享库中子程序的调用

sprof 读取并显示共享库性能剖析数据

tzselect 询问用户系统所在的位置并报告对应的时区

xtrace 显示正在执行的函数以跟踪程序执行

zdump 输出当前时间在多个时区中的表示

zic 时区编译器

ld-*.so 动态链接器/加载器

libBrokenLocale 被 Glibc 内部用作使某些不正确的程序 (例如某些 Motif 程序) 正常运行的粗糙手段,参阅 glibc-2.37/locale/broken_cur_max.c 中的注释了解更多信息

libanl 异步的命名查找库

libc 主要的 C 运行库

libc_malloc_debug 预加载该库时启用内存分配检查

libcrypt 密码学库

libdl 没有功能的空库。曾经是动态链接接口库,但其功能已经并入 libc

libg 没有功能的空库,曾经是 g++ 的运行库

libm 数学库

libmvec 向量数学库,在使用 libm 时自动按需链接。

libmcheck 链接到该库时启用内存分配检查

libmemusage 被 memusage 用于收集程序内存使用信息

libnsl 网络服务库,已经弃用

libnss_* 命名服务开关模块,包含用于解析域名、用户名、组名、代号、服务、协议等的函数。由 libc 根据 /etc/nsswitch.conf 的配置进行加载。

libpcprofile 可以预加载它,以对程序进行基于程序计数器的性能剖析

libpthread 没有功能的空库。曾经包含 POSIX.1b 实时扩展要求的多数接口函数,但这些函数现已并入 libc

libresolv 包含用于创建、发送和解析因特网域名服务数据包的函数

librt 包含 POSIX.1b 实时扩展要求的多数接口

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

libutil 没有功能的空库。曾经包含一些 Unix 工具使用的“标准”函数。这些函数已经并入 libc

8.6 Zlib-1.2.13


Zlib 软件包包含一些程序使用的压缩和解压缩子程序。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 6.2 MB

8.6.1 安装 Zlib

准备编译 Zlib:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

删除无用的静态库:

rm -fv /usr/lib/libz.a

8.6.2 Zlib 的内容

安装的库: libz.so

简要描述

libz 包含一些程序使用的压缩和解压缩函数

8.7 Bzip2-1.0.8


Bzip2 软件包包含用于压缩和解压缩文件的程序。使用 bzip2 压缩文本文件可以获得比传统的 gzip 优秀许多的压缩比。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 7.2 MB

8.7.1 安装 Bzip2

应用一个补丁,以安装该软件包的文档:

patch -Np1 -i ../bzip2-1.0.8-install_docs-1.patch

以下命令保证安装的符号链接是相对的:

sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile

确保 man 页面被安装到正确位置:

sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile

执行以下命令,准备编译 Bzip2:

make -f Makefile-libbz2_so
make clean

make 命令参数的含义:

-f Makefile-libbz2_so

该选项使用一个不同的 Makefile 文件构建 Bzip2,对于我们的例子来说就是使用 Makefile-libbz2_so 文件。它创建一个共享库 libbz2.so,并将 Bzip2 工具链接到这个库。

编译并测试该软件包:

make

安装软件包中的程序:

make PREFIX=/usr install

安装共享库:

cp -av libbz2.so.* /usr/lib
ln -sv libbz2.so.1.0.8 /usr/lib/libbz2.so

安装链接到共享库的 bzip2 二进制程序到 /bin 目录,并将两个和 bzip2 完全相同的文件替换成符号链接:

cp -v bzip2-shared /usr/bin/bzip2
for i in /usr/bin/{bzcat,bunzip2}; do
  ln -sfv bzip2 $i
done

删除无用的静态库:

rm -fv /usr/lib/libbz2.a

8.7.2 Bzip2 的内容

安装的程序: bunzip2 (链接到 bzip2), bzcat (链接到 bzip2), bzcmp (链接到 bzdiff), bzdiff, bzegrep (链接到 bzgrep), bzfgrep (链接到 bzgrep), bzgrep, bzip2, bzip2recover, bzless (链接到bzmore), 以及 bzmore

安装的库: libbz2.so

安装的目录: /usr/share/doc/bzip2-1.0.8

简要描述

bunzip2 解压缩 bzip 压缩文件

bzcat 解压到标准输出

bzcmp 对 bzip 压缩过的文件运行 cmp

bzdiff 对 bzip 压缩过的文件运行 diff

bzegrep 对 bzip 压缩过的文件运行 egrep 命令

bzfgrep 对 bzip 压缩过的文件运行 fgrep 命令

bzgrep 对 bzip 压缩过的文件运行 grep 命令

bzip2 使用 Burrows-Wheeler 块排序文本压缩算法和 Huffman 编码压缩文件;其压缩率优于更常见的使用 “Lempel-Ziv” 算法的压缩工具,如 gzip

bzip2recover 试图从损坏的 bzip2 压缩文件中恢复数据

bzless 对 bzip 压缩过的文件运行 less 命令

bzmore 对 bzip 压缩过的文件运行 more 命令

libbz2 这个库实现基于 Burrows-Wheeler 算法的无损块排序数据压缩

8.8 Xz-5.4.1


Xz 软件包包含文件压缩和解压缩工具,它能够处理 lzma 和新的 xz 压缩文件格式。使用 xz 压缩文本文件,可以得到比传统的 gzip 或 bzip2 更好的压缩比。

估计构建时间: 0.1 SBU

需要硬盘空间: 21 MB

8.8.1 安装 Xz

准备编译 Xz:

./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/xz-5.4.1

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.8.2 Xz 的内容

安装的程序: lzcat (到 xz 的链接), lzcmp (到 xzdiff 的链接), lzdiff (到 xzdiff 的链接), lzegrep (到 xzgrep 的链接), lzfgrep (到 xzgrep 的链接), lzgrep (到 xzgrep 的链接), lzless (到 xzless 的链接), lzma (到 xz 的链接), lzmadec, lzmainfo, lzmore (到 xzmore 的链接), unlzma (到 xz 的链接), unxz (到 xz 的链接), xz, xzcat (到 xz 的链接), xzcmp (到 xzdiff 的链接), xzdec, xzdiff, xzegrep (到 xzgrep 的链接), xzfgrep (到 xzgrep 的链接), xzgrep, xzless, 以及 xzmore

安装的库: liblzma.so

安装的目录: /usr/include/lzma 和 /usr/share/doc/xz-5.4.1

简要描述

lzcat 解压到标准输出

lzcmp 在 LZMA 压缩文件上执行 cmp

lzdiff 在 LZMA 压缩文件上执行 diff

lzegrep 在 LZMA 压缩文件上执行 egrep

lzfgrep 在 LZMA 压缩文件上执行 fgrep

lzgrep 在 LZMA 压缩文件上执行 grep

lzless 在 LZMA 压缩文件上执行 less

lzma 使用 LZMA 格式压缩或解压缩文件

lzmadec 一个轻量、快速的 LZMA 压缩文件解码器

lzmainfo 显示 LZMA 压缩文件头中存储的信息

lzmore 在 LZMA 压缩文件上执行 more

unlzma 使用 LZMA 格式解压缩文件

unxz 使用 XZ 格式解压缩文件

xz 使用 XZ 格式压缩或解压缩文件

xzcat 解压到标准输出

xzcmp 在 XZ 压缩文件上执行 cmp

xzdec 一个轻量、快速的 XZ 压缩文件解码器

xzdiff 在 XZ 压缩文件上执行 diff

xzegrep 在 XZ 压缩文件上执行 egrep

xzfgrep 在 XZ 压缩文件上执行 fgrep

xzgrep 在 XZ 压缩文件上执行 grep

xzless 在 XZ 压缩文件上执行 less

xzmore 在 XZ 压缩文件上执行 more

liblzma 实现基于 Lempel-Zip-Markov 链的无损块排序数据压缩算法的库

8.9 Zstd-1.5.4


Zstandard 是一种实时压缩算法,提供了较高的压缩比。它具有很宽的压缩比/速度权衡范围,同时支持具有非常快速的解压缩。

估计构建时间: 0.4 SBU

需要硬盘空间: 75 MB

8.9.1 安装 Zstd

编译该软件包:

make prefix=/usr

注意: 在输出的测试结果中,可能会出现 ‘failed’。这是正常的,只有 ‘FAIL’ 才表示测试失败。该软件包的测试应该能够全部通过。

运行命令以测试编译结果:

make check

安装该软件包:

make prefix=/usr install

删除静态库:

rm -v /usr/lib/libzstd.a

8.9.2 Zstd 的内容

安装的程序: zstd, zstdcat (到 zstd 的链接), zstdgrep, zstdless, zstdmt (到 zstd 的链接), 以及 unzstd (到 zstd 的链接)

安装的库: libzstd.so

简要描述

zstd 使用 ZSTD 格式压缩或解压缩文件

zstdgrep 在 ZSTD 压缩文件上运行 grep

zstdless 在 ZSTD 压缩文件上运行 less

libzstd 基于 ZSTD 算法实现无损数据压缩的库

8.10 File-5.44


File 软件包包含用于确定给定文件类型的工具。

估计构建时间: 0.1 SBU

需要硬盘空间: 16 MB

8.10.1 安装 File

准备编译 File:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.10.2 File 的内容

安装的程序: file

安装的库: libmagic.so

简要描述

file 通过进行文件系统、魔数和语言等测试,尝试对每个给定的文件进行分类

libmagic 包含 file 程序使用的魔数识别子程序

8.11 Readline-8.2


Readline 软件包包含一些提供命令行编辑和历史记录功能的库。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 16 MB

8.11.1 安装 Readline

重新安装 Readline 会导致旧版本的库被重命名为 <库名称>.old。这一般不是问题,但某些情况下会触发 ldconfig 的一个链接 bug。运行下面的两条 sed 命令防止这种情况:

sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install

现在修复上游发现的问题:

patch -Np1 -i ../readline-8.2-upstream_fix-1.patch

准备编译 Readline:

./configure --prefix=/usr    \
            --disable-static \
            --with-curses    \
            --docdir=/usr/share/doc/readline-8.2

新的配置选项的含义:

–with-curses

该选项告诉 Readline 它可以在 curses 库中查找 termcap 库函数,而不是单独的 termcap 库。这样就能生成正确的 readline.pc 文件。

编译该软件包:

make SHLIB_LIBS="-lncursesw"

make 命令选项的含义:

SHLIB_LIBS=”-lncursesw”

该选项强制 Readline 链接到 libncursesw 库。

该软件包不包含测试套件。

安装该软件包:

make SHLIB_LIBS="-lncursesw" install

如果需要,安装该软件包的文档:

install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-8.2

8.11.2 Readline 的内容

安装的库: libhistory.so 和 libreadline.so

安装的目录: /usr/include/readline 和 /usr/share/doc/readline-8.2

简要描述

libhistory 提供一个查询之前输入行的一致用户接口

libreadline 提供一组在程序的交互会话中操纵输入的文本的命令

8.12 M4-1.4.19


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

估计构建时间: 0.3 SBU

需要硬盘空间: 49 MB

8.12.1 安装 M4

准备编译 M4:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.12.2 M4 的内容

安装的程序: m4

简要描述

m4 复制给定文件,并展开它们包含的宏。这些宏可能是内置或用户定义的,可以接受任意个参数。除了展开宏外,m4 还包含用于包含指定文件、运行 Unix 命令、进行整数运算、处理文本、递归执行等功能的内建函数。m4 程序可以被用作编译器前端,也可以被单独用作宏处理器

8.13 Bc-6.2.4


Bc 软件包包含一个任意精度数值处理语言。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 7.6 MB

8.13.1 安装 Bc

准备编译 Bc:

CC=gcc ./configure --prefix=/usr -G -O3 -r

配置选项的含义:

CC=gcc

该选项指定编译时使用的编译器。

-G

忽略在 bc 程序未安装时无法工作的测试。

-O3

该选项指定编译时使用的优化等级。

-r

允许 bc 使用 Readline,以增强命令行编辑功能。

编译该软件包:

make

为了测试 bc,运行:

make test

安装该软件包:

make install

8.13.2 Bc 的内容

安装的程序: bc 和 dc

简要描述

bc 一个命令行计算器

dc 一个逆波兰式命令行计算器

8.14 Flex-2.6.4


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

估计构建时间: 0.1 SBU

需要硬盘空间: 33 MB

8.14.1 安装 Flex

准备编译 Flex:

./configure --prefix=/usr \
            --docdir=/usr/share/doc/flex-2.6.4 \
            --disable-static

编译该软件包:

make

如果要测试编译结果 (需要约 0.5 SBU), 执行:

make check

安装该软件包:

make install

个别程序还不知道 flex,并试图去运行它的前身 lex。为了支持这些程序,创建一个名为 lex 的符号链接,它运行 flex 并启动其模拟 lex 的模式:

ln -sv flex /usr/bin/lex

8.14.2 Flex 的内容

安装的程序: flex, flex++ (到 flex 的链接), 以及 lex (到 flex 的链接)

安装的库: libfl.so

安装的目录: /usr/share/doc/flex-2.6.4

简要描述

flex 一个用于生成在文本文件中识别模式的程序的工具;它允许灵活地指定查找模式的规则,消除了开发专用程序的需要

flex++ flex 的扩展,用于生成 C++ 代码和类。它是一个指向 flex 的符号链接

lex 一个以 lex 仿真模式运行 flex 的符号链接

libfl flex 库

8.15 Tcl-8.6.13


Tcl 软件包包含工具命令语言,它是一个可靠的通用脚本语言。Except 软件包是用 Tcl (读作“tickle”) 编写的。

估计构建时间: 2.7 SBU

需要硬盘空间: 89 MB

8.15.1 安装 Tcl

为了支持 Binutils,GCC,以及其他一些软件包测试套件的运行,需要安装这个软件包和接下来的两个 (Expect 与 DejaGNU)。为了测试目的安装三个软件包看似浪费,但是只有运行了测试,才能放心地确定多数重要工具可以正常工作,即使测试不是必要的。我们必须安装这些软件包,才能执行本章中的测试套件。

准备编译 Tcl:

SRCDIR=$(pwd)
cd unix
./configure --prefix=/usr           \
            --mandir=/usr/share/man

构建该软件包:

make

sed -e "s|$SRCDIR/unix|/usr/lib|" \
    -e "s|$SRCDIR|/usr/include|"  \
    -i tclConfig.sh

sed -e "s|$SRCDIR/unix/pkgs/tdbc1.1.5|/usr/lib/tdbc1.1.5|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.5/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/tdbc1.1.5/library|/usr/lib/tcl8.6|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.5|/usr/include|"            \
    -i pkgs/tdbc1.1.5/tdbcConfig.sh

sed -e "s|$SRCDIR/unix/pkgs/itcl4.2.3|/usr/lib/itcl4.2.3|" \
    -e "s|$SRCDIR/pkgs/itcl4.2.3/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/itcl4.2.3|/usr/include|"            \
    -i pkgs/itcl4.2.3/itclConfig.sh

unset SRCDIR

“make”命令之后的若干“sed”命令从配置文件中删除构建目录,并用安装目录替换它们。构建 LFS 的后续过程不对此严格要求,但如果之后构建使用 Tcl 的软件包,则可能需要这样的操作。

运行命令以测试编译结果:

make test

安装该软件包:

make install

将安装好的库加上写入权限,以便将来移除调试符号:

chmod -v u+w /usr/lib/libtcl8.6.so

安装 Tcl 的头文件。下一个软件包 Expect 需要它们才能构建。

make install-private-headers

创建一个必要的符号链接:

ln -sfv tclsh8.6 /usr/bin/tclsh

重命名一个与 Perl man 页面文件名冲突的 man 页面:

mv /usr/share/man/man3/{Thread,Tcl_Thread}.3

如果需要,可以运行以下命令安装文档:

cd ..
tar -xf ../tcl8.6.13-html.tar.gz --strip-components=1
mkdir -v -p /usr/share/doc/tcl-8.6.13
cp -v -r  ./html/* /usr/share/doc/tcl-8.6.13

8.15.2 Tcl 的内容

安装的程序: tclsh (到 tclsh8.6 的链接) 和 tclsh8.6

安装的库: libtcl8.6.so 和 libtclstub8.6.a

简要描述

tclsh8.6 Tcl 命令行 shell

tclsh 一个指向 tclsh8.6 的链接

libtcl8.6.so Tcl 运行库

libtclstub8.6.a Tcl 端桩库

8.16 Expect-5.45.4


Expect 软件包包含通过脚本控制的对话,自动化 telnet,ftp,passwd,fsck,rlogin,以及 tip 等交互应用的工具。Expect 对于测试这类程序也很有用,它简化了这类通过其他方式很难完成的工作。DejaGnu 框架是使用 Expect 编写的。

估计构建时间: 0.2 SBU

需要硬盘空间: 3.9 MB

8.16.1 安装 Expect

准备编译 Expect:

./configure --prefix=/usr           \
            --with-tcl=/usr/lib     \
            --enable-shared         \
            --mandir=/usr/share/man \
            --with-tclinclude=/usr/include

配置选项的含义:

–with-tcl=/usr/lib

需要使用该选项告知 configure 配置脚本 tclConfig.sh 的位置。

–with-tclinclude=/usr/include

该选项显式指定查找 Tcl 内部头文件的位置。

构建该软件包:

make

运行命令以测试编译结果:

make test

安装该软件包:

make install
ln -svf expect5.45.4/libexpect5.45.4.so /usr/lib

8.16.2 Expect 的内容

安装的程序: expect

安装的库: libexpect5.45.4.so

简要描述

expect 根据一个脚本与其他交互程序交流

libexpect-5.45.4.so 包含一些函数,使得 Expect 可以作为 Tcl 扩展使用,也可以直接在 C 或 C++ 中使用 (不使用 Tcl)

8.17 DejaGNU-1.6.3


DejaGnu 包含使用 GNU 工具运行测试套件的框架。它是用 expect 编写的,后者又使用 Tcl (工具命令语言)。

估计构建时间: 0.1 SBU

需要硬盘空间: 6.9 MB

8.17.1 安装 DejaGNU

DejaGNU 开发者建议在专用的目录中进行构建:

mkdir -v build
cd       build

准备编译 DejaGNU:

../configure --prefix=/usr
makeinfo --html --no-split -o doc/dejagnu.html ../doc/dejagnu.texi
makeinfo --plaintext       -o doc/dejagnu.txt  ../doc/dejagnu.texi

构建并安装该软件包:

make install
install -v -dm755  /usr/share/doc/dejagnu-1.6.3
install -v -m644   doc/dejagnu.{html,txt} /usr/share/doc/dejagnu-1.6.3

运行命令以测试编译结果:

make check

8.17.2 DejaGNU 的内容

安装的程序: dejagnu 和 runtest

简要描述

dejagnu DejaGNU 辅助命令启动器

runtest 一个寻找正确的 expect shell,并运行 DejaGNU 的封装脚本

8.18 Binutils-2.40


Binutils 包含汇编器、链接器以及其他用于处理目标文件的工具。

估计构建时间: 2.2 SBU

需要硬盘空间: 2.6 GB

8.18.1 安装 Binutils

进行简单测试,确认伪终端 (PTY) 在 chroot 环境中能正常工作:

expect -c "spawn ls"

该命令应该输出:

spawn ls

如果输出不是上面这样,而是下面的消息,就说明环境没有为 PTY 的正常工作设置好。在运行 Binutils 和 GCC 的测试套件前必须解决这个问题。

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

Binutils 文档推荐创建一个新的目录,以在其中构建 Binutils:

mkdir -v build
cd       build

准备编译 Binutils:

../configure --prefix=/usr       \
             --sysconfdir=/etc   \
             --enable-gold       \
             --enable-ld=default \
             --enable-plugins    \
             --enable-shared     \
             --disable-werror    \
             --enable-64-bit-bfd \
             --with-system-zlib

配置选项的含义:

–enable-gold

构建 gold 链接器,并且将它安装为 ld.gold (不影响默认链接器的安装)。

–enable-ld=default

构建传统的 bfd 链接器,并且将它安装为 ld (默认链接器) 和 ld.bfd。

–enable-plugins

启用链接器插件支持。

–enable-64-bit-bfd

(在字长较小的宿主平台上) 启用 64 位支持。在 64 位平台上可能不需要,但无害。

–with-system-zlib

使用安装好的 zlib 库,而不是构建附带的版本。

编译该软件包:

make tooldir=/usr

make 命令参数的含义:

tooldir=/usr

一般来说,工具目录 (最终存放该软件包中可执行文件的目录) 被设定为 $(exec_prefix)/$(target_alias)。例如,在 x86_64 机器上,它将展开为 /usr/x86_64-pc-linux-gnu。因为 LFS 是定制系统,不需要 /usr 中的特定目标工具目录。如果系统用于交叉编译 (例如,在 Intel 机器上编译软件包,生成可以在 PowerPC 机器上执行的代码),就会使用 $(exec_prefix)/$(target_alias) 目录。

重要: 本节中,Binutils 的测试套件被认为是十分关键的,在任何情况下都不能跳过。

测试编译结果:

make -k check

如果需要列出所有失败的测试,执行:

grep '^FAIL:' $(find -name '*.log')

Gold 测试套件中,有十二项测试在构建 GCC 时启用 --enable-default-pie--enable-default-ssp 的情况下会失败。

安装该软件包:

make tooldir=/usr install

删除无用的静态库以及一个空的 man 页面:

rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,sframe,opcodes}.a
rm -fv /usr/share/man/man1/{gprofng,gp-*}.1

8.18.2 Binutils 的内容

安装的程序: addr2line, ar, as, c++filt, dwp, elfedit, gprof, gprofng, ld, ld.bfd, ld.gold, nm, objcopy, objdump, ranlib, readelf, size, strings, 以及 strip

安装的库: libbfd.so, libctf.so, libctf-nobfd.so, libopcodes.so, 以及 libsframe.so

安装的目录: /usr/lib/ldscripts

简要描述

addr2line 将程序中的地址翻译成文件名和行号;给定一个内存地址以及可执行程序的名字,该程序使用可执行文件中的调试信息,确定与该地址相关的源代码文件和行号

ar 创建、修改、提取档案文件

as 一个能够汇编 gcc 输出的汇编代码并生成目标文件的汇编器

c++filt 被链接器用于 demangle C++ 和 Java 符号,防止重载函数冲突

dwp DWARF 封装工具

elfedit 更改 ELF 文件的 ELF 头

gprof 显示函数调用图性能分析数据

gprofng 收集和分析性能数据

ld 一个链接器,将一些目标文件和档案文件组合为一个单独的文件,重定位它们的数据,并绑定符号引用

ld.gold ld 的一个裁减版,只支持 ELF 目标文件格式

ld.bfd 一个指向 ld.bfd 的硬链接

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

objcopy 将一种目标文件翻译成另一种

objdump 显示给定目标文件的信息,通过命令行选项指定要显示哪些信息;这些信息对开发编译工具的程序员很有用

ranlib 生成档案文件内容的索引,并将索引存入档案文件;索引列出档案文件中所有可重定位目标文件定义的符号

readelf 显示 ELF 格式二进制文件的信息

size 列出给定文件各个段的大小和文件总大小

strings 对于每个给定文件,输出其中长度不小于给定长度 (默认是 4) 的可打印字符序列;对于目标文件,它默认只输出可加载的已初始化数据段中的字符串,对于其他文件,它扫描整个文件

strip 移除目标文件中的符号

libbfd 二进制文件描述符库

libctf 紧凑 ANSI-C 类型格式调试支持库

libctf-nobfd libctf 的变体,它不需要 libbfd 的功能

libopcodes 一个用于处理操作码 —— 处理器指令的 “可读文本”版本的库;它被 objdump 等构建工具所使用

libsframe 使用简单的栈展开器支持在线栈回溯的库

8.19 GMP-6.2.1


GMP 软件包包含提供任意精度算术函数的数学库。

估计构建时间: 0.3 SBU

需要硬盘空间: 52 MB

8.19.1 安装 GMP

注意

如果您在为 32 位 x86 构建 LFS,但您的 CPU 能够运行 64 位代码,而且 您指定了 CFLAGS 环境变量,配置脚本会试图为 64 位 CPU 进行配置并且失败。为了避免这个问题,像下面这样执行 configure 命令:

ABI=32 ./configure ...

注意

GMP 的默认设定会生成为本机处理器优化的库。如果您希望获得适合功能没有本机强大的 CPU 的库,执行以下命令,以生成通用库:

cp -v configfsf.guess config.guess
cp -v configfsf.sub   config.sub

准备编译 GMP:

./configure --prefix=/usr    \
            --enable-cxx     \
            --disable-static \
            --docdir=/usr/share/doc/gmp-6.2.1

新的配置选项的含义:

–enable-cxx

该参数启用 C++ 支持

–docdir=/usr/share/doc/gmp-6.2.1

该变量指定文档的正确位置

编译该软件包,并生成 HTML 文档:

make
make html

重要

我们认为,本节中 GMP 的测试套件被认为是关键的。无论如何都不要跳过测试过程。

测试编译结果:

make check 2>&1 | tee gmp-check-log

小心

GMP 中的代码是针对本机处理器高度优化的。在偶然情况下,检测处理器的代码会错误识别 CPU 的功能,导致测试套件或使用 GMP 的其他程序输出消息 “Illegal instruction” (非法指令)。如果发生这种情况,需要加入选项 –build=x86_64-pc-linux-gnu 并重新构建 GMP。

务必确认测试套件中的 197 个测试全部通过。运行以下命令检验结果:

awk '/# PASS:/{total+=$3} ; END{print total}' gmp-check-log

安装该软件包及其文档:

make install
make install-html

8.19.2 GMP 的内容

安装的库: libgmp.so 和 libgmpxx.so

安装的目录: /usr/share/doc/gmp-6.2.1

简要描述

libgmp 包含任意精度数学函数

libgmpxx 包含 C++ 任意精度数学函数

8.20 MPFR-4.2.0


MPFR 软件包包含多精度数学函数。

估计构建时间: 0.2 SBU

需要硬盘空间: 43 MB

8.20.1 安装 MPFR

修复依赖于旧的 Glibc 版本中一处缺陷的测试:

sed -e 's/+01,234,567/+1,234,567 /' \
    -e 's/13.10Pd/13Pd/'            \
    -i tests/tsprintf.c

准备编译 MPFR:

./configure --prefix=/usr        \
            --disable-static     \
            --enable-thread-safe \
            --docdir=/usr/share/doc/mpfr-4.2.0

编译该软件包,并生成 HTML 文档:

make
make html

重要

本节中 MPFR 的测试套件被认为是非常关键的,无论如何不能跳过。

测试编译结果,并确认所有 197 项测试都能通过:

make check

安装该软件包及其文档:

make install
make install-html

8.20.2 MPFR 的内容

安装的库: libmpfr.so

安装的目录: /usr/share/doc/mpfr-4.2.0

简要描述

libmpfr 包含多精度数学函数

8.21 MPC-1.3.1


MPC 软件包包含一个任意高精度,且舍入正确的复数算术库。

估计构建时间: 0.1 SBU

需要硬盘空间: 22 MB

8.21.1 安装 MPC

准备编译 MPC:

./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/mpc-1.3.1

编译该软件包,并生成 HTML 文档:

make
make html

运行命令以测试编译结果:

make check

安装该软件包及其文档:

make install
make install-html

8.21.2 MPC 的内容

安装的库: libmpc.so

安装的目录: /usr/share/doc/mpc-1.3.1

简要描述

libmpc 包含复数数学运算函数

8.22 Attr-2.5.1


Attr 软件包包含管理文件系统对象扩展属性的工具。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 4.1 MB

8.22.1 安装 Attr

准备编译 Attr:

./configure --prefix=/usr     \
            --disable-static  \
            --sysconfdir=/etc \
            --docdir=/usr/share/doc/attr-2.5.1

编译该软件包:

make

测试套件必须在支持扩展属性的文件系统,如 ext2、ext3 或 ext4 上运行。运行下列命令以测试编译结果:

make check

安装该软件包:

make install

8.22.2 Attr 的内容

安装的程序: attr, getfattr, 以及 setfattr

安装的库: libattr.so

安装的目录: /usr/include/attr 和 /usr/share/doc/attr-2.5.1

简要描述

attr 在文件系统对象上扩展属性

getfattr 查询文件系统对象的扩展属性

setfattr 设定文件系统对象的扩展属性

libattr 包含处理扩展属性的库函数

8.23 Acl-2.3.1


Acl 软件包包含管理访问控制列表的工具,访问控制列表能够细致地自由定义文件和目录的访问权限。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 6.1 MB

8.23.1 安装 Acl

准备编译 Acl:

./configure --prefix=/usr         \
            --disable-static      \
            --docdir=/usr/share/doc/acl-2.3.1

编译该软件包:

make

Acl 的测试套件必须在支持访问控制的文件系统上运行,且必须在使用 Acl 库构建 Coreutils 软件包之后才能运行。如果想运行它们,在构建 Coreutils 软件包后,返回这里并执行 make check

安装该软件包:

make install

8.23.2 Acl 的内容

安装的程序: chacl, getfacl, 以及 setfacl

安装的库: libacl.so

安装的目录: /usr/include/acl 和 /usr/share/doc/acl-2.3.1

简要描述

chacl 修改文件或目录的访问控制列表

getfacl 获取文件访问控制列表

setfacl 设定文件访问控制列表

libacl 包含操作访问控制列表的库函数

8.24 Libcap-2.67


Libcap 软件包为 Linux 内核提供的 POSIX 1003.1e 权能字实现用户接口。这些权能字是 root 用户的最高特权分割成的一组不同权限。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 2.9 MB

8.24.1 安装 Libcap

防止静态库的安装:

sed -i '/install -m.*STA/d' libcap/Makefile

编译该软件包:

make prefix=/usr lib=lib

make 命令选项的含义:

lib=lib

在 x86_64 上,该参数将库文件目录设定为 /usr/lib,而不是 /usr/lib64。它在 x86 上没有作用。

运行命令以测试编译结果:

make test

安装该软件包:

make prefix=/usr lib=lib install

8.24.2 Libcap 的内容

安装的程序: capsh, getcap, getpcaps, 以及 setcap

安装的库: libcap.so 和 libpsx.so

简要描述

capsh 一个用于演示和限制 Linux 权能字的 shell 封装器

getcap 检验文件权能字

getpcaps 查询进程的权能字

setcap 设定文件权能字

libcap 包含操作 POSIX 1003.1e 权能字的库函数

libpsx 包含为 pthread 库相关的系统调用提供 POSIX 语义的函数

8.25 Shadow-4.13


Shadow 软件包包含安全地处理密码的程序。

估计构建时间: 0.1 SBU

需要硬盘空间: 46 MB

8.25.1 安装 Shadow

注意

如果您希望强制使用强密码,参考 https://www.linuxfromscratch.org/blfs/view/11.3/postlfs/cracklib.html 以在构建 Shadow 前安装 CrackLib。然后,将 --with-libcrack 添加到下面的 configure 命令中。

禁止该软件包安装 groups 程序和它的 man 页面,因为 Coreutils 会提供更好的版本。同样,避免安装第 8.3 节 “Man-pages-6.03”软件包已经提供的 man 页面:

sed -i 's/groups$(EXEEXT) //' src/Makefile.in
find man -name Makefile.in -exec sed -i 's/groups\.1 / /'   {} \;
find man -name Makefile.in -exec sed -i 's/getspnam\.3 / /' {} \;
find man -name Makefile.in -exec sed -i 's/passwd\.5 / /'   {} \;

不使用默认的 crypt 加密方法,使用更安全的 SHA-512 方法加密密码,该方法也允许长度超过 8 个字符的密码。另外,将加密迭代次数调整到 500,000,默认值 5000 太小以至于无法防范暴力密码破解。还需要把过时的用户邮箱位置 /var/spool/mail 改为当前普遍使用的 /var/mail 目录。另外,从默认的 PATH 中删除/bin/sbin,因为它们只是指向 /usr 中对应目录的符号链接:

注意

如果由于某种原因,希望将 /bin 和/或 /sbin 包含在 PATH 中,可以在构建 LFS 后通过 .bashrc 修改 PATH。

sed -e 's:#ENCRYPT_METHOD DES:ENCRYPT_METHOD SHA512:' \
    -e 's@#\(SHA_CRYPT_..._ROUNDS 5000\)@\100@'       \
    -e 's:/var/spool/mail:/var/mail:'                 \
    -e '/PATH=/{s@/sbin:@@;s@/bin:@@}'                \
    -i etc/login.defs

注意

如果您选择构建有 Cracklib 支持的 Shadow,执行该命令:

sed -i 's:DICTPATH.*:DICTPATH\t/lib/cracklib/pw_dict:' etc/login.defs

准备编译 Shadow:

touch /usr/bin/passwd
./configure --sysconfdir=/etc \
            --disable-static  \
            --with-group-name-max-length=32

新的配置选项的含义:

touch /usr/bin/passwd

我们需要保证 /usr/bin/passwd 存在,因为它的位置会被硬编码到一些程序中;且如果它不存在的话,安装脚本会在错误的位置创建它。

–with-group-name-max-length=32

用户名最长只能有 32 个字符。设定组名称最大长度为相同值。

编译该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make exec_prefix=/usr install
make -C man install-man

8.25.2 配置 Shadow

该软件包包含用于添加、修改、删除用户和组,设定和修改它们的密码,以及进行其他管理任务的工具。如果希望查阅关于 password shadowing 的详细解释,阅读解压得到源代码目录树中的 doc/HOWTO 文件。如果使用 Shadow 支持,请注意所有需要验证密码的程序 (如显示管理器、FTP 程序、pop3 守护进程等) 都必须和 Shadow 兼容。换句话说,它们必须能使用 Shadow 加密的密码。

如果要对用户密码启用 Shadow 加密,执行以下命令:

pwconv

如果要对组密码启用 Shadow 加密,执行:

grpconv

下面需要解释 Shadow 中 useradd 的默认配置。首先,useradd 的默认操作是创建一个用户,以及一个名字和用户名相同的组。默认情况下,用户 ID (UID) 和组 ID (GID) 会从 1000 开始。这意味着,如果您不向 useradd 传递参数,每个用户都会属于一个不同的组。如果您不希望这样,就要传递 -g 或者 -N 参数给 useradd,或者在/etc/login.defs 中修改 USERGROUPS_ENAB 的值。参阅 useradd(8) 了解更多相关信息。

其次,为了修改默认参数,必须创建 /etc/default/useradd 文件,并定制其内容,以满足您的特定需要。使用以下命令创建它:

mkdir -p /etc/default
useradd -D --gid 999

/etc/default/useradd 参数解释

GROUP=999

该参数设定 /etc/group 文件中使用的第一个组编号。这里的值 999 是在上面的 –gid 参数中给定的。您可以将它修改为您希望的任何值。注意,useradd 绝不会重用 UID 或 GID。如果该参数指定的数字已经被使用了,它就会使用下一个可用的数字。另外,如果您第一次使用不带 -g 参数的 useradd 命令时没有编号 999 的组,您就会在终端看到错误消息 —— useradd: unknown GID 999,尽管用户账号仍会被正常创建。为了防止这种现象的出现,我们在第 7.6 节 “创建必要的文件和符号链接”中已经用编号 999 创建了 users 组。

CREATE_MAIL_SPOOL=yes

该参数使得 useradd 为每个新用户创建邮箱文件。useradd 会使得 mail 为邮箱文件属组,并为邮箱文件赋予 0660 权限模式。如果您不希望 useradd 创建邮箱文件,执行以下命令:

sed -i '/MAIL/s/yes/no/' /etc/default/useradd

8.25.3 设定根用户密码

为用户 root 选择一个密码,并执行以下命令设定它:

passwd root

8.25.4 Shadow 的内容

安装的程序: chage, chfn, chgpasswd, chpasswd, chsh, expiry, faillog, getsubids, gpasswd, groupadd, groupdel, groupmems, groupmod, grpck, grpconv, grpunconv, lastlog, login, logoutd, newgidmap, newgrp, newuidmap, newusers, nologin, passwd, pwck, pwconv, pwunconv, sg (到 newgrp 的链接), su, useradd, userdel, usermod, vigr (到 vipw 的链接), 以及 vipw

安装的目录: /etc/default 和 /usr/include/shadow

安装的库: libsubid.so

简要描述

chage 用于修改强制性密码更新的最大天数

chfn 用于修改用户全名和其他信息

chgpasswd 用于批量更新组密码

chpasswd 用于批量更新用户密码

chsh 用于改变用户的默认登录 shell

expiry 检查并强制保证当前密码过期策略

faillog 用于检查失败登录日志,设定锁定账户的最大失败次数,以及重置失败次数

getsubids 用于列出一个用户的辅助 ID 范围

gpasswd 用于增加或删除组的用户和管理员

groupadd 以指定名称创建组

groupdel 删除指定的组

groupmems 允许用户在不需要超级用户权限的情况下,管理自己的组成员列表

groupmod 用于修改给定的组名称或 GID

grpck 验证组文件 /etc/group/etc/gshadow 的完整性

grpconv 根据普通组文件创建或更新加密组文件

grpunconv 根据 /etc/gshadow 文件更新 /etc/group 文件,并删除前者

lastlog 报告所有用户或给定用户最后一次登录的信息

login 被系统用于允许用户登录

logoutd 是一个限制登录时间和端口的守护进程

newgidmap 用于设定用户命名空间的 gid 映射

newgrp 用于在登录会话中修改当前 GID

newuidmap 用于设定用户命名空间的 uid 映射

newusers 用于批量创建或更新用户账户

nologin 显示一条账户不可用的消息;它被设计为充当已禁用账户的默认 shell

passwd 用于修改用户或组账户的密码

pwck 检验密码文件 /etc/passwd/etc/shadow 的完整性

pwconv 从普通密码文件创建或更新加密密码文件

pwunconv 根据 /etc/shadow 更新 /etc/passwd 并删除前者

sg 在用户 GID 设为给定组 ID 的情况下,执行给定命令

su 用替换的用户和组 ID 运行 shell

useradd 以指定名称创建新用户,或更新新用户默认信息

userdel 删除给定用户

usermod 用于修改给定用户的登录名称、用户标识符 (UID)、shell、初始组、home 目录等信息

vigr 编辑 /etc/group/etc/gshadow 文件

vipw 编辑 /etc/passwd/etc/shadow 文件

libsubid 用于操作用户或组的辅助 ID 范围的库

8.26 GCC-12.2.0


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

估计构建时间: 43 SBU (已计入测试时间)

需要硬盘空间: 5.1 GB

8.26.1 安装 GCC

在 x86_64 上构建时,修改存放 64 位库的默认路径为 “lib”:

case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac

GCC 文档建议在一个新建的目录中构建 GCC:

mkdir -v build
cd       build

准备编译 GCC:

../configure --prefix=/usr            \
             LD=ld                    \
             --enable-languages=c,c++ \
             --enable-default-pie     \
             --enable-default-ssp     \
             --disable-multilib       \
             --disable-bootstrap      \
             --with-system-zlib

GCC 支持七种程序设计语言,但其中多数语言需要尚未安装的依赖项。阅读 BLFS 手册,以了解如何构建 GCC 支持的所有语言。

新的配置选项的含义:

LD=ld

该选项使得配置脚本使用之前在本章中构建的 Binutils 提供的 ld 程序,而不是交叉编译构建的版本。

–with-system-zlib

该选项使得 GCC 链接到系统安装的 Zlib 库,而不是它自带的 Zlib 副本。

注意

PIE (位置无关可执行文件) 是能加载到内存中任意位置的二进制程序。在不使用 PIE 时,称为 ASLR (地址空间布局随机化) 的安全特性能被用于共享库,但不能被用于可执行程序本身。启用 PIE 使得 ASLR 在作用于共享库的同时,同样作用于可执行程序,以预防一些基于可执行程序中关键代码或数据的固定地址的攻击。

SSP (栈溢出防护) 是保证程序的调用栈不被破坏的技术。在调用栈被破坏时可能导致安全问题,例如子程序的返回地址可能被修改,进而执行一些危险代码 (这些危险代码可能已经存在于程序或共享库中,或被攻击者用某种方式注入)。

编译该软件包:

make

重要

在本节中,GCC 的测试套件十分重要,但需要消耗较长的时间。我们建议首次编译 LFS 的读者运行测试套件。通过在以下命令中添加 -jx 参数,可以显著降低测试需要的时间,其中 x 表示系统 CPU 核心数。

已知 GCC 测试套件中的一组测试可能耗尽默认栈空间,因此运行测试前要增加栈空间:

ulimit -s 32768

以非特权用户身份测试编译结果,但出错时继续执行其他测试:

chown -Rv tester .
su tester -c "PATH=$PATH make -k check"

输入以下命令提取测试结果的摘要:

../contrib/test_summary

如果只想看摘要,将输出用管道送至 grep -A7 Summ。

可以将结果与 https://www.linuxfromscratch.org/lfs/build-logs/11.3/https://gcc.gnu.org/ml/gcc-testresults/ 的结果进行比较。

在 gcc 编译器的 i386 测试套件中,有十一项测试会失败。这是由于测试文件没有考虑 –enable-default-pie 选项。

在测试 g++ 编译器时,四项与 PR100400 有关的测试会被同时报告为 XPASS (意外通过) 和 FAIL (失败);这是因为与该问题相关的测试文件编写存在瑕疵。

少量意外的失败有时无法避免,GCC 开发者一般知道这类问题,但尚未解决它们。我们可以继续安全地构建系统,除非测试结果和以上 URL 的结果截然不同。

安装该软件包:

make install

GCC 构建目录目前属于用户 tester,导致安装的头文件目录 (及其内容) 具有不正确的所有权。将所有者修改为 root 用户和组:

chown -v -R root:root \
    /usr/lib/gcc/$(gcc -dumpmachine)/12.2.0/include{,-fixed}

创建一个 FHS 因 “历史原因” 要求的符号链接。

ln -svr /usr/bin/cpp /usr/lib

创建一个兼容性符号链接,以支持在构建程序时使用链接时优化 (LTO):

ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/12.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/

现在最终的工具链已经就位,重要的是再次确认编译和链接像我们期望的一样正常工作。为此,进行下列完整性检查:

echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'

上述命令不应该出现错误,最后一行命令输出的结果应该 (不同平台的动态链接器名称可能不同) 是:

[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

下面确认我们在使用正确的启动文件:

grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log

以上命令应该输出:

/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/crtn.o succeeded

以上结果可能随您的机器体系结构不同而略微不同。差异在于 /usr/lib/gcc 之后的目录名。我们关注的重点是,gcc 应该找到所有三个 crt*.o 文件,它们应该位于 /usr/lib 目录中。

确认编译器能正确查找头文件:

grep -B4 '^ /usr/include' dummy.log

该命令应当输出:

#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed
 /usr/include

同样要注意,以您的目标三元组命名的目录由于您体系结构的不同,可能和以上不同。

下一步确认新的链接器使用了正确的搜索路径:

grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'

那些包含 ‘-linux-gnu’ 的路径应该忽略,除此之外,以上命令应该输出:

SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");

在 32 位系统上可能使用不同的目录。例如,下面是 i686 机器上的输出:

SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");

之后确认我们使用了正确的 libc:

grep "/lib.*/libc.so.6 " dummy.log

以上命令应该输出:

attempt to open /usr/lib/libc.so.6 succeeded

确认 GCC 使用了正确的动态链接器:

grep found dummy.log

以上命令应该输出 (不同平台的动态链接器名称可能不同):

found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2

如果输出和以上描述不符,或者根本没有输出,那么必然有什么地方出了严重错误。检查并重新跟踪以上步骤,找到问题的原因,并修复它。在继续构建前必须解决这里发现的所有问题。

在确认一切工作良好后,删除测试文件:

rm -v dummy.c a.out dummy.log

最后移动一个位置不正确的文件:

mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib

8.26.2 GCC 的内容

安装的程序: c++, cc (到 gcc 的链接), cpp, g++, gcc, gcc-ar, gcc-nm, gcc-ranlib, gcov, gcov-dump, gcov-tool, 以及 lto-dump

安装的库: libasan.{a,so}, libatomic.{a,so}, libcc1.so, libgcc.a, libgcc_eh.a, libgcc_s.so, libgcov.a, libgomp.{a,so}, libitm.{a,so}, liblsan.{a,so}, liblto_plugin.so, libquadmath.{a,so}, libssp.{a,so}, libssp_nonshared.a, libstdc++.{a,so}, libstdc++fs.a, libsupc++.a, libtsan.{a,so}, 以及 libubsan.{a,so}

安装的目录: /usr/include/c++, /usr/lib/gcc, /usr/libexec/gcc, 以及 /usr/share/gcc-12.2.0

简要描述

c++ C++ 编译器

cc C 编译器

cpp C 预处理器;编译器使用它展开源文件中的 #include、#define,以及类似指令

g++ C++ 编译器

gcc C 编译器

gcc-ar ar 的一个包装器,它在命令行中添加一个插件。这个程序只被用于提供链接时优化功能,对于默认的构建选项来说没有作用。

gcc-nm nm 的一个包装器,它在命令行中添加一个插件。这个程序只被用于提供链接时优化功能,对于默认的构建选项来说没有作用。

gcc-ranlib ranlib 的一个包装器,它在命令行中添加一个插件。这个程序只被用于提供链接时优化功能,对于默认的构建选项来说没有作用。

gcov 一个覆盖率测试工具;用于分析程序以确定在哪里优化最有效

gcov-dump 离线 gcda 和 gcno 性能剖析数据显示工具

gcov-tool 离线 gcda 性能剖析预处理工具

lto-dump 用于转储 GCC 启用 LTO 时生成的目标文件

libasan 地址完整性检查库

libatomic GCC 内建原子操作运行库

libcc1 C 预处理库

libgcc 包含 gcc 的运行时支持

libgcov 在 GCC 被指示启动性能剖析时,这个库被链接到程序中

libgomp OpenMP API 的 GNU 实现,用于 C/C++ 和 Fortran 的跨平台共享内存并行编程

libitm GNU 事务内存库

liblsan 内存泄露清理检查库

liblto_plugin GCC 的 LTO 插件,允许 Binutils 处理 GCC 在启用 LTO 时生成的目标文件

libquadmath GCC 四精度数学 API 库

libssp 包含 GCC 的栈溢出保护功能支持子程序。一般不使用它,因为 Glibc 也提供这些子程序。

libstdc++ C++ 标准库

libstdc++fs ISO/IEC TS 18822:2015 文件系统库

libsupc++ 包含 C++ 编程语言支持子程序

libtsan 线程完整性检查库

libubsan 未定义行为清理检查库

8.27 Pkg-config-0.29.2


pkg-config 软件包提供一个在软件包安装的配置和编译阶段,向构建工具传递头文件和/或库文件路径的工具。

估计构建时间: 0.1 SBU

需要硬盘空间: 29 MB

8.27.1 安装 Pkg-config

准备编译 Pkg-config:

./configure --prefix=/usr              \
            --with-internal-glib       \
            --disable-host-tool        \
            --docdir=/usr/share/doc/pkg-config-0.29.2

新的配置选项的含义:

–with-internal-glib

该选项允许 pkg-config 使用它内部的 Glib 版本,因为 LFS 不提供外部的 Glib。

–disable-host-tool

该选项防止创建一个指向 pkg-config 程序的不需要的硬链接。

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.27.2 Pkg-config 的内容

安装的程序: pkg-config

安装的目录: /usr/share/doc/pkg-config-0.29.2

简要描述

pkg-config 返回某个库或软件包的元数据信息

8.28 Ncurses-6.4


Ncurses 软件包包含使用时不需考虑终端特性的字符屏幕处理函数库。

估计构建时间: 0.2 SBU

需要硬盘空间: 45 MB

8.28.1 安装 Ncurses

准备编译 Ncurses:

./configure --prefix=/usr           \
            --mandir=/usr/share/man \
            --with-shared           \
            --without-debug         \
            --without-normal        \
            --with-cxx-shared       \
            --enable-pc-files       \
            --enable-widec          \
            --with-pkg-config-libdir=/usr/lib/pkgconfig

新的配置选项的含义:

–with-shared

该选项使得 Ncurses 将 C 函数库构建并安装为共享库。

–without-normal

该选项禁止将 C 函数库构建和安装为静态库。

–without-debug

该选项禁止构建和安装用于调试的库。

–with-cxx-shared

该选项使得 Ncurses 将 C++ 绑定构建并安装为共享库,同时防止构建和安装静态的 C++ 绑定库。

–enable-pc-files

该参数使得构建系统生成并安装 pkg-config 使用的 .pc 文件。

–enable-widec

该选项使得宽字符库 (例如 libncursesw.so.6.4) 被构建,而不构建常规字符库 (例如 libncurses.so.6.4)。宽字符库在多字节和传统 8 位 locale 中都能工作,而常规字符库只能在 8 位 locale 中工作。宽字符库和普通字符库在源码层面是兼容的,但二进制不兼容。

编译该软件包:

make

该软件包有测试套件,但只能在安装该软件包后才能运行。测试用例位于 test/ 中。阅读其中的 README 文件了解更多细节。

安装该软件包会直接覆盖文件 libncursesw.so.6.4。这可能导致正在使用该库文件中的代码和数据的 shell 进程发生崩溃。因此,需要使用 DESTDIR 进行安装,并正确地使用 install 命令安装库文件:

make DESTDIR=$PWD/dest install
install -vm755 dest/usr/lib/libncursesw.so.6.4 /usr/lib
rm -v  dest/usr/lib/libncursesw.so.6.4
cp -av dest/* /

许多程序仍然希望链接器能够找到非宽字符版本的 Ncurses 库。通过使用符号链接和链接脚本,诱导它们链接到宽字符库:

for lib in ncurses form panel menu ; do
    rm -vf                    /usr/lib/lib${lib}.so
    echo "INPUT(-l${lib}w)" > /usr/lib/lib${lib}.so
    ln -sfv ${lib}w.pc        /usr/lib/pkgconfig/${lib}.pc
done

最后,确保那些在构建时寻找 -lcurses 的老式程序仍然能够构建:

rm -vf                     /usr/lib/libcursesw.so
echo "INPUT(-lncursesw)" > /usr/lib/libcursesw.so
ln -sfv libncurses.so      /usr/lib/libcurses.so

如果需要的话,安装 Ncurses 文档:

mkdir -pv      /usr/share/doc/ncurses-6.4
cp -v -R doc/* /usr/share/doc/ncurses-6.4

注意

上述指令没有创建非宽字符的 Ncurses 库,因为从源码编译的软件包不会在运行时链接到它。然而,已知的需要链接到非宽字符 Ncurses 库的二进制程序都需要版本 5。如果您为了满足一些仅有二进制版本的程序,或者满足 LSB 兼容性,必须安装这样的库,执行以下命令再次构建该软件包:

make distclean
./configure --prefix=/usr    \
            --with-shared    \
            --without-normal \
            --without-debug  \
            --without-cxx-binding \
            --with-abi-version=5
make sources libs
cp -av lib/lib*.so.5* /usr/lib

8.28.2 Ncurses 的内容

安装的程序: captoinfo (链接到 tic), clear, infocmp, infotocap (链接到 tic), ncursesw6-config, reset (链接到 tset), tabs, tic, toe, tput, 以及 tset

安装的库: libcursesw.so (指向 libncursesw.so 的符号链接和链接脚本), libformw.so, libmenuw.so, libncursesw.so, libncurses++w.so, libpanelw.so, 以及它们的库名称没有 “w” 的非宽字符替代品。

安装的目录: /usr/share/tabset, /usr/share/terminfo, 以及 /usr/share/doc/ncurses-6.4

简要描述

captoinfo 将 termcap 描述转换成 terminfo 描述

clear 如果可能的话,清空屏幕

infocmp 比较或输出 terminfo 描述

infotocap 将 terminfo 描述转化为 termcap 描述

ncursesw6-config 提供 ncurses 的配置信息

reset 以终端默认值重新初始化终端

tabs 清除并设置终端的制表符宽度

tic Terminfo 条目描述编译器,将 terminfo 文件从源代码格式翻译为 ncurses 库子程序需要的二进制格式 [terminfo 文件包含特定终端的功能信息。]

toe 列出所有可用的终端类型,并给出每种类型的主要名称和描述

tput 使 shell 可以使用终端相关的功能;也可以重置或初始化终端,或者报告它的长名称

tset 可以被用于初始化终端

libcursesw 指向 libncursesw 的链接

libncursesw 包含在终端屏幕上以多种复杂方式显示文本的函数;使用这些函数的典型例子是运行内核的 make menuconfig 时显示的目录

libncurses++w 包含该软件包中其他库的 C++ 语言绑定

libformw 包含实现表单的函数

libmenuw 包含实现目录的函数

libpanelw 包含实现面板的函数

8.29 Sed-4.9


Sed 软件包包含一个流编辑器。

估计构建时间: 0.3 SBU

需要硬盘空间: 31 MB

8.29.1 安装 Sed

准备编译 Sed:

./configure --prefix=/usr

编译该软件包,并生成 HTML 文档:

make
make html

运行命令以测试编译结果:

chown -Rv tester .
su tester -c "PATH=$PATH make check"

安装该软件包及其文档:

make install
install -d -m755           /usr/share/doc/sed-4.9
install -m644 doc/sed.html /usr/share/doc/sed-4.9

8.29.2 Sed 的内容

安装的程序: sed

安装的目录: /usr/share/doc/sed-4.9

简要描述

sed 一次性过滤和转换文本文件

8.30 Psmisc-23.6


Psmisc 软件包包含显示正在运行的进程信息的程序。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 6.5 MB

8.30.1 安装 Psmisc

准备编译 Psmisc:

./configure --prefix=/usr

编译该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make install

8.30.2 Psmisc 的内容

安装的程序: fuser, killall, peekfd, prtstat, pslog, pstree, 以及 pstree.x11 (到 pstree 的链接)

简要描述

fuser 报告使用给定文件或文件系统的进程 ID (PID)

killall 根据名称杀死进程;它向所有运行给定命令的进程发送信号

peekfd 根据给定 PID,查看正在运行进程的文件描述符

prtstat 打印某个进程的信息

pslog 报告某个进程当前使用的日志路径

pstree 以树形格式列出正在运行的进程

pstree.x11 除了在退出前等待用户确认外,和 pstree相同

8.31 Gettext-0.21.1


Gettext 软件包包含国际化和本地化工具,它们允许程序在编译时加入 NLS (本地语言支持) 功能,使它们能够以用户的本地语言输出消息。

估计构建时间: 1.3 SBU

需要硬盘空间: 241 MB

8.31.1 安装 Gettext

准备编译 Gettext:

./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/gettext-0.21.1

编译该软件包:

make

输入以下命令以测试编译结果 (需要较长时间, 大约 3 SBU):

make check

安装该软件包:

make install
chmod -v 0755 /usr/lib/preloadable_libintl.so

8.31.2 Gettext 的内容

安装的程序: autopoint, envsubst, gettext, gettext.sh, gettextize, msgattrib, msgcat, msgcmp, msgcomm, msgconv, msgen, msgexec, msgfilter, msgfmt, msggrep, msginit, msgmerge, msgunfmt, msguniq, ngettext, recode-sr-latin, 以及 xgettext

安装的库: libasprintf.so, libgettextlib.so, libgettextpo.so, libgettextsrc.so, libtextstyle.so, 以及 preloadable_libintl.so

安装的目录: /usr/lib/gettext, /usr/share/doc/gettext-0.21.1, /usr/share/gettext, 以及 /usr/share/gettext-0.19.8

简要描述

autopoint 将标准 Gettext 微架构文件复制到源代码包

envsubst 替换 shell 格式化字符串中的环境变量

gettext 通过查询消息目录中的翻译,将中性语言消息翻译成用户的语言

gettext.sh 主要用于 gettext 的 shell 函数库

gettextize 将所有标准 Gettext 文件复制到软件包顶层目录中,以开始国际化该软件包

msgattrib 根据属性过滤翻译目录中的消息,或修改这些属性

msgcat 连接并合并给定的 .po 文件

msgcmp 比较两个 .po 文件,以检查它们是否包含相同的 msgid 字符串集合

msgcomm 找出给定的多个 .po 中的公共消息

msgconv 将翻译目录转换成另一种字符编码

msgen 创建英文翻译目录

msgexec 对翻译目录中的所有翻译执行命令

msgfilter 对翻译目录中的所有翻译应用过滤器

msgfmt 根据翻译目录创建二进制消息目录

msggrep 找出翻译目录中所有匹配给定模式,或属于给定源代码文件的消息

msginit 创建一个新的 .po 文件,以用户环境中的值初始化其元信息

msgmerge 将两个原始翻译文件组合成一个文件

msgunfmt 反编译二进制消息目录,生成原始翻译文本

msguniq 去除翻译目录中重复的翻译

ngettext 显示某条语法形式依赖于数字的文本消息的母语翻译

recode-sr-latin 将塞尔维亚语文本从西里尔字符转换为拉丁字符

xgettext 从给定源代码文件中提取可翻译消息,以生成最初的翻译模板

libasprintf 定义 autosprintf 类,使得 C 格式化输出子程序在 C++ 程序中能够与 字符串和 流一起使用

libgettextlib 包含若干 Gettext 程序的公共子程序;并未设计为供其他程序使用

libgettextpo 用于编写处理 .po 文件的专用程序;这个库在 Gettext 发行的标准程序 (如 msgcomm, msgcmp, msgattrib, 以及 msgen) 不能满足要求时使用

libgettextsrc 包含若干 Gettext 程序的公共子程序;并未设计为供其他程序使用

libtextstyle 文本样式库

preloadable_libintl 一个被设计为由 LD_PRELOAD 预加载的库,它帮助 libintl 记录未翻译的消息

8.32 Bison-3.8.2


Bison 软件包包含语法分析器生成器。

估计构建时间: 2.3 SBU

需要硬盘空间: 62 MB

8.32.1 安装 Bison

准备编译 Bison:

./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.8.2

编译该软件包:

make

如果要测试编译结果 (需要约 5.5 SBU),运行命令:

make check

安装该软件包:

make install

8.32.2 Bison 的内容

安装的程序: bison 和 yacc

安装的库: liby.a

安装的目录: /usr/share/bison

简要描述

bison 根据一组规则,创建一个用于分析文本文件结构的程序;Bison 是 Yacc (Yet Another Compiler Compiler) 的替代品

yacc bison 的一个封装器,被那些仍然调用 yacc 而非 bison 的程序使用,它调用 bison 时附加 -y 选项

liby Yacc 库包含与 Yacc 兼容的 yyerror 和 main 函数实现;它并不是很有用,但 POSIX 需要它

8.33 Grep-3.8


Grep 软件包包含在文件内容中进行搜索的程序。

估计构建时间: 0.4 SBU

需要硬盘空间: 37 MB

8.33.1 安装 Grep

首先,移除使用 egrep 和 fgrep 时的警告,它会导致一些软件包测试失败:

sed -i "s/echo/#echo/" src/egrep.sh

准备编译 Grep:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.33.2 Grep 的内容

安装的程序: egrep, fgrep, 以及 grep

简要描述

egrep 打印与固定字符串匹配的行。已弃用,使用 grep -E 代替它

fgrep 打印与固定字符串匹配的行。已弃用,使用 grep -F 代替它

grep 打印与基本正则表达式匹配的行

8.34 Bash-5.2.15


Bash 软件包包含 Bourne-Again Shell。

估计构建时间: 1.2 SBU

需要硬盘空间: 52 MB

8.34.1 安装 Bash

准备编译 Bash:

./configure --prefix=/usr             \
            --without-bash-malloc     \
            --with-installed-readline \
            --docdir=/usr/share/doc/bash-5.2.15

新的配置选项的含义:

–with-installed-readline

该选项告诉 Bash 使用系统中已经安装的 readline 库,而不是它自己的 readline 版本。

编译该软件包:

make

如果不运行测试套件,直接跳到 “安装该软件包”。

为了准备进行测试,确保 tester 用户可以写入源代码目录:

chown -Rv tester .

该软件包的测试套件被设计为以非 root 用户身份运行,且该用户必须是标准输入所连接的终端的所有者。为了满足这一条件,使用 Expect 生成一个新的伪终端,并以 tester 用户身份运行测试:

su -s /usr/bin/expect tester << EOF
set timeout -1
spawn make tests
expect eof
lassign [wait] _ _ _ value
exit $value
EOF

测试套件使用 diff 检测测试脚本输出和预期是否存在不同。diff 的任何输出 (以 < 和 > 开头) 都表示测试失败,除非有消息提示可以忽略这里报告的差别。已知一项名为 run-builtins 的测试在一些宿主系统上可能失败,此时该测试输出的第一行和预期存在不同。

安装该软件包:

make install

执行新编译的 bash 程序 (替换当前正在执行的版本):

exec /usr/bin/bash --login

8.34.2 Bash 的内容

安装的程序: bash, bashbug, 以及 sh (到 bash 的链接)

安装的目录: /usr/include/bash, /usr/lib/bash, 和 /usr/share/doc/bash-5.2.15

简要描述

bash 一个广泛使用的命令解释器;它在执行命令前对命令行进行多种展开和替换操作,这些操作使得它成为强大的工具

bashbug 一个 shell 脚本,用于帮助用户按照电子邮件标准格式编写关于 bash 的 bug 报告

sh 一个指向 bash 程序的符号链接;当以 sh 命令运行时,bash 试图尽可能地模仿 sh 的历史版本,以符合 POSIX 标准

8.35 Libtool-2.4.7


Libtool 软件包包含 GNU 通用库支持脚本。它提供一致、可移植的接口,以简化共享库的使用。

估计构建时间: 1.4 SBU

需要硬盘空间: 44 MB

8.35.1 安装 Libtool

准备编译 Libtool:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make -k check

注意

在多核系统上,可以显著减少 Libtool 的测试时间。为了使用多个核心,在上述命令中附加 **TESTSUITEFLAGS=-j** 参数。例如,使用 -j4 可以减少超过 60% 的测试时间。

在 LFS 构建环境中,已知有五项测试因为循环依赖而失败,但这些测试在 automake 安装后能够通过。另外,在使用 grep-3.8 时,两项测试触发关于非 POSIX 正则表达式的警告而失败。

安装该软件包:

make install

删除无用的静态库:

rm -fv /usr/lib/libltdl.a

8.35.2 Libtool 的内容

安装的程序: libtool 和 libtoolize

安装的库: libltdl.so

安装的目录: /usr/include/libltdl 和 /usr/share/libtool

简要描述

libtool 提供通用化库文件构建支持服务

libtoolize 提供为软件包增加 libtool 支持的标准方法

libltdl 隐藏使用动态加载库时可能遇到的若干困难

8.36 GDBM-1.23


GDBM 软件包包含 GNU 数据库管理器。它是一个使用可扩展散列的数据库函数库,功能类似于标准的 UNIX dbm。该库提供用于存储键值对、通过键搜索和获取数据,以及删除键和对应数据的原语。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 13 MB

8.36.1 安装 GDBM

准备编译 GDBM:

./configure --prefix=/usr    \
            --disable-static \
            --enable-libgdbm-compat

配置选项的含义:

–enable-libgdbm-compat

该选项启用 libgdbm 兼容性库的构建。LFS 之外的一些软件包需要它提供的老式 DBM 子程序。

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.36.2 GDBM 的内容

安装的程序: gdbm_dump, gdbm_load, 以及 gdbmtool

安装的库: libgdbm.so 和 libgdbm_compat.so

简要描述

gdbm_dump 将 GDBM 数据库转储到文件

gdbm_load 从转储文件重建 GDBM 数据库

gdbmtool 测试和修改 GDBM 数据库

libgdbm 包含用于操作散列数据库的函数

libgdbm_compat 包含老式 DBM 函数的兼容性库

8.37 Gperf-3.1


Gperf 根据一组键值,生成完美散列函数。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 6.1 MB

8.37.1 安装 Gperf

准备编译 Gperf:

./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1

编译该软件包:

make

已知同时执行多个测试 (-j 选项的值大于 1) 会导致测试失败。执行以下命令测试编译结果:

make -j1 check

安装该软件包:

make install

8.37.2 Gperf 的内容

安装的程序: gperf

安装的目录: /usr/share/doc/gperf-3.1

简要描述

gperf 根据键值集合生成完美散列函数

8.38 Expat-2.5.0


Expat 软件包包含用于解析 XML 文件的面向流的 C 语言库。

估计构建时间: 0.1 SBU

需要硬盘空间: 12 MB

8.38.1 安装 Expat

准备编译 Expat:

./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/expat-2.5.0

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

如果需要,安装该软件包的文档:

install -v -m644 doc/*.{html,css} /usr/share/doc/expat-2.5.0

8.38.2 Expat 的内容

安装的程序: xmlwf

安装的库: libexpat.so

安装的目录: /usr/share/doc/expat-2.5.0

简要描述

xmlwf 是一个用于检验 XML 文档是否良好的非验证性工具

libexpat 包含解析 XML 文档的 API 函数

8.39 Inetutils-2.4


Inetutils 软件包包含基本网络程序。

估计构建时间: 0.2 SBU

需要硬盘空间: 31 MB

8.39.1 安装 Inetutils

准备编译 Inetutils:

./configure --prefix=/usr        \
            --bindir=/usr/bin    \
            --localstatedir=/var \
            --disable-logger     \
            --disable-whois      \
            --disable-rcp        \
            --disable-rexec      \
            --disable-rlogin     \
            --disable-rsh        \
            --disable-servers

配置选项的含义:

–disable-logger

该选项防止 Inetutils 安装 logger 程序,它被脚本文件用于向系统日志守护程序传递消息。这里不安装它,因为 Util-linux 会安装更新的版本。

–disable-whois

该选项防止构建过时的 whois 客户端,BLFS 手册中有一个更好的 whois 客户端。

–disable-r*

这些参数禁用过时的程序,由于安全问题,它们不应该被继续使用。它们提供的功能可以由 BLFS 手册中的 openssh 软件包代替。

–disable-servers

该选项禁用 Inetutils 软件包包含的若干网络服务程序,它们在基本的 LFS 系统中注定是不合适的。其中一些服务程序从本质上就不安全,只有在可信的网络环境中才能被认为是安全的。要注意的是,对于其中许多服务程序,都能找到更好的替代品。

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

将一个程序移动到正确的位置:

mv -v /usr/{,s}bin/ifconfig

8.39.2 Inetutils 的内容

安装的程序: dnsdomainname, ftp, ifconfig, hostname, ping, ping6, talk, telnet, tftp, 以及 traceroute

简要描述

dnsdomainname 显示系统的 DNS 域名

ftp 文件传输程序

hostname 报告或设定主机名称

ifconfig 管理网络接口

ping 发送回显请求数据包并报告响应用时

ping6 用于 IPv6 网络的 ping 版本

talk 用于和其他用户聊天

telnet TELNET 协议的接口

tftp 简单文件传输程序

traceroute 追踪您的数据包从您工作的主机到网络上另一台主机的路径,显示中间通过的跳跃 (网关)

8.40 Less-608


Less 软件包包含一个文本文件查看器。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 4.3 MB

8.40.1 安装 Less

准备编译 Less:

./configure --prefix=/usr --sysconfdir=/etc

配置选项的含义:

–sysconfdir=/etc

该选项告诉该软件包创建的程序在 /etc 查找配置文件

编译该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make install

8.40.2 Less 的内容

安装的程序: less, lessecho, 以及 lesskey

简要描述

less 一个文件查看器或分页器;它显示给定文件的内容,使得用户可以进行滚动、查找字符串,或跳到标记

lessecho 用于展开元字符,例如 Unix 系统上文件名中的 * 和 ?

lesskey 用于指定 less 的按键绑定

8.41 Perl-5.36.0


Perl 软件包包含实用报表提取语言。

估计构建时间: 7.9 SBU

需要硬盘空间: 234 MB

8.41.1 安装 Perl

该版本的 Perl 会构建 Compress::Raw::ZLib 和 Compress::Raw::BZip2 模块。默认情况下 Perl 会使用内部的源码副本构建它们。执行以下命令,使得 Perl 使用已经安装到系统上的库:

export BUILD_ZLIB=False
export BUILD_BZIP2=0

为了能够完全控制 Perl 的设置,您可以在以下命令中移除 “-des” 选项,并手动选择构建该软件包的方式。或者,直接使用下面给出的命令,以使用 Perl 自动检测的默认值:

sh Configure -des                                         \
             -Dprefix=/usr                                \
             -Dvendorprefix=/usr                          \
             -Dprivlib=/usr/lib/perl5/5.36/core_perl      \
             -Darchlib=/usr/lib/perl5/5.36/core_perl      \
             -Dsitelib=/usr/lib/perl5/5.36/site_perl      \
             -Dsitearch=/usr/lib/perl5/5.36/site_perl     \
             -Dvendorlib=/usr/lib/perl5/5.36/vendor_perl  \
             -Dvendorarch=/usr/lib/perl5/5.36/vendor_perl \
             -Dman1dir=/usr/share/man/man1                \
             -Dman3dir=/usr/share/man/man3                \
             -Dpager="/usr/bin/less -isR"                 \
             -Duseshrplib                                 \
             -Dusethreads

配置选项的含义:

-Dvendorprefix=/usr

这保证 perl 正确告知软件包安装其 Perl 模块的位置。

-Dpager=”/usr/bin/less -isR”

这保证该软件包使用 less 对输出进行分页,而不是使用 more。

-Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3

由于 Groff 还没有安装,Configure 不会创建 Perl 的 man 页面。这些参数覆盖这个默认行为。

-Duseshrplib

构建 libperl 共享库,一些 Perl 模块需要它。

-Dusethreads

构建带有线程支持的 Perl。

-Dprivlib,-Darchlib,-Dsitelib,…

这些选项定义 Perl 查找系统上安装的模块的位置。LFS 编辑决定将它们存放在以主版本号.次版本号 (如 5.36) 格式表示 Perl 版本的目录结构中,这样在升级 Perl 到更新的修订号 (修订号就是类似 5.36.0 这样的完整版本号中用小数点分割得到的最后一部分) 时,不需要重新安装所有模块。

编译该软件包:

make

为了测试编译结果 (需要约 11 SBU),执行以下命令:

make test

安装该软件包,并清理环境变量:

make install
unset BUILD_ZLIB BUILD_BZIP2

8.41.2 Perl 的内容

安装的程序: corelist, cpan, enc2xs, encguess, h2ph, h2xs, instmodsh, json_pp, libnetcfg, perl, perl5.36.0 (指向 perl 的硬链接), perlbug, perldoc, perlivp, perlthanks (指向 perlbug 的硬链接), piconv, pl2pm, pod2html, pod2man, pod2text, pod2usage, podchecker, podselect, prove, ptar, ptardiff, ptargrep, shasum, splain, xsubpp, 以及 zipdetails

安装的库: 很多,无法在这里全部列出

安装的目录: /usr/lib/perl5

简要描述

corelist Module::CoreList 的命令行前端

cpan 通过命令行与 Perl 综合归档网络 (CPAN) 交互

enc2xs 从 Unicode 字符映射或 Tcl 编码文件构建 Encode 模块使用的 Perl 扩展

encguess 猜测一些文件的编码格式

h2ph 将 .h C 头文件转化为 .ph Perl 头文件

h2xs 将 .h C 头文件转化为 Perl 扩展

instmodsh 用于检验安装好的 Perl 模块的 shell 脚本;可以从安装好的模块创建压缩包

json_pp 在特定输入输出格式之间转化数据

libnetcfg 可以被用于配置 libnet Perl 模块

perl 由 C 语言、sed、awk 和 sh 的最好特性结合成的一门瑞士军刀式语言

perl5.36.0 指向 perl 的硬链接

perlbug 用于创建关于 Perl 或者它附带的模块的 bug 报告,并用邮件发送它们

perldoc 显示集成在 Perl 安装目录树或某个 Perl 脚本中的一页 pod 格式文档

perlivp Perl 安装检验程序;它可以被用于确认 Perl 和它的库都安装正确

perlthanks 用于生成发送给 Perl 开发者的感谢信

piconv 字符编码转换器 iconv 的 Perl 版本

pl2pm 一个用于将 Perl4 .pl 文件转换成 Perl5 .pm 模块的粗糙工具

pod2html 将 pod 格式的文件转换为 HTML 格式

pod2man 将 pod 数据转换为格式化的 *roff 输入

pod2text 将 pod 数据转化为格式化的 ASCII 文本

pod2usage 输出文件中嵌入的 pod 文档中的使用方法信息

podchecker 检查 pod 格式文档文件的语法

podselect 显示 pod 文档中的指定章节

prove 用于运行使用 Test::Harness 模块的测试

ptar 一个 Perl 编写的类似 tar 的程序

ptardiff 一个比较压缩档案和未压缩版本的 Perl 程序

ptargrep 一个在 tar 档案中的文件内容上进行模式匹配的 Perl 程序

shasum 打印或检查 SHA 校验和

splain 被用于 Perl 的强制性详细警告诊断

xsubpp 将 Perl XS 代码转换为 C 代码

zipdetails 显示 Zip 文件内部结构的详细信息

8.42 XML::Parser-2.46


XML::Parser 模块是 James Clark 的 XML 解析器 Expat 的 Perl 接口。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 2.3 MB

8.42.1 安装 XML::Parser

准备编译 XML::Parser:

perl Makefile.PL

编译该软件包:

make

运行命令以测试编译结果:

make test

安装该软件包:

make install

8.42.2 XML::Parser 的内容

安装的模块: Expat.so

简要描述

Expat 提供 Expat 的 Perl 接口

8.43 Intltool-0.51.0


Intltool 是一个从源代码文件中提取可翻译字符串的国际化工具。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 1.5 MB

8.43.1 安装 Intltool

首先修复由 perl-5.22 及更新版本导致的警告:

sed -i 's:\\\${:\\\$\\{:' intltool-update.in

注意

上面使用的正则表达式由于大量的反斜线,看上去比较奇怪。它的功能是在序列 ‘${‘ 的花括号之前增加一个反斜线,得到 ‘${‘。

准备编译 Intltool:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install
install -v -Dm644 doc/I18N-HOWTO /usr/share/doc/intltool-0.51.0/I18N-HOWTO

8.43.2 Intltool 的内容

安装的程序: intltool-extract, intltool-merge, intltool-prepare, intltool-update, 以及 intltoolize

安装的目录: /usr/share/doc/intltool-0.51.0 和 /usr/share/intltool

简要描述

intltoolize 准备为软件包应用 intltool

intltool-extract 生成可供 gettext 读取的头文件

intltool-merge 将翻译好的字符串合并为多种类型的文件

intltool-prepare 更新 pot 文件并将它们和翻译文件合并

intltool-update 更新 po 模板文件并将它们和翻译文件合并

8.44 Autoconf-2.71


Autoconf 软件包包含生成能自动配置软件包的 shell 脚本的程序。

估计构建时间: 不到 0.1 SBU (计入测试时间为约 6.2 SBU)

需要硬盘空间: 24 MB

8.44.1 安装 Autoconf

首先修复由 bash-5.2 及更新版本导致的一些问题:

sed -e 's/SECONDS|/&SHLVL|/'               \
    -e '/BASH_ARGV=/a\        /^SHLVL=/ d' \
    -i.orig tests/local.at

准备编译 Autoconf:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

注意

在多核系统上,可以显著减少 autoconf 的测试时间。为了使用多个核心,在上述命令中附加 TESTSUITEFLAGS=-j 参数。例如,使用 -j4 可以减少超过 60% 的测试时间。

安装该软件包:

make install

8.44.2 Autoconf 的内容

安装的程序: autoconf, autoheader, autom4te, autoreconf, autoscan, autoupdate, 以及 ifnames

安装的目录: /usr/share/autoconf

简要描述

autoconf 产生自动配置软件源码包,使其适用于多种类 Unix 系统的 shell 脚本;它产生的脚本可以独立运行 —— 运行它们不需要 autoconf 程序

autoheader 一个创建 C #define 预处理指令的模板,以供配置脚本使用的程序

autom4te M4 宏处理器的封装器

autoreconf 在 autoconf 和 automake 模板文件发生变化时,按照正确顺序自动运行 autoconf、autoheader、aclocal、automake、gettextize, 以及 libtoolize,以便节省时间

autoscan 帮助用户为软件包创建configure.in 文件;它检验目录树中的源代码文件,在其中找出一般的移植性问题,然后创建一个 configure.scan 文件,作为软件包的原始 configure.in 文件

autoupdate 修改 configure.in 文件,将其中过时的 autoconf 宏名改为新的宏名。

ifnames 帮助用户为软件包编写 configure.in;它打印软件包在 C 预处理器条件中使用的所有标识符 [如果一个软件包已经被设定为有一定的可移植性,该程序可以帮助确定 configure 需要进行哪些测试。它也会填充 autoscan 生成的 configure.in 中留下的空隙。]

8.45 Automake-1.16.5


Automake 软件包包含自动生成 Makefile,以便和 Autoconf 一同使用的程序。

估计构建时间: 不到 0.1 SBU (计入测试时间为约 7.3 SBU)

需要硬盘空间: 114 MB

8.45.1 安装 Automake

准备编译 Automake:

./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.16.5

编译该软件包:

make

由于单个测试点中存在的内部时延,即使仅有一个处理器,也应该使用 make 命令的 -j4 选项加速测试。输入以下命令测试编译结果:

make -j4 check

已知名为 t/subobj.sh 的测试可能失败。

安装该软件包:

make install

8.45.2 Automake 的内容

安装的程序: aclocal, aclocal-1.16 (与 aclocal 互为硬链接), automake, 以及 automake-1.16 (与 automake 互为硬链接)

安装的目录: /usr/share/aclocal-1.16, /usr/share/automake-1.16, 以及 /usr/share/doc/automake-1.16.5

简要描述

aclocal 根据 configure.in 文件内容生成 aclocal.m4

aclocal-1.16 指向 aclocal 的硬链接

automake 一个根据 Makefile.am 文件,自动生成 Makefile.in 文件的工具 [为了创建软件包中的所有 Makefile.in 文件,在顶层目录运行该程序。它通过扫描 configure.in 文件,找到每个适用的 Makefile.am 文件,并生成对应的 Makefile.in 文件。]

automake-1.16 指向 automake 的硬链接

8.46 OpenSSL-3.0.8


OpenSSL 软件包包含密码学相关的管理工具和库。它们被用于向其他软件包提供密码学功能,例如 OpenSSH,电子邮件程序和 Web 浏览器 (以访问 HTTPS 站点)。

估计构建时间: 3.2 SBU

需要硬盘空间: 520 MB

8.46.1 安装 OpenSSL

准备编译 OpenSSL:

./config --prefix=/usr         \
         --openssldir=/etc/ssl \
         --libdir=lib          \
         shared                \
         zlib-dynamic

编译该软件包:

make

运行命令以测试编译结果:

make test

一项名为 30-test_afalg.t 的测试在某些 (CONFIG_CRYPTO_USER_API* 设定不一致的) 内核配置下会失败。如果它失败,可以放心地忽略它。

安装该软件包:

sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile
make MANSUFFIX=ssl install

将版本号添加到文档目录名,以和其他软件包保持一致:

mv -v /usr/share/doc/openssl /usr/share/doc/openssl-3.0.8

如果需要的话,安装一些额外的文档:

cp -vfr doc/* /usr/share/doc/openssl-3.0.8

注意

一旦新版的 OpenSSL 被发布,且它包含对安全缺陷的修复,就应该更新 OpenSSL。从 OpenSSL 3.0.0 起,OpenSSL 的版本号使用主版本号.次版本号.修订号的格式。主版本号相同的版本更新保证 API 与 ABI 的兼容性。由于 LFS 只安装共享库,没有必要重新编译链接到 libcrypto.so 或者 libssl.so 的软件包,前提是更新前后主版本号不变。

然而,需要重新启动链接到这两个库的,正在运行的程序。详见第 8.2.1 节 “升级问题”中的相关条目。

8.46.2 OpenSSL 的内容

安装的程序: c_rehash 和 openssl

安装的库: libcrypto.so 和 libssl.so

安装的目录: /etc/ssl, /usr/include/openssl, /usr/lib/engines 以及 /usr/share/doc/openssl-3.0.8

简要描述

c_rehash 一个 Perl 脚本,扫描一个目录中的所有文件,并添加它们的符号链接,符号链接名为对应文件的散列值。c_rehash 已弃用,应该使用 openssl rehash 命令替代它

openssl 一个命令行工具,用于从 shell 使用 OpenSSL的密码学库的一些密码学函数。它可以被用于 man 1 openssl描述的许多功能

libcrypto.so 实现不同 Internet 标准使用的许多密码学算法。该库提供的服务被 OpenSSL 的 SSL、TLS 和 S/MIME 实现使用,也被用于实现 OpenSSH、OpenPGP,以及其他密码学标准

libssl.so 实现传输层安全 (TLS v1) 协议。它提供了丰富的 API,这些 API 的文档可以通过执行 man 7 ssl查阅

8.47 Kmod-30


Kmod 软件包包含用于加载内核模块的库和工具。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 12 MB

8.47.1 安装 Kmod

准备编译 Kmod:

./configure --prefix=/usr          \
            --sysconfdir=/etc      \
            --with-openssl         \
            --with-xz              \
            --with-zstd            \
            --with-zlib

配置选项的含义:

–with-openssl

该选项允许 Kmod 处理内核模块的 PKCS7 数字签名。

–with-xz,–with-zlib,以及 –with-zstd

这些选项允许 Kmod 处理压缩过的内核模块。

编译该软件包:

make

该软件包的测试套件需要内核的原始头文件 (不是之前安装的 “净化的” 内核头文件),原始头文件超出了 LFS 的范畴。

安装该软件包,并创建与 Module-Init-Tools (曾经用于处理 Linux 内核模块的软件包) 兼容的符号链接:

make install

for target in depmod insmod modinfo modprobe rmmod; do
  ln -sfv ../bin/kmod /usr/sbin/$target
done

ln -sfv kmod /usr/bin/lsmod

8.47.2 Kmod 的内容

安装的程序: depmod (到 kmod 的链接), insmod (到 kmod 的链接), kmod, lsmod (到 kmod 的链接), modinfo (到 kmod 的链接), modprobe (到 kmod 的链接), 以及 rmmod (到 kmod 的链接)

安装的库: libkmod.so

简要描述

depmod 根据现有模块的符号信息创建依赖关系文件;modprobe 使用依赖关系文件自动加载需要的模块

insmod 在正在运行的内核中安装可加载模块

kmod 加载或卸载内核模块

lsmod 列出当前加载的模块

modinfo 检验与某个内核模块相关的目标文件,打印它能够收集到的一切信息

modprobe 使用一个 depmod 创建的依赖关系文件,自动加载相关模块

rmmod 从正在运行的内核中卸载模块

libkmod 这个库被其他程序用于加载和卸载内核模块

8.48 Libelf from Elfutils-0.188


Libelf 是一个处理 ELF (可执行和可链接格式) 文件的库。

估计构建时间: 0.3 SBU

需要硬盘空间: 120 MB

8.48.1 安装 Libelf

Libelf 是 elfutils-0.188 软件包的一部分。请使用 elfutils-0.188.tar.bz2 作为源代码包。

准备编译 Libelf:

./configure --prefix=/usr                \
            --disable-debuginfod         \
            --enable-libdebuginfod=dummy

编译该软件包:

make

运行命令以测试编译结果:

make check

已知一项名为 run-native-test.sh 的测试可能失败。

只安装 Libelf:

make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
rm /usr/lib/libelf.a

8.48.2 Libelf 的内容

安装的库: libelf.so (符号链接) 和 libelf-0.188.so

安装的目录: /usr/include/elfutils

简要描述

libelf 包含处理 ELF 目标文件的 API 函数

8.49 Libffi-3.4.4


Libffi 库提供一个可移植的高级编程接口,用于处理不同调用惯例。这允许程序在运行时调用任何给定了调用接口的函数。

FFI 是 Foreign Function Interface (跨语言函数接口) 的缩写。FFI 允许使用某种编程语言编写的程序调用其他语言编写的程序。特别地,Libffi 为 Perl 或 Python 等解释器提供使用 C 或 C++ 编写的共享库中子程序的能力。

估计构建时间: 1.8 SBU

需要硬盘空间: 11 MB

8.49.1 安装 Libffi

注意

和 GMP 类似,Libffi 在构建时会使用特定于当前处理器的优化。如果是在为另一台计算机构建系统,请将 –with-gcc-arch= 的设定值改为那一台计算机的 CPU 完全实现的某个架构名称。否则,所有链接到 libffi 的程序都可能触发非法指令异常。

准备编译 Libffi:

./configure --prefix=/usr          \
            --disable-static       \
            --with-gcc-arch=native

配置选项的含义:

–with-gcc-arch=native

保证 gcc 为当前系统进行优化。如果不使用该选项,构建系统会猜测系统架构,可能生成不正确的代码。如果要将生成的代码从本地系统复制到指令集功能较弱的系统中,需要使用目标系统架构作为该选项的参数值。关于不同系统架构的信息,参阅 gcc 手册中提供的的 x86 选项

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.49.2 Libffi 的内容

安装的库: libffi.so

简要描述

libffi 包含跨语言函数接口 API 函数

8.50 Python-3.11.2


Python 3 软件包包含 Python 开发环境。它被用于面向对象编程,编写脚本,为大型程序建立原型,或者开发完整的应用。Python 是一种解释性的计算机语言。

估计构建时间: 2.0 SBU

需要硬盘空间: 372 MB

8.50.1 安装 Python 3

准备编译 Python:

./configure --prefix=/usr        \
            --enable-shared      \
            --with-system-expat  \
            --with-system-ffi    \
            --enable-optimizations

配置选项的含义:

–with-system-expat

该选项允许链接到系统已经安装的 Expat。

–with-system-ffi

该选项允许链接到系统已经安装的 libffi.so。

–enable-optimizations

该选项启用有力,但是消耗时间的优化步骤。它会两次构建解释器;在初次构建结果上运行测试,并使用测试结果优化最终构建版本的性能。

编译该软件包:

make

不建议在此时运行测试。在不完整的 LFS 环境中,测试可能会永远陷入等待状态。如果希望运行测试,可以在本章结束时,或者在 BLFS 中重新安装 Python 3 时再运行测试。如果一定要进行测试,运行 make test。

安装该软件包:

make install

在本书中,我们以 root 用户身份,使用 pip3 命令,为所有用户安装 Python 3 程序和模块。这和 Python 开发者的建议不同:他们认为应该将这些包安装到虚拟环境中,或者某个用户的主目录中 (即,以该用户身份执行 pip3 命令)。只要使用 root 用户身份执行 pip3 命令,它就会输出若干行警告信息。

这项建议主要是为了避免和系统包管理器 (如 dpkg) 的冲突。LFS 没有系统包管理器,所以不存在这个问题。另外,pip3 在运行时,会检查它的最新版本。由于 LFS chroot 环境中没有配置域名解析,pip3 无法检查它的最新版本,也会输出一条警告信息。

在引导 LFS 系统并配置网络连接后,则会出现一条不同的警告信息,指示用户使用 PyPI 提供的,预先构建的 wheel 档案更新 pip3 (如果有更新的版本)。但是对于 LFS,我们认为 pip3 是 Python 3 的一部分,因此不应单独升级它。另外,使用预先构建的 wheel 包也会偏离我们的目标:从源代码构建 Linux 系统。因此,应该忽略关于 pip3 新版本的警告。如果您不想看到这些警告,可以执行以下命令,创建配置文件,以禁止这些警告:

cat > /etc/pip.conf << EOF
[global]
root-user-action = ignore
disable-pip-version-check = true
EOF

重要

在 LFS 和 BLFS 中,我们通常用 pip3 命令构建和安装 Python 模块。请注意两份手册中的 pip3 install 命令都应该以 root 身份运行 (除非这条命令是为 Python 虚拟环境进行安装)。以非 root 用户身份运行 pip3 install 命令可能看似正常工作,但这会导致其他用户无法访问安装的模块。

pip3 install 在不会自动重新安装已经安装好的模块。如果需要用 pip3 install 命令升级模块 (例如,从 meson-0.61.3 升级到 meson-0.62.0),则需要在命令行中加入 –upgrade 选项。如果由于某种原因,确实需要降级某个模块,或重新安装某个已安装的版本,需要在命令行中加入 –force-reinstall –no-deps 选项。

如果需要的话,安装预先格式化的文档:

install -v -dm755 /usr/share/doc/python-3.11.2/html

tar --strip-components=1  \
    --no-same-owner       \
    --no-same-permissions \
    -C /usr/share/doc/python-3.11.2/html \
    -xvf ../python-3.11.2-docs-html.tar.bz2

文档安装命令的含义:

–no-same-owner–no-same-permissions

保证安装的文件拥有正确的所有者和权限模式。在没有这些选项的时候,tar 会以上游开发者使用的用户和权限模式安装文件。

8.50.2 Python 3 的内容

安装的程序: 2to3, idle3, pip3, pydoc3, python3, 以及 python3-config

安装的库: libpython3.11.so 和 libpython3.so

安装的目录: /usr/include/python3.11, /usr/lib/python3 以及 /usr/share/doc/python-3.11.2

简要描述

2to3 是一个 Python 程序,读取 Python 2.x 源代码并对它进行一系列修正,转换成合法的 Python 3.x 源代码

idle3 一个封装脚本,启动支持 Python 语法的 GUI 文本编辑器。要运行这个脚本,必须在 Python 之前安装 Tk,从而构建 Tkinter Python 模块。

pip3 Python 包安装器。您可以使用 pip 安装来自 Python 软件包目录或其他目录的包。

pydoc3 是 Python 文档工具

python3 是 Python 的解释器,Python 是一种解释性的、交互的、面向对象的程序设计语言

8.51 Wheel-0.38.4


Wheel 是 Python wheel 软件包标准格式的参考实现。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 1.3 MB

8.51.1 安装 Wheel

执行以下命令编译 Wheel:

PYTHONPATH=src pip3 wheel -w dist --no-build-isolation --no-deps $PWD

使用以下命令安装 Wheel:

pip3 install --no-index --find-links=dist wheel

pip3 配置选项和命令的含义:

PYTHONPATH=src

允许使用 (尚未安装的) 该软件包构建它本身的 wheel 档案,以避免“先有鸡还是先有蛋”的问题。

wheel

该命令构建该软件包的 wheel 档案。

-w dist

指示 pip 将生成的 wheel 包置入 dist 目录。

install

该命令安装该软件包。

–no-build-isolation, –no-deps, 以及 –no-index

这些选项防止 pip 从在线软件包仓库 (PyPI) 获取文件。如果按正确的顺序安装软件包,则 pip 完全不会尝试获取文件;但是在用户不小心犯下错误时,这些选项可以作为保险措施。

–find-links dist

指示 pip 在 dist 目录中搜索 wheel 档案。

8.51.2 Wheel 的内容

安装的程序: wheel

安装的目录: /usr/lib/python3.11/site-packages/wheel 和 /usr/lib/python3.11/site-packages/wheel-0.38.4.dist-info

简要描述

wheel 是用于解包、包装,或者转换 wheel 档案的工具

8.52 Ninja-1.11.1


Ninja 是一个注重速度的小型构建系统。

估计构建时间: 0.3 SBU

需要硬盘空间: 77 MB

提示

如果不使用 systemd,本节内容不是严格必要的。但是,Ninja 和 Meson 组成一个强大的构建系统,预期这一组合将被越来越广泛地使用。BLFS 手册中的一些软件包需要它。

8.52.1 安装 Ninja

在运行时,ninja 通常并行运行尽可能多的进程。默认情况下最大进程数是系统 CPU 核心数加 2 得到的值。这可能导致 CPU 过热,或者耗尽系统内存。如果使用命令行执行 ninja,可以传递 -jN 参数以限制并行进程数。但是,某些软件包内嵌了 ninja 的执行过程,且并不传递 -j 参数。

应用下面这个可选的修改,用户即可通过一个环境变量 NINJAJOBS 限制并行进程数量。例如设置:

export NINJAJOBS=4

会限制 ninja 使用 4 个并行进程。

如果希望 ninja 能够识别环境变量 NINJAJOBS,使用流编辑器,添加这一功能:

sed -i '/int Guess/a \
  int   j = 0;\
  char* jobs = getenv( "NINJAJOBS" );\
  if ( jobs != NULL ) j = atoi( jobs );\
  if ( j > 0 ) return j;\
' src/ninja.cc

构建 Ninja:

python3 configure.py --bootstrap

构建选项的含义:

–bootstrap

这个参数强制 Ninja 为当前系统重新构建自身。

运行命令以测试编译结果:

./ninja ninja_test
./ninja_test --gtest_filter=-SubprocessTest.SetWithLots

安装该软件包:

install -vm755 ninja /usr/bin/
install -vDm644 misc/bash-completion /usr/share/bash-completion/completions/ninja
install -vDm644 misc/zsh-completion  /usr/share/zsh/site-functions/_ninja

8.52.2 Ninja 的内容

安装的程序: ninja

简要描述

ninja 是 ninja 构建系统

8.53 Meson-1.0.0


Meson 是一个开放源代码构建系统,它的设计保证了非常快的执行速度,和尽可能高的用户友好性。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 41 MB

提示

如果不使用 systemd,本节内容不是严格必要的。但是,Meson 和 Ninja 组成一个强大的构建系统,预期这一组合将被越来越广泛地使用。BLFS 手册中的一些软件包需要它。

8.53.1 安装 Meson

执行以下命令编译 Meson:

pip3 wheel -w dist --no-build-isolation --no-deps $PWD

测试套件需要一些超过 LFS 覆盖范围的软件包。

安装该软件包:

pip3 install --no-index --find-links dist meson
install -vDm644 data/shell-completions/bash/meson /usr/share/bash-completion/completions/meson
install -vDm644 data/shell-completions/zsh/_meson /usr/share/zsh/site-functions/_meson

安装选项的含义:

-w dist

将生成的 wheel 包置入 dist 目录。

–find-links dist

从 dist 目录安装 wheel 包。

8.53.2 Meson 的内容

安装的程序: meson

安装的目录: /usr/lib/python3.11/site-packages/meson-1.0.0.dist-info 和 /usr/lib/python3.11/site-packages/mesonbuild

简要描述

meson 一个高产出的构建系统

8.54 Coreutils-9.1


Coreutils 软件包包含各种操作系统都需要提供的基本工具程序。

估计构建时间: 0.9 SBU

需要硬盘空间: 156 MB

8.54.1 安装 Coreutils

POSIX 要求 Coreutils 中的程序即使在多字节 locale 中也能正确识别字符边界。下面应用一个补丁,以解决 Coreutils 不满足该要求的问题,并修复其他一些国际化相关的 bug:

patch -Np1 -i ../coreutils-9.1-i18n-1.patch

注意

在之前,这个补丁中找出了许多 bug。在向 Coreutils 维护者报告新 bug 前,请检查这些 bug 在不使用该补丁的情况下是否还会重现。

现在准备编译 Coreutils:

autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
            --prefix=/usr            \
            --enable-no-install-program=kill,uptime

配置选项的含义:

autoreconf

国际化补丁修改了构建系统,因此需要重新生成配置文件:

FORCE_UNSAFE_CONFIGURE=1

该环境变量允许以 root 用户身份构建该软件包。

–enable-no-install-program=kill,uptime

这个开关用于防止 Coreutils 安装那些被其他软件包安装的二进制程序。

编译该软件包:

make

如果不运行测试套件,直接跳到 “安装该软件包”。

现在测试套件已经可以运行了。首先运行那些设计为由 root 用户运行的测试:

make NON_ROOT_USERNAME=tester check-root

之后我们要以 tester 用户身份运行其余测试。然而,某些测试要求测试用户属于至少一个组。为了不跳过这些测试,我们添加一个临时组,并使得 tester 用户成为它的成员:

echo "dummy:x:102:tester" >> /etc/group

修正访问权限,使得非 root 用户可以编译和运行测试:

chown -Rv tester . 

现在运行测试:

su tester -c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"

名为 test-getlogin 的测试在 LFS chroot 环境中可能失败。

删除临时组:

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

安装该软件包:

make install

将程序移动到 FHS 要求的位置:

mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' /usr/share/man/man8/chroot.8

8.54.2 Coreutils 的内容

安装的程序: [, b2sum, base32, base64, basename, basenc, cat, chcon, 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, id, install, join, link, ln, logname, ls, md5sum, mkdir, mkfifo, mknod, mktemp, mv, nice, nl, nohup, nproc, numfmt, od, paste, pathchk, pinky, pr, printenv, printf, ptx, pwd, readlink, realpath, rm, rmdir, runcon, seq, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, shred, shuf, sleep, sort, split, stat, stdbuf, stty, sum, sync, tac, tail, tee, test, timeout, touch, tr, true, truncate, tsort, tty, uname, unexpand, uniq, unlink, users, vdir, wc, who, whoami, 以及 yes

安装的库: libstdbuf.so (在 /usr/libexec/coreutils 中)

安装的目录: /usr/libexec/coreutils

简要描述

[ 这是一个真实存在的命令,/usr/bin/[;它和 test 命令的功能相同

base32 根据 base32 标准 (RFC 4648) 编码和解码数据

base64 根据 base64 标准 (RFC 4648) 编码和解码数据

b2sum 打印或检查 BLAKE2 (512 位) 校验和

basename 从文件名移除所有路径和一个给定后缀

basenc 使用一些算法编码或解码数据

cat 将文件合并到标准输出

chcon 修改文件和目录的 SELinux 安全上下文

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 打印文件的前 10 (或给定行数) 行

hostid 以十六进制格式打印主机数字标识符

id 报告当前用户或给定用户的有效用户 ID、组 ID 和所属的组

install 复制文件并设定它们的访问权限,以及 (如果可能) 它们的所有者和属组

join 将两个文件中拥有相同域的行合并

link (以给定文件名) 创建硬链接

ln 在文件之间创建硬链接或软 (符号) 链接

logname 报告当前用户登录名

ls 列出给定目录内容

md5sum 报告或检查消息摘要 5 (MD5) 校验和

mkdir 以给定名称创建目录

mkfifo 以给定名称创建先进先出 (FIFO),在 UNIX 惯用语中又称为 “命名管道”

mknod 以给定名称创建设备节点;设备节点可能是字符特殊文件、块特殊文件或 FIFO

mktemp 安全地创建临时文件,常用在脚本中

mv 移动或重命名文件或目录

nice 以修改的调度优先级运行程序

nl 标出给定文件的行

nohup 执行命令并使其忽略挂机信号,同时将输出重定向到日志文件

nproc 打印进程可用的处理单元数目

numfmt 在数字和人类可读字符串之间互相转换

od 以八进制或其他格式转储文件

paste 合并给定文件,将它们的对应行连接起来,以制表符分割

pathchk 检查文件名的有效性和可移植性

pinky 是轻量级 finger 客户端,报告给定用户的一些信息

pr 对文件进行分页和分栏以便打印

printenv 打印环境变量

printf 以给定格式打印给定参数,很像 C printf 函数

ptx 用文中的每个关键字,根据给定文件内容生成重排索引

pwd 报告当前工作目录名

readlink 报告给定符号链接的值

realpath 打印解析过的目录

rm 删除文件或目录

rmdir 如果目录是空的,删除它们

runcon 以给定 SELinux 安全上下文运行命令

seq 以给定的范围和增量打印等差数列

sha1sum 打印或检查 160 位安全散列算法 1 (SHA1) 校验和

sha224sum 打印或检查 224 位安全散列算法校验和

sha256sum 打印或检查 256 位安全散列算法校验和

sha384sum 打印或检查 384 位安全散列算法校验和

sha512sum 打印或检查 512 位安全散列算法校验和

shred 将给定文件多次用复杂模式覆盖,增加恢复数据的难度

shuf 打乱文件中的行

sleep 等待给定时间

sort 对给定文件的行进行排序

split 根据大小或行数,将指定文件分割成若干部分

stat 显示文件或文件系统状态

stdbuf 以修改的标准流缓冲操作运行命令

stty 设置或报告终端行设定

sum 打印每个指定文件的校验和及块个数

sync 刷新文件系统缓冲;它将修改过的块强制写入磁盘,并更新超级块

tac 逆序连接给定文件

tail 输出给定文件的最后 10 (或指定行数) 行

tee 读取标准输入,并将内容同时写入标准输出和给定文件

test 比较两个值,或检查文件类型

timeout 在限定时间内运行命令

touch 修改文件时间戳,将每个给定文件的访问和修改时间设为当前时间; 以零长度创建当前不存在的文件

tr 从标准输入变换、压缩或删除给定字符

true 什么也不做;总是以成功状态码退出

truncate 将文件截断或扩展到指定大小

tsort 进行拓扑排序;根据给定文件的部分顺序信息输出完整的排序列表

tty 报告标准输入的终端文件名

uname 报告系统信息

unexpand 将空格转换成制表符

uniq 在连续的相同行中只保留一行,删除其他所有行

unlink 删除给定文件

users 报告当前登录系统的用户名

vdir 和 ls -l 相同

wc 报告给定文件的行数、单词数和字节数,如果给定了多个文件,还会输出这些统计值的总和

who 报告当前登录的用户

whoami 报告与当前有效用户 ID 相关的用户名

yes 不停输出 “y”,或给定的字符串,直到被杀死

libstdbuf stdbuf 使用的库

8.55 Check-0.15.2


Check 是一个 C 语言单元测试框架。

估计构建时间: 0.1 SBU (计入测试时间为约 1.7 SBU)

需要硬盘空间: 12 MB

8.55.1 安装 Check

准备编译 Check:

./configure --prefix=/usr --disable-static

构建该软件包:

make

现在编译已经完成,执行以下命令执行 Check 测试套件:

make check

安装该软件包:

make docdir=/usr/share/doc/check-0.15.2 install

8.55.2 Check 的内容

安装的程序: checkmk

安装的库: libcheck.so

简要描述

checkmk 用于生成 C 语言单元测试的 awk 脚本,生成的单元测试可以和 Check 单元测试框架一起使用

libcheck.so 包含使得测试程序能够调用 Check 的函数

8.56 Diffutils-3.9


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

估计构建时间: 0.3 SBU

需要硬盘空间: 35 MB

8.56.1 安装 Diffutils

准备编译 Diffutils:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.56.2 Diffutils 的内容

安装的程序: cmp, diff, diff3, 以及 sdiff

简要描述

cmp 逐字节比较两个文件并报告它们的不同之处

diff 比较两个文件或目录,并报告文件中哪些行不同

diff3 逐行比较三个文件

sdiff 合并两个文件,并交互地输出结果

8.57 Gawk-5.2.1


Gawk 软件包包含操作文本文件的程序。

估计构建时间: 0.2 SBU

需要硬盘空间: 43 MB

8.57.1 安装 Gawk

首先,确保不安装某些不需要的文件:

sed -i 's/extras//' Makefile.in

准备编译 Gawk:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make LN='ln -f' install

被覆盖的 make 变量的含义:

LN=’ln -f’

该变量保证之前在第 6.9 节 “Gawk-5.2.1”中安装的硬链接被正确更新。

如果需要,安装该软件包的文档:

mkdir -pv                                   /usr/share/doc/gawk-5.2.1
cp    -v doc/{awkforai.txt,*.{eps,pdf,jpg}} /usr/share/doc/gawk-5.2.1

8.57.2 Gawk 的内容

安装的程序: awk (到 gawk 的链接), gawk, 以及 gawk-5.2.1

安装的库: filefuncs.so, fnmatch.so, fork.so, inplace.so, intdiv.so, ordchr.so, readdir.so, readfile.so, revoutput.so, revtwoway.so, rwarray.so, 以及 time.so (均位于 /usr/lib/gawk 中)

安装的目录: /usr/lib/gawk, /usr/libexec/awk, /usr/share/awk, 以及 /usr/share/doc/gawk-5.2.1

简要描述

awk 到 gawk 的链接

gawk 一个操作文本文件的程序;是 awk 的 GNU 实现

gawk-5.2.1 与 gawk 互为硬链接

8.58 Findutils-4.9.0


Findutils 软件包包含用于查找文件的程序。这些程序能直接搜索目录树中的所有文件,也可以创建、维护和搜索文件数据库 (一般比递归搜索快,但在数据库最近没有更新时不可靠)。Findutils 还提供了 xargs 程序,它能够对一次搜索列出的素有文件执行给定的命令。

估计构建时间: 0.4 SBU

需要硬盘空间: 51 MB

8.58.1 安装 Findutils

准备编译 Findutils:

case $(uname -m) in
    i?86)   TIME_T_32_BIT_OK=yes ./configure --prefix=/usr --localstatedir=/var/lib/locate ;;
    x86_64) ./configure --prefix=/usr --localstatedir=/var/lib/locate ;;
esac

配置选项的含义:

TIME_32_BIT_OK=yes

该设定对于在 32 位系统中构建该软件包是必要的。

–localstatedir

该选项将 locate 数据库移动到 /var/lib/locate,以与 FHS 兼容。

编译该软件包:

make

运行命令以测试编译结果:

chown -Rv tester .
su tester -c "PATH=$PATH make check"

安装该软件包:

make install

8.58.2 Findutils 的内容

安装的程序: find, locate, updatedb, 以及 xargs

安装的目录: /var/lib/locate

简要描述

find 在给定目录树中搜索满足给定条件的文件

locate 在文件名数据库中进行搜索,报告包含特定字符串或匹配特定模式的文件名

updatedb 更新 locate 数据库;它扫描整个文件系统 (包括当前挂载的其他文件系统,除非被告知不这样做),并把找到的所有文件名加入数据库

xargs 可以将给定命令作用于一个列表中的所有文件

8.59 Groff-1.22.4


Groff 软件包包含处理和格式化文本和图像的程序。

估计构建时间: 0.2 SBU

需要硬盘空间: 89 MB

8.59.1 安装 Groff

Groff 期望环境变量 PAGE 包含默认纸张大小。对于美国用户来说,PAGE=letter 是正确的。对于其他地方的用户,PAGE=A4 可能更好。尽管在编译时配置了默认纸张大小,可以通过写入 “A4” 或 “letter” 到 /etc/papersize 文件,覆盖默认值。

准备编译 Groff:

PAGE=<paper_size> ./configure --prefix=/usr

构建该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make install

8.59.2 Groff 的内容

安装的程序: addftinfo, afmtodit, chem, eqn, eqn2graph, gdiffmk, glilypond, gperl, gpinyin, grap2graph, grn, grodvi, groff, groffer, grog, grolbp, grolj4, gropdf, grops, grotty, hpftodit, indxbib, lkbib, lookbib, mmroff, neqn, nroff, pdfmom, pdfroff, pfbtops, pic, pic2graph, post-grohtml, preconv, pre-grohtml, refer, roff2dvi, roff2html, roff2pdf, roff2ps, roff2text, roff2x, soelim, tbl, tfmtodit, 以及 troff

安装的目录: /usr/lib/groff, /usr/share/doc/groff-1.22.4, 以及 /usr/share/groff

简要描述

addftinfo 读取 troff 字体文件并为其添加 groff 系统使用的一些额外字体规格信息

afmtodit 创建供 groff 和 grops 使用的字体文件

chem 产生化学结构式的 groff 预处理器

eqn 将 troff 输入文件中嵌入的公式描述编译成 troff 理解的命令

eqn2graph 将 troff EQN (公式) 转换成裁减好的图像

gdiffmk 标出 groff/nroff/troff 文件的区别

glilypond 将 lilypond 语言写成的乐谱转换为 groff 语言

gperl groff 预处理器,允许在 groff 文件中插入 perl 代码

gpinyin groff 的预处理器,允许在 groff 文件中增加汉语拼音

grap2graph 将 grap 程序文件转换成裁切好的位图 (grap 是一门古老的,用于创建示意图的 Unix 编程语言)。

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 是一个生成用于 HP LaserJet 4 打印机的 PCL5 格式的 groff 驱动程序

gropdf 将 troff 输出转换成 PDF

grops 将 troff 输出转换成 PostScript

grotty 将 troff 输出转换成用于打字机类设备的形式

hpftodit 根据 HP 标签的字体规格文件,创建用于 groff -Tlj4的字体文件

indxbib 创建用于给定文件文献数据库的反向索引,以供 refer、lookbib 以及 lkbib 使用

lkbib 在文献数据库中搜索包含指定关键字的引用,并报告找到的所有引用

lookbib 在标准错误输出上显示命令提示符 (除非标准输入不是终端),读取包含一组关键字的行,在给定文件的文献数据库中搜索包含这些关键字的引用,将它们打印到标准输出,重复这一过程直到输入结束

mmroff groff 的简单预处理器

neqn 将公式格式化为美国标准信息交换代码 (ASCII) 输出

nroff 一个使用 groff 仿真 nroff 命令的脚本

pdfmom 一个 groff 包装器,提供从 mom 宏包编码的文件转换为 PDF 文档的功能

pdfroff 用 groff 创建 PDF 文档

pfbtops 将 .pfb 格式的 PostScript 字体转换为 ASCII

pic 将 troff 或 TeX 输入文件中嵌入的图片描述编译成 TeX 或 troff 理解的命令

pic2graph 将 PIC 图示转换成裁切好的图像

post-grohtml 将 GNU troff 的输出翻译成 HTML

preconv 将输入文件的编码转换成 GNU troff 理解的格式

pre-grohtml 将 GNU troff 的输出翻译成 HTML

refer 将文件内容复制到标准输出,除了在 .[ 和 .] 之间的行被解释为文献引用,.R1 和 .R2 之间的行被解释为处理文献引用的方式

roff2dvi 将 roff 文件转换成 DVI 格式

roff2html 将 roff 文件转换成 HTML 格式

roff2pdf 将 roff 文件转换成 PDF

roff2ps 将 roff 文件转换成 ps 文件

roff2text 将 roff 文件转换成文本文件

roff2x 将 roff 文件转换成其他格式

soelim 读取文件,将 .so 文件 形式的行替换为该文件的内容

tbl 将 troff 输入中嵌入的表格描述编译成 troff 理解的命令

tfmtodit 创建用于 groff -Tdvi 的字体文件

troff 和 UNIX troff 高度兼容;它应该由 groff 命令调用,后者也会以正确的顺序和选项运行预处理器和后处理器

8.60 GRUB-2.06


GRUB 软件包包含 “大统一” (GRand Unified) 启动引导器。

估计构建时间: 0.3 SBU

需要硬盘空间: 161 MB

8.60.1 安装 GRUB

注意

如果您的系统支持 UEFI,且您希望通过 UEFI 引导 LFS,您可以跳过这个 LFS 软件包,并按照 BLFS 页面中的说明,安装支持 UEFI 的 GRUB (及其依赖项)。

警告

移除所有可能影响构建的环境变量:

unset {C,CPP,CXX,LD}FLAGS

不要尝试使用自定义的编译选项“优化”该软件包。该软件包是一个引导加载器,其源代码中的低级操作可能被一些激进的优化所破坏。

修复导致 grub-install 在 /boot 分区 (或者根分区,如果 /boot 不是一个独立分区) 由 e2fsprogs-1.47.0 或更新版本创建时运行失败的问题:

patch -Np1 -i ../grub-2.06-upstream_fixes-1.patch

准备编译 GRUB:

./configure --prefix=/usr          \
            --sysconfdir=/etc      \
            --disable-efiemu       \
            --disable-werror

新的配置选项的含义:

–disable-werror

该选项允许在有较新的 Flex 版本导致的警告时完成构建。

–disable-efiemu

该选项通过禁用 LFS 不需要的特性和测试程序,最小化需要构建的内容。

编译该软件包:

make

不推荐运行该软件包的测试套件。许多测试依赖于在 LFS 的有限环境中不存在的软件包。如果一定要进行测试,运行 make check。

安装该软件包:

make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions

使用 GRUB 引导您的 LFS 系统的方法将在第 10.4 节 “使用 GRUB 设定引导过程”中讨论。

8.60.2 GRUB 的内容

安装的程序: grub-bios-setup, grub-editenv, grub-file, grub-fstest, grub-glue-efi, grub-install, grub-kbdcomp, grub-macbless, grub-menulst2cfg, grub-mkconfig, grub-mkimage, grub-mklayout, grub-mknetdir, grub-mkpasswd-pbkdf2, grub-mkrelpath, grub-mkrescue, grub-mkstandalone, grub-ofpathname, grub-probe, grub-reboot, grub-render-label, grub-script-check, grub-set-default, grub-sparc64-setup, 以及 grub-syslinux2cfg

安装的目录: /usr/lib/grub, /etc/grub.d, /usr/share/grub, 以及 /boot/grub (在初次运行 grub-install 时安装)

简要描述

grub-bios-setup 是 grub-install 使用的辅助程序

grub-editenv 是一个用于编辑环境块的工具

grub-file 检验文件是否是给定类型

grub-fstest 是一个调试文件系统驱动程序的工具

grub-glue-efi 将 32 位和 64 位二进制文件结合成一个文件 (以便在 Apple 生产的机器使用)。

grub-install 在您的驱动器上安装 GRUB

grub-kbdcomp 是一个脚本,用于将 xkb 布局转化为 GRUB 能够识别的格式

grub-macbless 是 Mac 风格的,用于 HFS 和 HFS+ 文件系统的 bless 程序 (bless 仅用于 Apple 生产的机器;它能将设备变得可引导)

grub-menulst2cfg 将经典的 GRUB menu.lst 转化为 grub.cfg 以供 GRUB 2 使用

grub-mkconfig 生成一个 grub.cfg 文件

grub-mkimage 创建 GRUB 可引导镜像

grub-mklayout 生成 GRUB 键盘布局文件

grub-mknetdir 准备 GRUB 网络启动目录

grub-mkpasswd-pbkdf2 生成用于引导菜单的加密 PBKDF2 密码

grub-mkrelpath 生成相对于根目录的系统路径名称

grub-mkrescue 为软盘,CDROM/DVD,或 USB 设备创建 GRUB 可引导镜像

grub-mkstandalone 生成独立 (包含所有模块) 的镜像

grub-ofpathname 打印 GRUB 设备路径的帮助程序

grub-probe 探测给定路径或设备的信息

grub-reboot 仅为下次启动设置 GRUB 默认引导项

grub-render-label 为 Apple Mac 设置 Apple .disk_label

grub-script-check 在 GRUB 配置脚本中检查语法错误

grub-set-default 设置 GRUB 默认引导项

grub-sparc64-setup grub-setup 使用的帮助程序

grub-syslinux2cfg 将 syslinux 配置文件转换为 grub.cfg 格式

8.61 Gzip-1.12


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

估计构建时间: 0.3 SBU

需要硬盘空间: 21 MB

8.61.1 安装 Gzip

准备编译 Gzip:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.61.2 Gzip 的内容

安装的程序: gunzip, gzexe, gzip, uncompress (与 gunzip 互为硬链接), zcat, zcmp, zdiff, zegrep, zfgrep, zforce, zgrep, zless, zmore, 以及 znew

简要描述

gunzip 解压缩 gzip 压缩的文件

gzexe 创建自解压可执行文件

gzip 使用 Lempel-Ziv (LZ77) 编码压缩文件

uncompress 解压压缩文件

zcat 将给定 gzip 压缩文件解压到标准输出

zcmp 在 gzip 压缩文件上运行 cmp

zdiff 在 gzip 压缩文件上运行 diff

zegrep 在 gzip 压缩文件上运行 egrep

zfgrep 在 gzip 压缩文件上运行 fgrep

zforce 为给定所有文件中的 gzip 压缩文件确保 .gz 扩展名,这样 gzip 就不会重复压缩它们;在文件传输过程中文件名被截断时,这个命令很有用

zgrep 在 gzip 压缩文件上运行 grep

zless 在 gzip 压缩文件上运行 less

zmore 在 gzip 压缩文件上运行 more

znew 将 compress 格式压缩文件重新压缩为 gzip 格式 —— 转换 .Z 文件为 .gz 文件

8.62 IPRoute2-6.1.0


IPRoute2 软件包包含基于 IPv4 的基本和高级网络程序。

估计构建时间: 0.1 SBU

需要硬盘空间: 17 MB

8.62.1 安装 IPRoute2

该软件包中的 arpd 程序依赖于 LFS 不安装的 Berkeley DB,因此不会被构建。然而,用于 arpd 的一个目录和它的 man 页面仍会被安装。运行以下命令以防止它们的安装。(如果需要使用 arpd 二进制程序,参考 BLFS 手册中的 Berkeley DB 编译说明,它位于 https://www.linuxfromscratch.org/blfs/view/11.3/server/db.html。)

sed -i /ARPD/d Makefile
rm -fv man/man8/arpd.8

编译该软件包:

make NETNS_RUN_DIR=/run/netns

该软件包没有能够工作的测试套件。

安装该软件包:

make SBINDIR=/usr/sbin install

如果需要,安装该软件包的文档:

mkdir -pv             /usr/share/doc/iproute2-6.1.0
cp -v COPYING README* /usr/share/doc/iproute2-6.1.0

8.62.2 IPRoute2 的内容

安装的程序: bridge, ctstat (到 lnstat 的链接), genl, ifstat, ip, lnstat, nstat, routel, rtacct, rtmon, rtpr, rtstat (到 lnstat 的链接), ss, 以及 tc

安装的目录: /etc/iproute2, /usr/lib/tc, 以及 /usr/share/doc/iproute2-6.1.0

简要描述

bridge 配置网桥

ctstat 连接状态工具

genl 通用网络连接工具前端

ifstat 显示网络接口统计信息,包含每个接口上发送和接收的数据包数量

ip 该软件包的主程序。它包含许多功能,例如:

            ip link <device> 允许用户查看和修改设备状态

            ip addr 允许用户查看网络地址及其属性,添加新地址或删除旧地址

            ip neigh 允许用户查看 ARP 近邻绑定及其属性,增加新近邻项,或删除旧项

            ip rule 允许用户查看或修改路由策略

            ip route 允许用户查看路由表或修改路由表规则

            ip tunnel 允许用户查看 IP 隧道及其属性,或修改它们

            ip maddr 允许用户查看多播地址及其属性,或修改它们

            ip mroute 允许用户设定、修改或删除多播路由

            ip monitor 允许用户连续地监视设备、地址和路由的状态

lnstat 提供 Linux 网络统计;它是旧的rtstat 的更通用、功能更完备的替代品

nstat 显示网络统计

routel ip route 的一个组件,用于显示路由表

rtacct 显示 /proc/net/rt_acct 的内容

rtmon 路由监视工具

rtpr 将 ip -o 的输出转换为可读形式

rtstat 路由状态工具

ss 与 netstat 命令相似;显示活动连接

tc 实现服务质量 (QoS) 和服务类型 (CoS) 协议的流量控制程序

            tc qdisc 允许用户设定排队规则

            tc class 允许用户设定基于排队规则调度的调度类

            tc filter 允许用户设定 QoS/CoS 数据包过滤

            tc monitor 可用于监视内核中流量控制策略的变化。

8.63 Kbd-2.5.1


Kbd 软件包包含按键表文件、控制台字体和键盘工具。

估计构建时间: 0.1 SBU

需要硬盘空间: 35 MB

8.63.1 安装 Kbd

退格和删除键的行为在 Kbd 软件包的不同按键映射中不一致。以下补丁修复 i386 按键映射中的这个问题:

patch -Np1 -i ../kbd-2.5.1-backspace-1.patch

在应用补丁后,退格键生成编码为 127 的字符,删除键生成广为人知的 escape 序列。

删除多余的 resizecons 程序 (它需要已经不存在的 svgalib 提供视频模式文件 —— 一般使用 setfont 即可调整控制台大小) 及其 man 页面。

sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in

准备编译 Kbd:

./configure --prefix=/usr --disable-vlock

配置选项的含义:

--disable-vlock

该选项防止构建 vlock 工具,因为它需要 chroot 环境中不可用的 PAM 库。

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

注意

对于一些语言 (如白俄罗斯文),Kbd 软件包没有提供有用的的键盘映射。它提供的白俄罗斯文 “by” 键盘映射假设使用 ISO-8859-5 编码,但通常应该使用的是 CP1251 编码的键盘映射。使用白俄罗斯文等文字的用户需要单独下载可工作的键盘映射。

如果需要,安装该软件包的文档:

mkdir -pv           /usr/share/doc/kbd-2.5.1
cp -R -v docs/doc/* /usr/share/doc/kbd-2.5.1

8.63.2 Kbd 的内容

安装的程序: chvt, deallocvt, dumpkeys, fgconsole, getkeycodes, kbdinfo, kbd_mode, kbdrate, loadkeys, loadunimap, mapscrn, openvt, psfaddtable (到 psfxtable 的链接), psfgettable (到 psfxtable 的链接), psfstriptable (到 psfxtable 的链接), psfxtable, setfont, setkeycodes, setleds, setmetamode, setvtrgb, showconsolefont, showkey, unicode_start, 以及 unicode_stop

安装的目录: /usr/share/consolefonts, /usr/share/consoletrans, /usr/share/keymaps, /usr/share/doc/kbd-2.5.1, 以及 /usr/share/unimaps

简要描述

chvt 修改当前虚拟终端

deallocvt 取消未使用的虚拟终端分配

dumpkeys 转储键盘转换表

fgconsole 打印活动虚拟终端的个数

getkeycodes 打印内核扫描码到键码的映射表

kbdinfo 获取终端状态信息

kbd_mode 报告或设置键盘模式

kbdrate 设置键盘重复和延迟率

loadkeys 加载键盘翻译表

loadunimap 加载内核 unicode 到字体的映射表

mapscrn 一个过时程序,曾用于将用户定义输出字符映射表加载到终端驱动程序;现在该任务由 setfont 完成

openvt 在新的虚拟终端 (VT) 启动程序

psfaddtable 向控制台字体增加 Unicode 字符表

psfgettable 提取控制台字体中嵌入的 Unicode 字符表

psfstriptable 删除控制台字体中嵌入的 Unicode 字符表

psfxtable 处理控制台字体的 Unicode 字符表

setfont 修改控制台上的增强图形适配器 (EGA) 和视频图像阵列 (VGA) 字体

setkeycodes 加载内核扫描码到键码的映射表项;在键盘上有特殊按键时很有用

setleds 设置键盘标志位和发光二极管 (LED)

setmetamode 定义键盘转换键 (meta-key) 处理

setvtrgb 设定所有虚拟终端的控制台颜色映射

showconsolefont 显示当前 EGA/VGA 控制台屏幕字体

showkey 报告键盘按键的扫描码、键码和 ASCII 编码

unicode_start 将键盘和控制台设定为 UNICODE 模式 [不要使用该程序,除非您的键盘映射文件是 ISO-8859-1 编码的。对于其他编码,该工具产生错误结果。]

unicode_stop 使键盘和控制台退出 UNICODE 模式

8.64 Libpipeline-1.5.7


Libpipeline 软件包包含用于灵活、方便地处理子进程流水线的库。

估计构建时间: 0.1 SBU

需要硬盘空间: 10 MB

8.64.1 安装 Libpipeline

准备编译 Libpipeline:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.64.2 Libpipeline 的内容

安装的库: libpipeline.so

简要描述

libpipeline 用于安全地在子进程之间构建流水线

8.65 Make-4.4


Make 软件包包含一个程序,用于控制从软件包源代码生成可执行文件和其他非源代码文件的过程。

估计构建时间: 0.5 SBU

需要硬盘空间: 13 MB

8.65.1 安装 Make

首先,修复上游发现的一些问题:

sed -e '/ifdef SIGPIPE/,+2 d' \
    -e '/undef  FATAL_SIG/i FATAL_SIG (SIGPIPE);' \
    -i src/main.c

准备编译 Make:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.65.2 Make 的内容

安装的程序: make

简要描述

make 自动确定软件包中需要 (重新) 构建的部分,并执行对应命令

8.66 Patch-2.7.6


Patch 软件包包含通过应用 “补丁” 文件,修改或创建文件的程序,补丁文件通常是 diff 程序创建的。

估计构建时间: 0.1 SBU

需要硬盘空间: 12 MB

8.66.1 安装 Patch

准备编译 Patch:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.66.2 Patch 的内容

安装的程序: patch

简要描述

patch 根据补丁文件修改文件 (补丁文件一般是使用 diff 程序创建的差异清单。通过将这些差异应用到原始文件,patch 即可创建应用补丁的文件版本。)

8.67 Tar-1.34


Tar 软件包提供创建 tar 归档文件,以及对归档文件进行其他操作的功能。Tar 可以对已经创建的归档文件进行提取文件,存储新文件,更新文件,或者列出文件等操作。

估计构建时间: 1.5 SBU

需要硬盘空间: 40 MB

8.67.1 安装 Tar

准备编译 Tar:

FORCE_UNSAFE_CONFIGURE=1  \
./configure --prefix=/usr

配置选项的含义:

FORCE_UNSAFE_CONFIGURE=1

该选项强制以 root 用户身份运行 mknod 测试。一般认为以 root 用户身份运行该测试是危险的,不过由于是在仅仅部分构建好的系统上运行测试,可以覆盖掉这个安全措施。

编译该软件包:

make

运行命令以测试编译结果:

make check

一项名为 capabilities: binary store/restore 的测试在运行时会失败,这是由于 LFS 没有 selinux 功能,但如果宿主系统的内核在构建 LFS 使用的文件系统上不支持扩展属性,该测试会被跳过。

安装该软件包:

make install
make -C doc install-html docdir=/usr/share/doc/tar-1.34

8.67.2 Tar 的内容

安装的程序: tar

安装的目录: /usr/share/doc/tar-1.34

简要描述

tar 创建称为 tarball 的档案文件,从档案文件中提取文件,或列出档案文件内容

8.68 Texinfo-7.0.2


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

估计构建时间: 0.3 SBU

需要硬盘空间: 128 MB

8.68.1 安装 Texinfo

准备编译 Texinfo:

./configure --prefix=/usr

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

可选地,安装属于 TeX 环境的组件:

make TEXMF=/usr/share/texmf install-tex

make 命令参数的含义:

TEXMF=/usr/share/texmf

TEXMF Makefile 变量包含之后可能安装的 TeX 软件包的 TeX 目录树根位置。

Info 文档系统使用一个纯文本文件保存目录项的列表。该文件位于 /usr/share/info/dir。不幸的是,由于一些软件包 Makefile 中偶然出现的问题,它有时会与系统实际安装的 info 页面不同步。如果需要重新创建 /usr/share/info/dir 文件,可以运行以下命令完成这一工作:

pushd /usr/share/info
  rm -v dir
  for f in *
    do install-info $f dir 2>/dev/null
  done
popd

8.68.2 Texinfo 的内容

安装的程序: info, install-info, makeinfo (到 texi2any 的链接), pdftexi2dvi, pod2texi, texi2any, texi2dvi, texi2pdf, 以及 texindex

安装的库: MiscXS.so, Parsetexi.so, 以及 XSParagraph.so (都在 /usr/lib/texinfo 中)

安装的目录: /usr/share/texinfo 和 /usr/lib/texinfo

简要描述

info 用于阅读和 man 页面类似的 info 页面,man 页面一般只解释可用的命令行选项,而 info 页面更为深入 [例如,可以对比 man bison 和 info bison。]

install-info 用于安装 info 页面;该命令更新 info 索引文件

makeinfo 将给定 Texinfo 源代码文档转换成 info 页面、纯文本或 HTML

pdftexi2dvi 将给定 Texinfo 文档格式化为可移植文档格式 (PDF) 文件

pod2texi 将 Pod 转换成 Texinfo 格式

texi2any 将 Texinfo 文档转换成其他几种格式

texi2dvi 将给定 Texinfo 文档格式化为可打印的设备无关文件

texi2pdf 将给定 Texinfo 文档格式化为可移植文档格式 (PDF) 文件

texindex 用于排序 Texinfo 索引文件

8.69 Vim-9.0.1273


Vim 软件包包含强大的文本编辑器。

估计构建时间: 2.4 SBU

需要硬盘空间: 235 MB

Vim 的替代品 如果您喜爱其他编辑器 —— 例如 Emacs、Joe、或者 Nano —— 参考 https://www.linuxfromscratch.org/blfs/view/11.3/postlfs/editors.html 中建议的安装说明。

8.69.1 安装 Vim

首先,修改 vimrc 配置文件的默认位置为 /etc:

echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h

准备编译 Vim:

./configure --prefix=/usr

编译该软件包:

make

为了准备运行测试套件,需要使得 tester 用户拥有写入源代码目录树的权限:

chown -Rv tester .

现在,以 tester 用户身份运行测试:

su tester -c "LANG=en_US.UTF-8 make -j1 test" &> vim-test.log

测试套件会将大量二进制数据输出到屏幕。这可能扰乱当前终端设置。为了避免这个问题,像上面的命令一样,将输出重定向到日志文件。测试成功完成后,日志文件末尾会包含 “ALL DONE”。

安装该软件包:

make install

许多用户条件反射地输入 vi,而不是 vim。为了在用户习惯性地输入 vi 时能够执行 vim,为二进制程序和各种语言的 man 页面创建符号链接:

ln -sv vim /usr/bin/vi
for L in  /usr/share/man/{,*/}man1/vim.1; do
    ln -sv vim.1 $(dirname $L)/vi.1
done

默认情况下,Vim 的文档安装在 /usr/share/vim 中。下面创建符号链接,使得可以通过 /usr/share/doc/vim-9.0.1273 访问文档,这个路径与其他软件包的文档位置格式一致:

ln -sv ../vim/vim90/doc /usr/share/doc/vim-9.0.1273

如果在安装 LFS 系统后安装了 X 窗口系统,可能需要在安装 X 后重新编译 Vim。Vim 提供的 GUI 版本编辑器需要 X 和一些额外的软件包才能安装。关于这一安装过程的更多信息,参考 Vim 文档和 BLFS 手册中位于 https://www.linuxfromscratch.org/blfs/view/11.3/postlfs/vim.html 的 Vim 安装页面。

8.69.2 配置 Vim

默认情况下,vim 在不兼容 vi 的模式下运行。这对于过去使用其他编辑器的用户来说可能显得陌生。以下配置包含的 “nocompatible” 设定是为了强调编辑器使用了新的行为这一事实。它也提醒那些想要使用 “compatible” 模式的用户,必须在配置文件的一开始改变模式。这是因为它会修改其他设置,对这些设置的覆盖必须在设定模式后进行。执行以下命令创建默认 vim 配置文件:

cat > /etc/vimrc << "EOF"
" Begin /etc/vimrc

" Ensure defaults are set before customizing settings, not after
source $VIMRUNTIME/defaults.vim
let skip_defaults_vim=1

set nocompatible
set backspace=2
set mouse=
syntax on
if (&term == "xterm") || (&term == "putty")
  set background=dark
endif

" End /etc/vimrc
EOF

set nocompatible 设定使得 vim 以一种更有用的方式 (也是默认方式) 行动,而不是兼容于 vi 的旧模式。删除其中的 “no” 可以保持旧的 vi 行为。set backspace=2 设定允许退格越过换行,自动缩进,以及插入模式的起始位置。参数 syntax on 启用 vim 符号高亮功能。参数 set mouse= 允许在 chroot 中或通过远程连接工作时使用鼠标正确地粘贴文本。最后,if 语句为 set background=dark 纠正 vim 对于某些终端模拟器背景色的猜测。这能够提供更适合这些程序黑色背景的配色方案。

关于其他可用选项的文档可以通过执行以下命令获得:

vim -c ':options'

注意

默认情况下 Vim 只安装英语拼写检查文件。如果希望安装您使用的语言的拼写检查文件,需要将适用于您的语言和字符编码的 .spl 文件和可选的 .sug 文件从 runtime/spell 复制到 /usr/share/vim/vim90/spell/

为了使用这些拼写检查文件,需要在 /etc/vimrc 中进行配置,例如:

set spelllang=en,ru
set spell

参阅 runtime/spell/README.txt 获得更多信息。

8.69.3 Vim 的内容

安装的程序: ex (到 vim 的链接), rview (到 vim 的链接), rvim (到 vim 的链接), vi (到 vim 的链接), view (到 vim 的链接), vim, vimdiff (到 vim 的链接), vimtutor, 以及 xxd

安装的目录: /usr/share/vim

简要描述

ex 以 ex 模式启动 vim

rview 是 view 的受限模式;不能启动 shell 命令,且不能挂起 view

rvim 是 vim 的受限模式;不能启动 shell 命令,且不能挂起 vim

vi 到 vim 的链接

view 以只读模式启动 vim

vim 文本编辑器

vimdiff 用 vim 编辑两个或三个文件版本,并显示差异

vimtutor 教会用户使用 vim 的基本快捷键和命令

xxd 创建文件的十六进制转储;也可以进行逆操作,因此可用于修补二进制文件

8.70 Eudev-3.2.11


Eudev 软件包包含动态创建设备节点的程序。

估计构建时间: 0.1 SBU

需要硬盘空间: 83 MB

8.70.1 安装 Eudev

首先,修复 .pc 文件记录的 udev 规则位置:

sed -i '/udevdir/a udev_dir=${udevdir}' src/udev/udev.pc.in

准备编译 Eudev:

./configure --prefix=/usr           \
            --bindir=/usr/sbin      \
            --sysconfdir=/etc       \
            --enable-manpages       \
            --disable-static

编译该软件包:

make

创建一些目录,它们目前被用于测试,但之后也会成为安装好的 eudev 的一部分。

mkdir -pv /usr/lib/udev/rules.d
mkdir -pv /etc/udev/rules.d

运行命令以测试编译结果:

make check

安装该软件包:

make install

安装一些在 LFS 环境中很有用的自定义规则和支持文件:

tar -xvf ../udev-lfs-20171102.tar.xz
make -f udev-lfs-20171102/Makefile.lfs install

8.70.2 配置 Eudev

硬件设备的相关信息被维护在 /etc/udev/hwdb.d/usr/lib/udev/hwdb.d 目录中。Eudev 需要将这些信息编译到二进制数据库 /etc/udev/hwdb.bin 中。初始化该数据库:

udevadm hwdb --update

每次硬件信息有更新时,都要运行该命令。

8.70.3 Eudev 的内容

安装的程序: udevadm 和 udevd

安装的库: libudev.so

安装的目录: /etc/udev, /usr/lib/udev, 以及 /usr/share/doc/udev-udev-lfs-20171102

简要描述

udevadm 通用 udev 管理工具:控制 udevd 守护进程,从 udev 数据库中提供信息,监视 uevent,等待 uevent 完成,测试 udev 配置,并为指定设备触发 uevent。

udevd 一个守护进程,它在 netlink 套接字上监听 uevent,并创建设备节点、运行配置好的外部程序,以响应这些 uevent。

libudev 一个提供 udev 设备信息接口的库

/etc/udev 包含 udev 配置文件、设备权限设置和设备命名规则

8.71 Man-DB-2.11.2


Man-DB 软件包包含查找和阅读 man 页面的程序。

估计构建时间: 0.2 SBU

需要硬盘空间: 40 MB

8.71.1 安装 Man-DB

准备编译 Man-DB:

./configure --prefix=/usr                         \
            --docdir=/usr/share/doc/man-db-2.11.2 \
            --sysconfdir=/etc                     \
            --disable-setuid                      \
            --enable-cache-owner=bin              \
            --with-browser=/usr/bin/lynx          \
            --with-vgrind=/usr/bin/vgrind         \
            --with-grap=/usr/bin/grap             \
            --with-systemdtmpfilesdir=            \
            --with-systemdsystemunitdir=

配置选项的含义:

–disable-setuid

该选项防止将 man 程序 setuid 到用户 man。

–enable-cache-owner=bin

该选项将系统范围的缓存文件所有者改为用户 bin。

–with-…

这三个选项设定一些默认程序。lynx 是基于文本的 web 浏览器 (安装过程可在 BLFS 中查阅),vgrind 将程序源代码转换成 Groff 输入,grap 用于在 Groff 文档中画图。vgrind 和 grap 在阅读 man 手册页面时一般用不到。它们不是 LFS 或 BLFS 的一部分,但如果需要的话,您应该可以在完成 LFS 的构建后自行安装它们。

–with-systemd…

该选项防止安装不必要的,为 systemd 提供的目录和文件。

编译该软件包:

make

运行命令以测试编译结果:

make check

安装该软件包:

make install

8.71.2 LFS 中的非英文 man 手册页面

下表展示了 Man-DB 假定的安装在 /usr/share/man/<ll> 中的 man 手册页面的编码字符集。另外,Man-DB 还能正确地判断出这些页面是否为 UTF-8 编码。

表 8.1. 传统 8 位 man 手册页面的预期字符编码

语言 (代码) 编码 语言 (代码) 编码
丹麦语 (da) ISO-8859-1 克罗地亚语 (hr) ISO-8859-2
德语 (de) ISO-8859-1 匈牙利语 (hu) ISO-8859-2
英语 (en) ISO-8859-1 日语 (ja) EUC-JP
西班牙语 (es) ISO-8859-1 朝鲜语 (ko) EUC-KR
爱沙尼亚语 (et) ISO-8859-1 立陶宛语 (lt) ISO-8859-13
芬兰语 (fi) ISO-8859-1 拉脱维亚语 (lv) ISO-8859-13
法语 (fr) ISO-8859-1 马其顿语 (mk) ISO-8859-5
爱尔兰语 (ga) ISO-8859-1 波兰语 (pl) ISO-8859-2
加利西亚语 (gl) ISO-8859-1 罗马尼亚语 (ro) ISO-8859-2
印度尼西亚语 (id) ISO-8859-1 希腊文 (el) ISO-8859-7
冰岛语 (is) ISO-8859-1 斯洛伐克语 (sk) ISO-8859-2
意大利语 (it) ISO-8859-1 斯洛文尼亚语 (sl) ISO-8859-2
挪威巴克摩语 (nb) ISO-8859-1 拉丁文书塞尔维亚语 ISO-8859-2
荷兰语 (nl) ISO-8859-1 塞尔维亚语 (sr) ISO-8859-5
挪威尼诺斯克语 (nn) ISO-8859-1 土耳其语 (tr) ISO-8859-9
挪威语 (no) ISO-8859-1 乌克兰语 (uk) KOI8-U
葡萄牙语 (pt) ISO-8859-1 越南语 (vi) TCVN5712-1
瑞典语 (sv) ISO-8859-1 简体中文 (zh_CN) GBK
白俄罗斯语 (be) CP1251 简体中文,新加坡 (zh_SG) GBK
保加利亚语 (bg) CP1251 繁体中文,香港特别行政区 (zh_HK) BIG5HKSCS
捷克语 (cs) ISO-8859-2 繁体中文 (zh_TW) BIG5

注意

用该表之外的语言编写的 man 手册页面不被支持。

8.71.3 Man-DB 的内容

安装的程序: accessdb, apropos (到 whatis 的链接), catman, lexgrog, man, man-recode, mandb, manpath, 以及 whatis

安装的库: libman.so 和 libmandb.so (都在 /usr/lib/man-db 中)

安装的目录: /usr/lib/man-db, /usr/libexec/man-db, and /usr/share/doc/man-db-2.11.2

简要描述

accessdb 将 whatis 数据库内容转储为人类可读格式

apropos 搜索 whatis 数据库,显示包含给定字符串的系统命令的简要描述

catman 创建或更新预先格式化的 man 手册页面

lexgrog 显示给定 man 手册页面的单行摘要信息

man 格式化并显示请求的 man 手册页面

man-recode 转换 man 页面的编码

mandb 创建或更新 whatis 数据库

manpath 显示 $MANPATH 的内容,或者 (如果 $MANPATH 未设定) 根据 man.conf 和用户环境确定的合适搜索路径

whatis 搜索 whatis 数据库,显示包含给定关键词的系统命令的简要描述

libman 包含 man 运行时支持

libmandb 包含 man 运行时支持

8.72 Procps-ng-4.0.2


Procps-ng 软件包包含监视进程的程序。

估计构建时间: 0.1 SBU

需要硬盘空间: 26 MB

8.72.1 安装 Procps-ng

准备编译 Procps-ng:

./configure --prefix=/usr                           \
            --docdir=/usr/share/doc/procps-ng-4.0.2 \
            --disable-static                        \
            --disable-kill

配置选项的含义:

–disable-kill

该选项使得 kill 命令不被构建;它将由 Util-linux 软件包提供。

编译该软件包:

make

如果要运行测试套件,执行命令:

make check

已知一项名为 free with commit 的测试在宿主系统中有使用自定义内存分配器的程序 (如 JVM 和网页浏览器) 运行时可能失败。

安装该软件包:

make install

8.72.2 Procps-ng 的内容

安装的程序: free, pgrep, pidof, pkill, pmap, ps, pwdx, slabtop, sysctl, tload, top, uptime, vmstat, w, 以及 watch

安装的库: libproc-2.so

安装的目录: /usr/include/procps 和 /usr/share/doc/procps-ng-4.0.2

简要描述

free 报告系统中可用和已用内存 (包括物理内存和交换空间) 的容量

pgrep 根据名称和其他属性查找进程

pidof 报告给定程序的 PID

pkill 根据名称和其他属性向进程发送信号

pmap 报告给定进程的内存映射

ps 列出正在运行的进程

pwdx 报告一个进程的当前工作目录

slabtop 实时显示内核 slab 缓存详细信息

sysctl 在运行时修改内核参数

tload 打印当前系统平均负载示意图

top 列出 CPU 占用最大的进程列表;它实时地提供处理器活动的连续概况

uptime 报告系统运行时间、登录用户数目和系统平均负载

vmstat 报告虚拟内存统计,给出进程、内存、分页、块输入输出 (IO)、陷阱和 CPU 活动信息

w 显示当前登录用户和它们的登录地点、时间

watch 重复执行给定命令,显示其输出的第一页;这使得用户可以观察输出随时间的变化

libproc-2 包含该软件包大多数程序使用的函数

8.73 Util-linux-2.38.1


Util-linux 软件包包含若干工具程序。这些程序中有处理文件系统、终端、分区和消息的工具。

估计构建时间: 0.5 SBU

需要硬盘空间: 283 MB

8.73.1 安装 Util-linux

准备编译 Util-linux:

./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
            --bindir=/usr/bin    \
            --libdir=/usr/lib    \
            --sbindir=/usr/sbin  \
            --disable-chfn-chsh  \
            --disable-login      \
            --disable-nologin    \
            --disable-su         \
            --disable-setpriv    \
            --disable-runuser    \
            --disable-pylibmount \
            --disable-static     \
            --without-python     \
            --without-systemd    \
            --without-systemdsystemunitdir \
            --docdir=/usr/share/doc/util-linux-2.38.1

–disable 和 –without 选项防止一些警告,它们与那些需要 LFS 中不存在的依赖项,或者和其他软件包安装的程序不兼容的组件的构建过程相关。

编译该软件包:

make

如果希望的话,以非 root 用户身份运行测试套件:

警告

以 root 用户身份运行测试套件可能对系统造成损害。为了运行它,内核配置选项 CONFIG_SCSI_DEBUG 必须在当前运行的系统中可用,且必须被构建为内核模块。直接将其构建为内核的一部分会导致系统无法引导。为了测试的完整覆盖,必须安装其他 BLFS 软件包。如果希望的话,可以在引导构建完成的 LFS 系统后,执行以下命令运行测试:

bash tests/run.sh --srcdir=$PWD --builddir=$PWD
chown -Rv tester .
su tester -c "make -k check"

如果宿主系统内核没有启用配置选项 CONFIG_CRYPTO_USER_API_HASH,则 hardlink 测试会失败。另外,已知 misc: mbsencode 测试和 script: replay 测试中各有一项子测试可能失败。

安装该软件包:

make install

8.73.2 Util-linux 的内容

安装的程序: addpart, agetty, blkdiscard, blkid, blkzone, blockdev, cal, cfdisk, chcpu, chmem, choom, chrt, col, colcrt, colrm, column, ctrlaltdel, delpart, dmesg, eject, fallocate, fdisk, fincore, findfs, findmnt, flock, fsck, fsck.cramfs, fsck.minix, fsfreeze, fstrim, getopt, hexdump, hwclock, i386 (到 setarch 的链接), ionice, ipcmk, ipcrm, ipcs, irqtop, isosize, kill, last, lastb (到 last 的链接), ldattach, linux32 (到 setarch 的链接), linux64 (到 setarch 的链接), logger, look, losetup, lsblk, lscpu, lsipc, lsirq, lslocks, lslogins, lsmem, lsns, mcookie, mesg, mkfs, mkfs.bfs, mkfs.cramfs, mkfs.minix, mkswap, more, mount, mountpoint, namei, nsenter, partx, pivot_root, prlimit, readprofile, rename, renice, resizepart, rev, rfkill, rtcwake, script, scriptlive, scriptreplay, setarch, setsid, setterm, sfdisk, sulogin, swaplabel, swapoff, swapon, switch_root, taskset, uclampset, ul, umount, uname26 (到 setarch 的链接), unshare, utmpdump, uuidd, uuidgen, uuidparse, wall, wdctl, whereis, wipefs, x86_64 (到 setarch 的链接), 以及 zramctl

安装的库: libblkid.so, libfdisk.so, libmount.so, libsmartcols.so, 以及 libuuid.so

安装的目录: /usr/include/blkid, /usr/include/libfdisk, /usr/include/libmount, /usr/include/libsmartcols, /usr/include/uuid, /usr/share/doc/util-linux-2.38.1, 以及 /var/lib/hwclock

简要描述

addpart 告知 Linux 内核有新的分区

agetty 打开 tty 端口,提示输入登录名,再启动 login 程序

blkdiscard 丢弃设备上的扇区

blkid 一个命令行工具,用于定位和打印块设备属性

blkzone 用于管理分区存储的块存储设备

blockdev 允许用户从命令行调用块设备 ioctl

cal 显示简单的日历

cfdisk 操作给定设备的分区表

chcpu 修改 CPU 状态

chmem 配置内存

choom 显示或调整 OOM-killer 分数,这一数值用于确定 Linux 在内存不足时首先杀死哪个进程

chrt 操纵进程实时属性

col 过滤掉反向换行符

colcrt 为缺失加粗、半行等功能的终端过滤 nroff 输出

colrm 过滤掉给定列

column 将给定文件格式化为多栏

ctrlaltdel 将 Ctrl+Alt+Del 键组合的功能设定为硬复位或软复位

delpart 要求 Linux 内核删除分区

dmesg 转储内核引导消息

eject 弹出可移动媒体

fallocate 为文件预先分配空间

fdisk 操作给定设备的分区表

fincore 统计给定文件在内存中占用的页面数

findfs 根据标签或统一标识符 (UUID) 查找文件系统

findmnt 是 libmount 库的命令行接口,可以处理 mountinfo、fstab 和 mtab 文件

flock 获取文件锁,并在持有锁的情况下运行命令

fsck 用于检查或修复文件系统

fsck.cramfs 用于对给定设备上的 Cramfs 文件系统进行一致性检查

fsck.minix 用于对给定设备上的 Minix 文件系统进行一致性检查

fsfreeze 是内核驱动 ioctl 操作 FIFREEZE/FITHAW 的简单包装

fstrim 丢弃已挂载文件系统上未使用的块

getopt 解析给定命令行的选项

hardlink 通过创建硬链接,归并重复的文件

hexdump 以十六进制、十进制、八进制或 ascii 格式转储文件

hwclock 读取或设置系统硬件时钟,它又被称为实时时钟 (RTC) 或基本输入输出系统 (BIOS) 时钟

i386 到 setarch 的符号链接

ionice 设定程序的 IO 调度类和优先级

ipcmk 创建多种 IPC 资源

ipcrm 删除给定的进程间通信 (IPC) 资源

ipcs 提供 IPC 状态信息

irqtop 以 top(1) 风格显示内核中断计数信息

isosize 报告 ISO 9660 文件系统的大小

kill 向进程发送信号

last 显示哪些用户最后登录 (或登出),在 /var/log/wtmp 文件中反向搜索;它也会显示系统引导、关闭和运行级别变化记录

lastb 显示 /var/log/btmp 记录的失败登录企图

ldattach 为串口线附加行规则

linux32 到 setarch 的符号链接

linux64 到 setarch 的符号链接

logger 将给定消息记入系统日志

look 显示以给定字符串开始的行

losetup 设定和控制回环设备

lsblk 以树状格式列出所有或给定块设备的信息

lscpu 打印 CPU 体系结构信息

lsfd 显示当前已打开的文件信息;可以代替 lsof 命令

lsipc 打印系统当前部署的 IPC 设施的信息

lsirq 显示内核中断计数信息

lslocks 列出本地系统锁

lslogins 列出用户、组和系统账户的信息

lsmem 列出可用内存的范围和它们的在线状态

lsns 列出命名空间

mcookie 为 xauth 创建魔术 cookie (128位随机十六进制数)

mesg 控制其他用户能否向当前用户终端发送消息

mkfs 在设备 (一般是硬盘分区) 上创建文件系统

mkfs.bfs 创建 Santa Cruz Operations (SCO) bfs 文件系统

mkfs.cramfs 创建 cramfs 文件系统

mkfs.minix 创建 Minix 文件系统

mkswap 将给定文件或设备初始化为交换空间

more 在屏幕上分页文本的过滤器

mount 将给定设备上的文件系统挂载到文件系统树结构中的给定目录

mountpoint 检查目录是否为挂载点

namei 显示给定路径中的符号链接

nsenter 在其他程序的命名空间中运行程序

partx 告知内核磁盘分区的存在性和编号

pivot_root 将当前进程的根文件系统设为给定文件系统

prlimit 获取和设定进程资源限制

readprofile 读取内核性能分析信息

rename 重命名给定文件,将给定字符串替换为另一个字符串

renice 修改正在运行的进程的优先级

resizepart 要求 Linux 内核改变分区大小

rev 反转给定文件的每一行

rkfill 用于启用或禁用无线设备的工具

rtcwake 进入睡眠状态,直到给定的唤醒时间

script 记录终端会话打字机文档

scriptlive 根据计时信息重新运行会话打字机文档

scriptreplay 根据计时信息重放终端会话打字机文档

setarch 在新程序环境中修改系统报告的体系结构,并设置进程执行域信息

setsid 在新会话中运行给定程序

setterm 设定终端属性

sfdisk 一个分区表修改器

sulogin 允许 root 登录;一般在系统进入单用户模式时由 init 执行

swaplabel 允许修改交换空间 UUID 和标签

swapoff 禁止在文件或设备上进行分页交换

swapon 启用文件或设备上的分页交换,或列出当前用于交换的设备和文件

switch_root 将另一个文件系统切换为挂载树的根

taskset 获取或设置进程 CPU 亲和性

uclampset 调节进程资源占用限位属性

ul 将下划线转换为在当前终端中表示下划线的 escape 序列的过滤器

umount 断开文件系统与系统文件目录树的连接

uname26 到 setarch 的符号链接

unshare 在某些命名空间与父进程脱离的情况下运行程序

utmpdump 以用户友好的格式显示给定登录文件内容

uuidd UUID 库使用的守护进程,用于安全、确保唯一性地生成 UUID

uuidgen 创建新的 UUID。每个新创建的 UUID 都是一个随机数,它大概率和其他 UUID —— 包括在本地系统或其他系统,在过去或未来创建的 UUID —— 都不同(可能存在约 340 万亿亿亿亿个不同的 UUID)

uuidparse 用于解析统一标识符的工具

wall 显示文件或标准输入 (默认值) 的内容到所有登录用户的终端

wdctl 显示硬件看门狗电路状态

whereis 报告给定命令二进制,源代码,以及 man 页面文件的位置

wipefs 从设备上擦除文件系统签名

x86_64 到 setarch 的符号链接

zramctl 设定和控制 zram (压缩内存盘) 设备的程序

libblkid 包含设备识别和标识提取子程序

libfdisk 包含操作分区表的子程序

libmount 包含挂载和解挂块设备的子程序

libsmartcols 包含以表格形式在屏幕上输出的辅助子程序

libuuid 包含为对象生成唯一标识符,使它在本地系统以外也可以访问的子程序

8.74 E2fsprogs-1.47.0


E2fsprogs 软件包包含处理 ext2 文件系统的工具。此外它也支持 ext3 和 ext4 日志文件系统。

估计构建时间: 机械硬盘上 2.4 SBU,固态硬盘上 0.4 SBU

需要硬盘空间: 95 MB

8.74.1 安装 E2fsprogs

E2fsprogs 文档推荐在源代码目录树中的一个子目录内构建该软件包:

mkdir -v build
cd       build

准备编译 E2fsprogs:

../configure --prefix=/usr           \
             --sysconfdir=/etc       \
             --enable-elf-shlibs     \
             --disable-libblkid      \
             --disable-libuuid       \
             --disable-uuidd         \
             --disable-fsck

配置选项的含义:

–enable-elf-shlibs

该选项表示创建该软件包中一些程序使用的共享库。

–disable-* 这些选项防止构建和安装 libuuid 和 libblkid 库,uuidd 守护程序,以及 fsck 包装器;因为 Util-linux 会安装更新的版本。

编译该软件包:

make

执行以下命令,以运行测试:

make check

已知一项名为 u_direct_io 的测试可能在一些系统上失败。

安装该软件包:

make install

删除无用的静态库:

rm -fv /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a

该软件包安装了一个 gzip 压缩的 .info 文件,却没有更新系统的 dir 文件。执行以下命令解压该文件,并更新系统 dir 文件:

gunzip -v /usr/share/info/libext2fs.info.gz
install-info --dir-file=/usr/share/info/dir /usr/share/info/libext2fs.info

如果需要,执行以下命令创建并安装一些额外的文档:

makeinfo -o      doc/com_err.info ../lib/et/com_err.texinfo
install -v -m644 doc/com_err.info /usr/share/info
install-info --dir-file=/usr/share/info/dir /usr/share/info/com_err.info

8.74.2 配置 E2fsprogs

/etc/mke2fs.conf 包含 mke2fs 一些命令行选项的默认值。您可以修改这些默认值,使之符合您的需求。例如,一些工具 (未被 LFS 或 BLFS 包含) 无法识别启用了 metadata_csum_seed 特性的 ext4 文件系统。如果需要使用这样的工具,可以执行命令,从默认的 ext4 特性列表中移除该特性:

sed 's/metadata_csum_seed,//' -i /etc/mke2fs.conf

更多信息详见 man 页面 mke2fs.conf(5)

8.74.3 E2fsprogs 的内容

安装的程序: badblocks, chattr, compile_et, debugfs, dumpe2fs,e2freefrag, e2fsck, e2image, e2label, e2mmpstatus, e2scrub, e2scrub_all, e2undo, e4crypt, e4defrag, filefrag, fsck.ext2, fsck.ext3, fsck.ext4, logsave, lsattr, mk_cmds, mke2fs, mkfs.ext2, mkfs.ext3, mkfs.ext4, mklost+found, resize2fs, 以及 tune2fs

安装的库: libcom_err.so, libe2p.so, libext2fs.so, 以及 libss.so

安装的目录: /usr/include/e2p, /usr/include/et, /usr/include/ext2fs, /usr/include/ss, /usr/lib/e2fsprogs, /usr/share/et, 以及 /usr/share/ss

简要描述

badblocks 在一个设备 (一般是磁盘分区) 上搜索坏块

chattr 改变 ext{234} 文件系统上文件的标志属性

compile_et 一个错误表编译器;它将包含错误编号名称和消息的表转化成 C 源代码,以和 com_err 库一起使用

debugfs 一个文件系统调试器;可以检验并修改 ext{234} 文件系统的状态

dumpe2fs 打印给定设备上文件系统的超级块和块组信息

e2freefrag 报告可用空间碎片信息

e2fsck 用于检查或修复 ext{234} 文件系统

e2image 用于将 ext{234} 文件系统关键数据保存到文件

e2label 显示或修改给定设备上的 ext{234} 文件系统标签

e2mmpstatus 检查 ext4 文件系统的MMP (多重挂载保护) 状态

e2scrub 检查已经挂载的 ext{234} 文件系统的内容

e2scrub_all 检查所有已挂载的 ext{234} 文件系统是否存在错误

e2undo 重放设备上找到的 ext{234} 文件系统撤销日志 [可以用于撤销 E2fsprogs 程序的失败操作。]

e4crypt Ext4 文件系统加密工具

e4defrag 用于 ext4 文件系统的在线碎片整理工具

filefrag 报告特定文件碎片化程度

fsck.ext2 默认情况下检查 ext2 文件系统,是 e2fsck 的硬链接

fsck.ext3 默认情况下检查 ext3 文件系统,是 e2fsck 的硬链接

fsck.ext4 默认情况下检查 ext4 文件系统,是 e2fsck 的硬链接

logsave 将命令输出保存到日志文件

lsattr 列出 ext2 文件系统上的文件属性

mk_cmds 将包含命令名称和帮助信息的表格转换成 C 源代码文件,以便和 libss 子系统库一起使用

mke2fs 在给定设备上创建 ext{234} 文件系统

mkfs.ext2 默认情况下创建 ext2 文件系统,是 mke2fs 的硬链接

mkfs.ext3 默认情况下创建 ext3 文件系统,是 mke2fs 的硬链接

mkfs.ext4 默认情况下创建 ext4 文件系统,是 mke2fs 的硬链接

mklost+found 创建 lost+found 目录;它在 ext{234} 文件系统上为该目录预先分配磁盘块,以减轻 e2fsck 的负担

resize2fs 可以用于扩大或压缩 ext{234} 文件系统

tune2fs 调整 ext{234} 文件系统的可调参数

libcom_err 公用错误显示子程序

libe2p 被 dumpe2fs、chattr, 和 lsattr 使用

libext2fs 包含允许用户级程序操纵 ext{234} 文件系统的子程序

libss 被 debugfs 使用

8.75 Sysklogd-1.5.1


Sysklogd 软件包包含记录系统消息 (例如在意外情况发生时内核输出的消息) 的程序。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 0.7 MB

8.75.1 安装 Sysklogd

首先,修复 klogd 中在特定情况下会发生段错误的问题,并改正一个过时的程序结构:

sed -i '/Error loading kernel symbols/{n;n;d}' ksym_mod.c
sed -i 's/union wait/int/' syslogd.c

编译该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make BINDIR=/sbin install

8.75.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 *

# End /etc/syslog.conf
EOF

8.75.3 Sysklogd 的内容

安装的程序: klogd 和 syslogd

简要描述

klogd 一个截获并记录内核消息的系统守护程序

syslogd 记录系统程序提供给日志系统的消息 [每条消息至少包含时间戳和主机名,通常还包含程序的名字,但这依赖于日志守护进程的信任度设置。]

8.76 Sysvinit-3.06


Sysvinit 软件包包含控制系统启动、运行和关闭的程序。

估计构建时间: 不到 0.1 SBU

需要硬盘空间: 4.4 MB

8.76.1 安装 Sysvinit

首先,应用一个补丁,它会删除 sysvinit 中其他软件包已经安装的程序,使一条消息更加清晰,并修复一个引发编译器警告的问题:

patch -Np1 -i ../sysvinit-3.06-consolidated-1.patch

编译该软件包:

make

该软件包不包含测试套件。

安装该软件包:

make install

8.76.2 Sysvinit 的内容

安装的程序: bootlogd, fstab-decode, halt, init, killall5, poweroff (到 halt 的链接), reboot (到 halt 的链接), runlevel, shutdown, 以及 telinit (到 init 的链接)

简要描述

bootlogd 将引导消息写入日志文件

fstab-decode 以 fstab 编码的参数运行命令

halt 通常调用 shutdown 并传递 -h 参数,但是如果已经处于运行级别 0,则它会通知内核停止系统运行;在系统被关闭时,它在 /var/log/wtmp 文件中进行记录

init 内核初始化硬件后启动的第一个进程;它接管引导过程,启动其配置文件中指定的所有进程

killall5 向除了自身会话中以外的所有进程发送信号;它不会杀死作为它本身父进程的 shell

poweroff 告诉内核停止系统运行并关闭电源 (参阅 halt)

reboot 告诉内核重启系统 (参阅 halt)

runlevel 报告上一次的和当前的系统运行级别,上一次系统运行级别记录在 /run/utmp 中

shutdown 安全地将系统下线,向所有进程发送信号,并通知所有登录用户

telinit 告诉 init 切换到某个运行级别

8.77 About Debugging Symbols


许多程序和库在默认情况下被编译为带有调试符号的二进制文件 (通过使用 gcc 的 -g 选项)。这意味着在调试这些带有调试信息的程序和库时,调试器不仅能给出内存地址,还能给出子程序和变量的名称。

然而,包含这些调试符号会显著增大程序或库的体积。下面是两个表现调试符号占用空间的例子:

具体的文件大小与使用的编译器和 C 库相关,但是移除调试符号的程序通常比移除调试符号前小 50% 到 80%。由于大多数用户永远不会用调试器调试系统软件,可以通过移除它们的调试符号,回收大量磁盘空间。下一节展示如何从系统程序和库中移除所有调试符号。

8.78 Stripping


本节是可选的。如果系统不是为程序员设计的,也没有调试系统软件的计划,可以通过从二进制程序和库移除调试符号和不必要的符号表项,将系统的体积减小约 2 GB。对于一般的 Linux 用户,这不会造成任何不便。

大多数使用以下命令的用户不会遇到什么困难。但是,如果打错了命令,很容易导致新系统无法使用。因此,在运行 strip 命令前,最好备份 LFS 系统的当前状态。

strip 命令的 –strip-unneeded选项从程序或库中移除所有调试符号。它也会移除所有链接器 (对于静态库) 或动态链接器 (对于动态链接的程序和共享库) 不需要的符号表项。

一些库的调试符号需要保存在单独的文件中。之后在 BLFS 中,如果使用 valgrindgdb 运行退化测试,则需要这些调试信息的存在。

需要注意的是,strip 命令会覆盖它正在处理的二进制程序或库文件。这可能导致正在使用该文件中代码或数据的进程崩溃。如果运行 strip 的进程受到影响,则可能导致正在被处理的程序或库完全损坏;这可能导致系统完全不可用。为了避免这种情况,将一些库和程序复制到 /tmp 中,在那里移除调试符号,再使用 install 命令重新安装它们。(第 8.2.1 节 “升级问题” 中的相关条目介绍了使用 install 命令的原因。)

注意

ELF 加载器的文件名在 64 位系统是 ld-linux-x86-64.so.2,在 32 位系统是 ld-linux.so.2。下面的命令会为当前架构选择正确的文件名,并排除以 “g” 结尾的文件。

重要

在构建过程中,如果任何一个软件包的版本和本书指定的版本不同 (无论是依照安全公告的要求还是为了满足个人需求),则可能需要更新 save_usrlib 或者 online_usrlib 中的库文件名。否则可能导致系统完全无法使用。

save_usrlib="$(cd /usr/lib; ls ld-linux*[^g])
             libc.so.6
             libthread_db.so.1
             libquadmath.so.0.0.0
             libstdc++.so.6.0.30
             libitm.so.1.0.0
             libatomic.so.1.2.0"

cd /usr/lib

for LIB in $save_usrlib; do
    objcopy --only-keep-debug $LIB $LIB.dbg
    cp $LIB /tmp/$LIB
    strip --strip-unneeded /tmp/$LIB
    objcopy --add-gnu-debuglink=$LIB.dbg /tmp/$LIB
    install -vm755 /tmp/$LIB /usr/lib
    rm /tmp/$LIB
done

online_usrbin="bash find strip"
online_usrlib="libbfd-2.40.so
               libsframe.so.0.0.0
               libhistory.so.8.2
               libncursesw.so.6.4
               libm.so.6
               libreadline.so.8.2
               libz.so.1.2.13
               $(cd /usr/lib; find libnss*.so* -type f)"

for BIN in $online_usrbin; do
    cp /usr/bin/$BIN /tmp/$BIN
    strip --strip-unneeded /tmp/$BIN
    install -vm755 /tmp/$BIN /usr/bin
    rm /tmp/$BIN
done

for LIB in $online_usrlib; do
    cp /usr/lib/$LIB /tmp/$LIB
    strip --strip-unneeded /tmp/$LIB
    install -vm755 /tmp/$LIB /usr/lib
    rm /tmp/$LIB
done

for i in $(find /usr/lib -type f -name \*.so* ! -name \*dbg) \
         $(find /usr/lib -type f -name \*.a)                 \
         $(find /usr/{bin,sbin,libexec} -type f); do
    case "$online_usrbin $online_usrlib $save_usrlib" in
        *$(basename $i)* )
            ;;
        * ) strip --strip-unneeded $i
            ;;
    esac
done

unset BIN LIB save_usrlib online_usrbin online_usrlib

这里会产生关于很多文件的错误信息,因为无法识别这些文件的格式。这些警告可以安全地忽略。它们表明那些文件是脚本文件,而不是二进制文件。

8.79 Cleaning Up


最后,清理在执行测试的过程中遗留的一些文件:

rm -rf /tmp/*

在 /usr/lib 和 /usr/libexec 目录中还有一些扩展名为 .la 的文件。它们是 “libtool 档案” 文件。正如我们已经讨论过的,它们在现代 Linux 系统中仅用于 libltdl。LFS 中没有库被设计为通过 libltdl 加载,而且已知一些 .la 文件能导致 BLFS 软件包构建失败。现在删除这些文件:

find /usr/lib /usr/libexec -name \*.la -delete

如果希望了解更多关于 libtool 档案文件的信息,参阅 BLFS 章节 “About Libtool Archive (.la) files”

第 6 章第 7 章中构建的编译器仍然有一部分安装在系统上,它现在已经没有存在的意义了。执行命令删除它:

find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf

最后,移除上一章开始时创建的临时 ‘tester’ 用户账户。

userdel -r tester