构造基于x86_64的LFS(3)
继续构造LFS,从安装基本系统软件开始
安装基本系统软件
因为上次备份系统离开了chroot环境,所有现在要重新进入,先挂载虚拟内核文件系统,再进入chroot
值得注意的是,这次也不需要设定环境变量$LFS
1 | mount -v --bind /dev $LFS/dev |
这里将不涉及任何软件包管理,而是直接进入到软件包的安装
Man-pages
Man-pages 软件包包含 2,400 多个手册页。
解压Man-pages
1 | cd /sources/ |
移除描述密码散列函数的两个手册页。Libxcrypt 会提供这些手册页的更好版本。
1 | rm -v man3/crypt* |
安装Man-pages
1 | make prefix=/usr install |
Iana-Etc
Iana-Etc 软件包包含网络服务和协议的数据。
解压Iana-Etc
1 | cd /sources/ |
只需把文件复制到正确位置就行
1 | cp services protocols /etc |
Glibc
进入Glibc,先打一个补丁
一些 Glibc 程序使用与 FHS 不兼容的 /var/db 目录存放它们的运行时数据。应用一个补丁,使得这些程序在 FHS 兼容的位置存放运行时数据
1 | patch -Np1 -i ../glibc-2.40-fhs-1.patch |
删除之前的build目录并新建一个
1 | rm -rf build/ |
确保将 ldconfig 和 sln 工具安装到 /usr/sbin 目录中
1 | echo "rootsbindir=/usr/sbin" > configparms |
准备编译Gblic
1 | ../configure --prefix=/usr \ |
编译Glibc
1 | make |
编译完成后进行测试,在这之前需要先跳过一些测试
1 | sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile |
测试通过后安装软件包
1 | make install |
改正 ldd 脚本中硬编码的可执行文件加载器路径
1 | sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/ldd |
安装locale,这里就直接安装所有的了。
1 | make localedata/install-locales |
由于 Glibc 的默认值在网络环境下不能很好地工作,需要创建配置文件 /etc/nsswitch.conf
1 | cat > /etc/nsswitch.conf << "EOF" |
安装并设置时区数据
1 | cat > temp.sh << "EOF" |
确定本地时区
1 | tzselect |
然后根据时区创建/etc/localtime,根据上面脚本的运行结果自行决定是否替换Asia/Shanghai字段
1 | ln -sfv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime |
现在配置动态加载器,创建一个新的/etc/ld.so.conf
1 | cat > /etc/ld.so.conf << "EOF" |
Zlib
解压Zlib
1 | cd /sources/ |
准备编译Zlib
1 | ./configure --prefix=/usr |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
删除无用的静态库
1 | rm -fv /usr/lib/libz.a |
Bzip2
解压Bzip2
1 | cd /sources/ |
打补丁
1 | patch -Np1 -i ../bzip2-1.0.8-install_docs-1.patch |
以下命令保证安装的符号链接是相对的
1 | sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile |
确保手册页被安装到正确位置
1 | sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile |
准备编译Bzip2
1 | make -f Makefile-libbz2_so |
开始编译并测试软件包
1 | make |
安装软件包
1 | make PREFIX=/usr install |
安装共享库
1 | cp -av libbz2.so.* /usr/lib |
安装链接到共享库的 bzip2 二进制程序到 /bin 目录,并将两个和 bzip2 完全相同的文件替换成符号链接
1 | cat > temp.sh << "EOF" |
删除无用的静态库
1 | rm -fv /usr/lib/libbz2.a |
Xz
之前已经解压过了,直接进入Xz目录
1 | cd /sources/xz-5.6.2 |
准备编译Xz
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Lz4
解压Lz4
1 | cd /sources/ |
开始编译,然后测试编译结果,最后安装软件包
1 | make BUILD_STATIC=no PREFIX=/usr |
Zstd
解压Zstd
1 | cd /sources/ |
开始编译,然后测试编译结果,最后安装软件包
1 | make prefix=/usr |
删除静态库
1 | rm -v /usr/lib/libzstd.a |
File
进入File目录
1 | cd /sources/File-5.45/ |
准备编译File
1 | ./configure --prefix=/usr |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Readline
解压Readline
1 | cd /sources/ |
重新安装 Readline 会导致旧版本的库被重命名为 <库名称>.old。这一般不是问题,但某些情况下会触发 ldconfig 的一个链接 bug。运行下面的两条 sed 命令防止这种情况:
1 | sed -i '/MV.*old/d' Makefile.in |
下面防止在共享库中硬编码库文件搜索路径 (rpath)。该软件包在安装到标准位置时并不需要 rpath,而且 rpath 在一些情况下会产生我们不希望的副作用,甚至导致安全问题
1 | sed -i 's/-Wl,-rpath,[^ ]*//' support/shobj-conf |
准备编译Readline
1 | ./configure --prefix=/usr \ |
开始编译,完成后安装软件包
1 | make SHLIB_LIBS="-lncursesw" |
安装软件包的文档
1 | install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-8.2.13 |
M4
进入M4目录
1 | cd /sources/m4-1.4.19 |
准备编译M4
1 | ./configure --prefix=/usr |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Bc
解压Bc
1 | cd /sources/ |
准备编译Bc
1 | CC=gcc ./configure --prefix=/usr -G -O3 -r |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Flex
解压Flex
1 | cd /sources/ |
准备编译Flex
1 | ./configure --prefix=/usr \ |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
创建软连接
1 | ln -sv flex /usr/bin/lex |
Tcl
解压Tcl
1 | cd /source/ |
准备编译Tcl
1 | SRCDIR=$(pwd) |
开始编译
1 | make |
测试编译结果,然后安装软件包
1 | make test |
将安装好的库加上写入权限,以便将来移除调试符号
1 | chmod -v u+w /usr/lib/libtcl8.6.so |
安装 Tcl 的头文件。下一个软件包 Expect 需要它们才能构建
1 | make install-private-headers |
创建一个必要的符号链接
1 | ln -sfv tclsh8.6 /usr/bin/tclsh |
重命名一个与 Perl 手册页文件名冲突的手册页
1 | mv /usr/share/man/man3/{Thread,Tcl_Thread}.3 |
安装文档
1 | cd .. |
Expect
解压Expect
1 | cd /sources/ |
Expect 需要伪终端 (PTY) 才能正常工作。进行简单测试以验证 PTY 是否在 chroot 环境中正常工作,若输出ok则继续,否则仔细阅读处理方法8.17.1. 安装 Expect
1 | python3 -c 'from pty import spawn; spawn(["echo", "ok"])' |
打patch
1 | patch -Np1 -i ../expect-5.45.4-gcc14-1.patch |
准备编译Expect
1 | ./configure --prefix=/usr \ |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
DejaGNU
解压DejaGNU
1 | cd /sources/ |
单独创建一个目录用于构建
1 | mkdir -v build |
准备编译DejaGNU
1 | ../configure --prefix=/usr |
测试编译结果
1 | make check |
安装软件包
1 | make install |
Pkgconf
解压Pkgconf
1 | cd /sources/ |
准备编译Pkgconf
1 | ./configure --prefix=/usr \ |
开始编译,完成后安装软件包
1 | make && make install |
为了维持与原始的 Pkg-config 软件包的兼容性,创建两个符号链接
1 | ln -sv pkgconf /usr/bin/pkg-config |
Binutils
重新创建单独用于构建的目录
1 | cd /sources/ |
准备编译Binutils
1 | ../configure --prefix=/usr \ |
开始编译
1 | make tooldir=/usr |
测试编译结果
1 | make -k check |
Gold 测试套件中,有十二项测试在构建 GCC 时启用 –enable-default-pie 和 –enable-default-ssp 的情况下会失败。请仔细核对失败的测试数量
安装软件包
1 | make tooldir=/usr install |
删除无用的静态库
1 | rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,gprofng,opcodes,sframe}.a |
GMP
解压GMP
1 | cd /sources/ |
准备编译GMP
1 | ./configure --prefix=/usr \ |
开始编译,完成后生成HTML文档
1 | make && make html |
测试编译结果
1 | make check 2>&1 | tee gmp-check-log |
务必确认测试套件中至少 199 项测试通过。运行以下命令检验结果
1 | awk '/# PASS:/{total+=$3} ; END{print total}' gmp-check-log |
安装软件包及其文档
1 | make install && make install-html |
MPFR
解压MPFR
1 | cd /sources/ |
准备编译MPFR
1 | ./configure --prefix=/usr \ |
开始编译,并生成HTML文档
1 | make && make html |
测试编译结果,并确认所有 198 项测试都能通过
1 | make check |
安装软件包和文档
1 | make install && make install-html |
MPC
解压MPC
1 | cd /sources/ |
准备编译MPC
1 | ./configure --prefix=/usr \ |
开始编译并生成HTML文档
1 | make && make html |
测试编译结果
1 | make check |
安装软件包和文档
1 | make install && make install-html |
Attr
解压Attr
1 | cd /sources/ |
准备编译Attr
1 | ./configure --prefix=/usr \ |
开始编译,然后测试编译结果,完成后安装软件包
1 | make |
Acl
解压Acl
1 | cd /sources/ |
准备编译Acl
1 | ./configure --prefix=/usr \ |
开始编译,完成后安装软件包
1 | make && make install |
Libcap
解压Libcap
1 | cd /sources/ |
防止静态库的安装
1 | sed -i '/install -m.*STA/d' libcap/Makefile |
开始编译
1 | make prefix=/usr lib=lib |
测试编译结果
1 | make test |
安装软件包
1 | make prefix=/usr lib=lib install |
Libxcrypt
解压Libxcrypt
1 | cd /sources/ |
准备编译Libxcrypt
1 | ./configure --prefix=/usr \ |
开始编译,然后测试编译结果,完成后安装软件包
1 | make |
Shadow
解压Shadow
1 | cd /sources/ |
禁止该软件包安装 groups 程序和它的手册页,因为 Coreutils 会提供更好的版本
1 | sed -i 's/groups$(EXEEXT) //' src/Makefile.in |
不使用默认的 crypt 加密方法,使用安全程度高很多的 YESCRYPT 算法加密密码,这也允许设定长度超过 8 个字符的密码。还需要把过时的用户邮箱位置 /var/spool/mail 改为当前普遍使用的 /var/mail 目录。另外,从默认的 PATH 中删除/bin 和 /sbin,因为它们只是指向 /usr 中对应目录的符号链接
1 | sed -e 's:#ENCRYPT_METHOD DES:ENCRYPT_METHOD YESCRYPT:' \ |
准备编译Shadow
1 | touch /usr/bin/passwd |
开始编译
1 | make |
安装软件包
1 | make exec_prefix=/usr install |
对用户和组启用Shadow加密
1 | pwconv |
为了修改默认参数,必须创建 /etc/default/useradd 文件,并定制其内容,以满足您的特定需要
1 | mkdir -p /etc/default |
设置root密码
1 | passwd root |
GCC
在 x86_64 上构建时,修改存放 64 位库的默认路径为 “lib”
1 | cd /sources/gcc-14.2.0 |
准备编译GCC
1 | ../configure --prefix=/usr \ |
开始编译
1 | make |
移除或修复若干已知会失败的测试
1 | sed -e '/cpython/d' -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp |
以非特权用户身份测试编译结果,但出错时继续执行其他测试
1 | chown -R tester . |
查看测试结果
1 | ../contrib/test_summary |
安装软件包
1 | make install |
GCC 构建目录目前属于用户 tester,导致安装的头文件目录 (及其内容) 具有不正确的所有权。将所有者修改为 root 用户和组
1 | chown -v -R root:root \ |
创建一个 FHS 因 “历史原因” 要求的符号链接
1 | ln -svr /usr/bin/cpp /usr/lib |
创建一个软链接cc指向C编译器
1 | ln -sv gcc.1 /usr/share/man/man1/cc.1 |
创建一个兼容性符号链接,以支持在构建程序时使用链接时优化 (LTO)
1 | ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/14.2.0/liblto_plugin.so \ |
进行下列完整性检查
1 | echo 'int main(){}' > dummy.c |
以下是期望输出
1 | [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] |
下面确认我们在使用正确的启动文件
1 | grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log |
以下是期望输出
1 | /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/Scrt1.o succeeded |
确认编译器能正确查找头文件
1 | grep -B4 '^ /usr/include' dummy.log |
以下是期望输出
1 | #include <...> search starts here: |
确认新的链接器使用了正确的搜索路径
1 | grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g' |
忽略包含 ‘-linux-gnu’ 的路径,以下是期望输出
1 | SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64") |
确认使用了正确的 libc
1 | grep "/lib.*/libc.so.6 " dummy.log |
以下是期望输出
1 | attempt to open /usr/lib/libc.so.6 succeeded |
确认 GCC 使用了正确的动态链接器
1 | grep found dummy.log |
以下是期望输出 (不同平台的动态链接器名称可能不同)
1 | found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2 |
如果输出和以上描述不符,或者根本没有输出,那么必然有什么地方出了严重错误。检查并重新跟踪以上步骤,找到问题的原因,并修复它。在继续构建前必须解决这里发现的所有问题。
删除测试文件
1 | rm -v dummy.c a.out dummy.log |
移动一个位置不正确的文件
1 | mkdir -pv /usr/share/gdb/auto-load/usr/lib |
Ncurses
准备编译Ncurses
1 | cd /sources/ncurses-6.5 |
开始编译
1 | make |
安装软件包
1 | make DESTDIR=$PWD/dest install |
许多程序仍然希望链接器能够找到非宽字符版本的 Ncurses 库。通过使用符号链接和链接脚本,诱导它们链接到宽字符库 (注意这里扩展名为 so 的链接只有在已经编辑 curses.h 使之总是使用宽字符 ABI 时才安全)
1 | cat > temp.sh << "EOF" |
创建软链接以确保老式程序仍然能构建
1 | ln -sfv libncursesw.so /usr/lib/libcurses.so |
安装文档
1 | cp -v -R doc -T /usr/share/doc/ncurses-6.5 |
Sed
准备编译Sed
1 | cd /sources/sed-4.9 |
开始编译,并生成HTML文档
1 | make && make html |
测试编译结果
1 | chown -R tester . |
安装软件包和文档
1 | make install |
Psmisc
解压Psmisc
1 | cd /sources/ |
准备编译Psmisc
1 | ./configure --prefix=/usr |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Gettext
准备编译Gettext
1 | cd /sources/ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Bison
准备编译Bison
1 | cd /sources/bison-3.8.2 |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Grep
移除使用 egrep 和 fgrep 时的警告,它会导致一些软件包测试失败
1 | cd /sources/ |
准备编译Grep
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Bash
准备编译Bash
解压Bash
1 | cd /sources/ |
1 | ./configure --prefix=/usr \ |
开始编译
1 | make |
确保 tester 用户可以写入源代码目录,该软件包的测试套件被设计为以非 root 用户身份运行,且该用户必须是标准输入所连接的终端的所有者。为了满足这一条件,使用 Expect 生成一个新的伪终端,并以 tester 用户身份运行测试
1 | chown -R tester . |
测试套件使用 diff 检测测试脚本输出和预期是否存在不同。diff 的任何输出 (以 < 和 > 开头) 都表示测试失败,除非有消息提示可以忽略这里报告的差别。已知一项名为 run-builtins 的测试在一些宿主系统上可能失败,此时该测试输出的第一行和预期存在不同。
安装软件包
1 | make install |
执行新编译的 bash 程序 (替换当前正在执行的版本)
1 | exec /usr/bin/bash --login |
Libtool
解压Libtool
1 | cd /sources/ |
准备编译Libtool
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包,删除掉无用的静态库
1 | make |
GDBM
解压GDBM
1 | cd /sources/ |
准备编译GDBM
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Gperf
解压Gperf
1 | cd /sources/ |
准备编译 Gperf
1 | ./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1 |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Expat
解压Expat
1 | cd /sources/ |
准备编译Expat
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Inetutils
解压Inetutils
1 | cd /sources/ |
使得该软件包能够用 gcc-14.1 或更新版本构建
1 | sed -i 's/def HAVE_TERMCAP_TGETENT/ 1/' telnet/telnet.c |
准备编译Inetutils
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
将一个程序移动到正确位置
1 | mv -v /usr/{,s}bin/ifconfig |
Less
解压Less
1 | cd /sources/ |
准备编译 Less
1 | ./configure --prefix=/usr --sysconfdir=/etc |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Perl
该版本的 Perl 会构建 Compress::Raw::ZLib 和 Compress::Raw::BZip2 模块。默认情况下 Perl 会使用内部的源码副本构建它们。执行以下命令,使得 Perl 使用已经安装到系统上的库
1 | export BUILD_ZLIB=False |
准备编译Perl
1 | sh Configure -des \ |
开始编译
1 | make |
测试编译结果
1 | TEST_JOBS=$(nproc) make test_harness |
安装软件包并清理环境变量
1 | make install |
XML::Parser
解压XML::Parser
1 | cd /sources/ |
准备编译 XML::Parser
1 | perl Makefile.PL |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Intltool
解压Intltool
1 | cd /sources/ |
修复由 perl-5.22 及更新版本导致的警告
1 | sed -i 's:\\\${:\\\$\\{:' intltool-update.in |
准备编译 Intltool
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Autoconf
解压Autoconf
1 | cd /sources/ |
准备编译 Autoconf
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Automake
解压 Automake
1 | cd /sources/ |
准备编译 Automake
1 | ./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.17 |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
OpenSSL
解压OpenSSL
1 | cd /sources/ |
准备编译 OpenSSL
1 | ./config --prefix=/usr \ |
开始编译
1 | make |
测试编译结果
1 | HARNESS_JOBS=$(nproc) make test |
安装软件包
1 | sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile |
将版本号添加到文档目录名,以和其他软件包保持一致
1 | mv -v /usr/share/doc/openssl /usr/share/doc/openssl-3.3.1 |
安装文档
1 | cp -vfr doc/* /usr/share/doc/openssl-3.3.1 |
Kmod
解压Kmod
1 | cd /sources/ |
准备编译Kmod
1 | ./configure --prefix=/usr \ |
开始编译
1 | make |
安装软件包
1 | make install |
Elfutils中的Libelf
解压Elfutils
1 | cd /sources |
准备编译Libelf
1 | ./configure --prefix=/usr \ |
开始编译,然后测试编译结果
1 | make |
安装Libelf
1 | make -C libelf install |
Libffi
解压Libffi
1 | cd /sources/ |
准备编译 Libffi
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Python
解压Python
1 | rm -rf Python-3.12.5 |
准备编译 Python
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
在引导 LFS 系统并配置网络连接后,则会出现一条不同的警告信息,指示用户使用 PyPI 提供的,预先构建的 wheel 档案更新 pip3 (如果有更新的版本)。但是对于 LFS,我们认为 pip3 是 Python 3 的一部分,因此不应单独升级它。另外,使用预先构建的 wheel 包也会偏离我们的目标:从源代码构建 Linux 系统。因此,应该忽略关于 pip3 新版本的警告。如果您不想看到这些警告,可以执行以下命令,创建配置文件,以禁止这些警告
1 | cat > /etc/pip.conf << EOF |
安装文档
1 | install -v -dm755 /usr/share/doc/python-3.12.5/html |
Flit-Core
解压Flit-Core
1 | cd /sources/ |
开始构建,然后安装软件包
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Wheel
解压Wheel
1 | cd /sources/ |
编译Wheel,然后安装
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Setuptools
解压Setuptools
1 | cd /sources |
开始构建,然后安装软件包
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Ninja
解压Ninja
1 | cd /sources/ |
开始构建,然后安装软件包
1 | python3 configure.py --bootstrap |
Meson
解压Meson
1 | cd /sources |
编译Meson,然后安装软件包
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Coreutils
打patch
1 | cd /sources/coreutils-9.5 |
准备编译 Coreutils
1 | autoreconf -fiv |
开始编译
1 | make |
测试编译结果
1 | make NON_ROOT_USERNAME=tester check-root |
安装软件包
1 | make install |
将程序移动到 FHS 要求的位置
1 | mv -v /usr/bin/chroot /usr/sbin |
Check
解压Check
1 | cd /sources/ |
准备编译Check
1 | ./configure --prefix=/usr --disable-static |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Diffutils
解压Diffutils
1 | cd /sources |
准备编译Diffutils
1 | ./configure --prefix=/usr |
开始编译,然后测试编译结果,最后安装软件包
1 | make |
Gawk
确保不安装某些不需要的文件
1 | cd gawk-5.3.0 |
准备编译 Gawk
1 | ./configure --prefix=/usr |
开始编译
1 | make |
测试编译结果
1 | chown -R tester . |
安装软件包
1 | rm -f /usr/bin/gawk-5.3.0 |
Findutils
解压Findutils
1 | cd /sources |
准备编译 Findutils
1 | ./configure --prefix=/usr --localstatedir=/var/lib/locate |
开始编译
1 | make |
测试编译结果
1 | chown -R tester . |
安装软件包
1 | make install |
Groff
解压Groff
1 | tar -xf groff-1.23.0.tar.gz |
准备编译 Groff
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
GRUB
解压GRUB
1 | cd /sources |
移除所有可能影响构建的环境变量
1 | unset {C,CPP,CXX,LD}FLAGS |
补充源码包发布时缺失的一个文件
1 | echo depends bli part_gpt > grub-core/extra_deps.lst |
准备编译GRUB
1 | ./configure --prefix=/usr \ |
开始编译,然后安装软件包
1 | make |
Gzip
解压Gzip
1 | cd /sources/ |
准备编译Gzip
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
IPRoute2
解压IPRoute2
1 | cd /sources |
该软件包中的 arpd 程序依赖于 LFS 不安装的 Berkeley DB,因此不会被构建。然而,用于 arpd 的一个目录和它的手册页仍会被安装。运行以下命令以防止它们的安装
1 | sed -i /ARPD/d Makefile |
开始编译
1 | make NETNS_RUN_DIR=/run/netns |
安装软件包和文档
1 | make SBINDIR=/usr/sbin install |
Kbd
解压Kbd
1 | cd /sources |
打patch
1 | patch -Np1 -i ../kbd-2.6.4-backspace-1.patch |
删除多余的 resizecons 程序 (它需要已经不存在的 svgalib 提供视频模式文件 —— 一般使用 setfont 即可调整控制台大小) 及其手册页
1 | sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure |
准备编译 Kbd
1 | ./configure --prefix=/usr --disable-vlock |
开始编译,完成后测试编译结果,最后安装软件包和文档
1 | make |
Libpipeline
解压Libpipeline
1 | cd /sources |
准备编译 Libpipeline
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Make
解压Make
1 | cd /sources |
准备编译 Make
1 | ./configure --prefix=/usr |
开始编译
1 | make |
测试编译结果
1 | chown -R tester . |
安装软件包
1 | make install |
Patch
解压Patch
1 | cd /sources |
准备编译 Patch
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Tar
解压Tar
1 | cd /sources |
准备编译 Tar
1 | FORCE_UNSAFE_CONFIGURE=1 \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
测试出现错误
1 | 233: capabilities: binary store/restore FAILED (capabs_raw01.at:28) |
Texinfo
解压Texinfo
1 | cd /sources |
准备编译Texinfo
1 | ./configure --prefix=/usr |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Vim
解压Vim
1 | cd /sources/ |
修改 vimrc 配置文件的默认位置为 /etc
1 | echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h |
准备编译 Vim
1 | ./configure --prefix=/usr |
开始编译
1 | make |
测试编译结果
1 | chown -R tester . |
安装软件包
1 | make install |
为了在用户习惯性地输入 vi 时能够执行 vim,为二进制程序和各种语言的手册页创建符号链接
1 | ln -sv vim /usr/bin/vi |
创建符号链接,使得可以通过 /usr/share/doc/vim-9.1.0660 访问文档,这个路径与其他软件包的文档位置格式一致
1 | ln -sv ../vim/vim91/doc /usr/share/doc/vim-9.1.0660 |
创建默认Vim配置文件
1 | cat > /etc/vimrc << "EOF" |
MarkupSafe
解压MarkupSafe
1 | cd /sources |
编译MarkupSafe,然后安装软件包
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Jinja2
解压Jinja2
1 | cd /sources |
构建Jinja2,然后安装软件包
1 | pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD |
Systemd中的Udev
解压Systemd
1 | cd /sources/ |
从默认的 udev 规则中删除不必要的组 render 和 sgx
1 | sed -i -e 's/GROUP="render"/GROUP="video"/' \ |
删除一条需要完整安装 Systemd 的 udev 规则
1 | sed '/systemd-sysctl/s/^/#/' -i rules.d/99-systemd.rules.in |
调整硬编码的网络配置文件路径,使之适合单独安装 udev
1 | sed '/NETWORK_DIRS/s/systemd/udev/' -i src/basic/path-lookup.h |
创建一个用于构建的目录
1 | mkdir -v build |
准备编译Udev
1 | meson setup .. \ |
获取软件包提供的 udev 辅助程序列表并将其保存到环境变量中
1 | export udev_helpers=$(grep "'name' :" ../src/udev/meson.build | \ |
只构建 udev 需要的组件
1 | ninja udevadm systemd-hwdb \ |
安装软件包
1 | install -vm755 -d {/usr/lib,/etc}/udev/{hwdb.d,rules.d,network} |
安装一些在 LFS 环境中很有用的自定义规则和支持文件
1 | tar -xvf ../../udev-lfs-20230818.tar.xz |
安装手册页
1 | tar -xf ../../systemd-man-pages-256.4.tar.xz \ |
移除 udev_helpers 变量
1 | unset udev_helpers |
硬件设备的相关信息被维护在 /etc/udev/hwdb.d 和 /usr/lib/udev/hwdb.d 目录中。Udev 需要将这些信息编译到二进制数据库 /etc/udev/hwdb.bin 中。初始化该数据库
1 | udev-hwdb update |
Man-DB
解压Man-DB
1 | cd /sources |
准备编译 Man-DB
1 | ./configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
Procps-ng
解压Procps-ng
1 | cd /sources |
准备编译 Procps-ng
1 | ./configure --prefix=/usr \ |
开始编译
1 | make |
测试编译结果
1 | chown -R tester . |
安装软件包
1 | make install |
Util-Linux
解压Util-Linux
1 | cd /sources |
准备编译 Util-linux
1 | ./configure --bindir=/usr/bin \ |
开始编译
1 | make |
测试编译结果
1 | touch /etc/fstab |
安装软件包
1 | make install |
E2fsprogs
解压E2fsprogs
1 | cd /sources |
创建一个用于构建的目录
1 | mkdir -v build |
准备编译 E2fsprogs
1 | ../configure --prefix=/usr \ |
开始编译,完成后测试编译结果,最后安装软件包
1 | make |
删除无用的静态库
1 | rm -fv /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a |
该软件包安装了一个 gzip 压缩的 .info 文件,却没有更新系统的 dir 文件。执行以下命令解压该文件,并更新系统 dir 文件
1 | gunzip -v /usr/share/info/libext2fs.info.gz |
安装文档
1 | makeinfo -o doc/com_err.info ../lib/et/com_err.texinfo |
/etc/mke2fs.conf 包含 mke2fs 一些命令行选项的默认值。您可以修改这些默认值,使之符合您的需求。例如,一些工具 (未被 LFS 或 BLFS 包含) 无法识别启用了 metadata_csum_seed 特性的 ext4 文件系统。如果需要使用这样的工具,可以执行命令,从默认的 ext4 特性列表中移除该特性
1 | sed 's/metadata_csum_seed,//' -i /etc/mke2fs.conf |
Sysklogd
解压Sysklogd
1 | cd /sources |
准备编译Sysklogd
1 | ./configure --prefix=/usr \ |
开始编译,然后安装软件包
1 | make |
创建一个新的 /etc/syslog.conf 文件
1 | cat > /etc/syslog.conf << "EOF" |
SysVinit
解压SysVinit
1 | cd /sources |
打patch
1 | patch -Np1 -i ../sysvinit-3.10-consolidated-1.patch |
开始编译,然后安装软件包
1 | make |
软件包基本安装完毕,这里不进行符号移除,有需要可以查看手册8.84. 移除调试符号
现在清除测试时遗留的一些文件
1 | rm -rf /tmp/{*,.*} |
