NakanoMiku
文章10
标签12
分类3
构造基于x86_64的LFS(3)

构造基于x86_64的LFS(3)

继续构造LFS,从安装基本系统软件开始

安装基本系统软件

因为上次备份系统离开了chroot环境,所有现在要重新进入,先挂载虚拟内核文件系统,再进入chroot
值得注意的是,这次也不需要设定环境变量$LFS

mount -v --bind /dev $LFS/dev
mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run

if [ -h $LFS/dev/shm ]; then
  install -v -d -m 1777 $LFS$(realpath /dev/shm)
else
  mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm
fi

chroot "$LFS" /usr/bin/env -i   \
    HOME=/root                  \
    TERM="$TERM"                \
    PS1='(lfs chroot) \u:\w\$ ' \
    PATH=/usr/bin:/usr/sbin     \
    MAKEFLAGS="-j$(nproc)"      \
    TESTSUITEFLAGS="-j$(nproc)" \
    /bin/bash --login

这里将不涉及任何软件包管理,而是直接进入到软件包的安装

Man-pages

Man-pages 软件包包含 2,400 多个手册页。
解压Man-pages

cd /sources/
tar -xf man-pages-6.9.1.tar.xz 
cd man-pages-6.9.1

移除描述密码散列函数的两个手册页。Libxcrypt 会提供这些手册页的更好版本。

rm -v man3/crypt*

安装Man-pages

make prefix=/usr install

Iana-Etc

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

cd /sources/
tar -xf iana-etc-20240806.tar.gz
cd iana-etc-20240806

只需把文件复制到正确位置就行

cp services protocols /etc

Glibc

进入Glibc,先打一个补丁

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

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

删除之前的build目录并新建一个

rm -rf build/
mkdir -v build
cd       build

确保将 ldconfigsln 工具安装到 /usr/sbin 目录中

echo "rootsbindir=/usr/sbin" > configparms

准备编译Gblic

../configure --prefix=/usr                            \
             --disable-werror                         \
             --enable-kernel=4.19                     \
             --enable-stack-protector=strong          \
             --disable-nscd                           \
             libc_cv_slibdir=/usr/lib

编译Glibc

make

编译完成后进行测试,在这之前需要先跳过一些测试

sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile
touch /etc/ld.so.conf
make check

测试通过后安装软件包

make install

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

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

安装locale,这里就直接安装所有的了。

make localedata/install-locales

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

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

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

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

# End /etc/nsswitch.conf
EOF

安装并设置时区数据

cat > temp.sh << "EOF"
tar -xf ../../tzdata2024a.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
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh

确定本地时区

tzselect

然后根据时区创建/etc/localtime,根据上面脚本的运行结果自行决定是否替换Asia/Shanghai字段

ln -sfv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

现在配置动态加载器,创建一个新的/etc/ld.so.conf

cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib

EOF

Zlib

解压Zlib

cd /sources/
tar -xvf zlib-1.3.1.tar.gz
cd zlib-1.3.1

准备编译Zlib

./configure --prefix=/usr

开始编译,然后测试编译结果,最后安装软件包

make
make check
make install

删除无用的静态库

rm -fv /usr/lib/libz.a

Bzip2

解压Bzip2

cd /sources/
tar -xvf bzip2-1.0.8.tar.gz
cd bzip2-1.0.8

打补丁

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

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

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

确保手册页被安装到正确位置

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

准备编译Bzip2

make -f Makefile-libbz2_so
make clean

开始编译并测试软件包

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 完全相同的文件替换成符号链接

cat > temp.sh << "EOF"
cp -v bzip2-shared /usr/bin/bzip2
for i in /usr/bin/{bzcat,bunzip2}; do
  ln -sfv bzip2 $i
done
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh

删除无用的静态库

rm -fv /usr/lib/libbz2.a

Xz

之前已经解压过了,直接进入Xz目录

cd /sources/xz-5.6.2

准备编译Xz

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Lz4

解压Lz4

cd /sources/
tar -xf lz4-1.10.0.tar.gz 
cd lz4-1.10.0/

开始编译,然后测试编译结果,最后安装软件包

make BUILD_STATIC=no PREFIX=/usr
make -j1 check
make BUILD_STATIC=no PREFIX=/usr install

Zstd

解压Zstd

cd /sources/
tar -xf zstd-1.5.6.tar.gz 
cd zstd-1.5.6/

开始编译,然后测试编译结果,最后安装软件包

make prefix=/usr
make check
make prefix=/usr install

删除静态库

rm -v /usr/lib/libzstd.a

File

进入File目录

cd /sources/File-5.45/

准备编译File

./configure --prefix=/usr

开始编译,然后测试编译结果,最后安装软件包

make
make check
make install

Readline

解压Readline

cd /sources/
tar -xvf readline-8.2.13.tar.gz
cd readline-8.2.13

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

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

下面防止在共享库中硬编码库文件搜索路径 (rpath)。该软件包在安装到标准位置时并不需要 rpath,而且 rpath 在一些情况下会产生我们不希望的副作用,甚至导致安全问题

sed -i 's/-Wl,-rpath,[^ ]*//' support/shobj-conf

准备编译Readline

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

开始编译,完成后安装软件包

make SHLIB_LIBS="-lncursesw"
make SHLIB_LIBS="-lncursesw" install

安装软件包的文档

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

M4

进入M4目录

cd /sources/m4-1.4.19

准备编译M4

./configure --prefix=/usr

开始编译,然后测试编译结果,最后安装软件包

make
make check
make install

Bc

解压Bc

cd /sources/
tar -xvf bc-6.7.6.tar.xz 
cd bc-6.7.6

准备编译Bc

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

开始编译,然后测试编译结果,最后安装软件包

make
make test
make install

Flex

解压Flex

cd /sources/
tar -xvf flex-2.6.4.tar.gz
cd flex-2.6.4

准备编译Flex

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

开始编译,然后测试编译结果,最后安装软件包

make
make check
make install

创建软连接

ln -sv flex   /usr/bin/lex
ln -sv flex.1 /usr/share/man/man1/lex.1

Tcl

解压Tcl

cd /source/
tar -xf tcl8.6.14-src.tar.gz 
cd tcl8.6.14

准备编译Tcl

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

开始编译

make

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

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

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

unset SRCDIR

测试编译结果,然后安装软件包

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 手册页文件名冲突的手册页

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

安装文档

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

Expect

解压Expect

cd /sources/
tar -xf expect5.45.4.tar.gz
cd expect5.45.4

Expect 需要伪终端 (PTY) 才能正常工作。进行简单测试以验证 PTY 是否在 chroot 环境中正常工作,若输出ok则继续,否则仔细阅读处理方法8.17.1. 安装 Expect

python3 -c 'from pty import spawn; spawn(["echo", "ok"])'

打patch

patch -Np1 -i ../expect-5.45.4-gcc14-1.patch

准备编译Expect

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

开始编译,然后测试编译结果,最后安装软件包

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

DejaGNU

解压DejaGNU

cd /sources/
tar -xvf dejagnu-1.6.3.tar.gz
cd dejagnu-1.6.3

单独创建一个目录用于构建

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 check

安装软件包

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

Pkgconf

解压Pkgconf

cd /sources/
tar -xf pkgconf-2.3.0.tar.xz
cd pkgconf-2.3.0

准备编译Pkgconf

./configure --prefix=/usr              \
            --disable-static           \
            --docdir=/usr/share/doc/pkgconf-2.3.0

开始编译,完成后安装软件包

make && make install

为了维持与原始的 Pkg-config 软件包的兼容性,创建两个符号链接

ln -sv pkgconf   /usr/bin/pkg-config
ln -sv pkgconf.1 /usr/share/man/man1/pkg-config.1

Binutils

重新创建单独用于构建的目录

cd /sources/
rm -rf build/
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 \
             --enable-new-dtags  \
             --with-system-zlib  \
             --enable-default-hash-style=gnu

开始编译

make tooldir=/usr

测试编译结果

make -k check

Gold 测试套件中,有十二项测试在构建 GCC 时启用 –enable-default-pie 和 –enable-default-ssp 的情况下会失败。请仔细核对失败的测试数量

安装软件包

make tooldir=/usr install

删除无用的静态库

rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,gprofng,opcodes,sframe}.a

GMP

解压GMP

cd /sources/
tar -xvf gmp-6.3.0.tar.xz
cd gmp-6.3.0

准备编译GMP

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

开始编译,完成后生成HTML文档

make && make html

测试编译结果

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

务必确认测试套件中至少 199 项测试通过。运行以下命令检验结果

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

安装软件包及其文档

make install && make install-html

MPFR

解压MPFR

cd /sources/
tar -xvf mpfr-4.2.1.tar.xz 
cd mpfr-4.2.1

准备编译MPFR

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

开始编译,并生成HTML文档

make && make html

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

make check

安装软件包和文档

make install && make install-html

MPC

解压MPC

cd /sources/
tar -xvf mpc-1.3.1.tar.gz
cd mpc-1.3.1

准备编译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

Attr

解压Attr

cd /sources/
tar -xvf attr-2.5.2.tar.gz 
cd attr-2.5.2

准备编译Attr

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

开始编译,然后测试编译结果,完成后安装软件包

make
make check
make install

Acl

解压Acl

cd /sources/
tar -xvf acl-2.3.2.tar.xz 
cd acl-2.3.2

准备编译Acl

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

开始编译,完成后安装软件包

make && make install

Libcap

解压Libcap

cd /sources/
tar -xvf libcap-2.70.tar.xz
cd libcap-2.70

防止静态库的安装

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

开始编译

make prefix=/usr lib=lib

测试编译结果

make test

安装软件包

make prefix=/usr lib=lib install

Libxcrypt

解压Libxcrypt

cd /sources/
tar -xvf libxcrypt-4.4.36.tar.xz
cd libxcrypt-4.4.36

准备编译Libxcrypt

./configure --prefix=/usr                \
            --enable-hashes=strong,glibc \
            --enable-obsolete-api=no     \
            --disable-static             \
            --disable-failure-tokens

开始编译,然后测试编译结果,完成后安装软件包

make
make check
make install

Shadow

解压Shadow

cd /sources/
tar -xvf shadow-4.16.0.tar.xz 
cd shadow-4.16.0

禁止该软件包安装 groups 程序和它的手册页,因为 Coreutils 会提供更好的版本

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 加密方法,使用安全程度高很多的 YESCRYPT 算法加密密码,这也允许设定长度超过 8 个字符的密码。还需要把过时的用户邮箱位置 /var/spool/mail 改为当前普遍使用的 /var/mail 目录。另外,从默认的 PATH 中删除/bin 和 /sbin,因为它们只是指向 /usr 中对应目录的符号链接

sed -e 's:#ENCRYPT_METHOD DES:ENCRYPT_METHOD YESCRYPT:' \
    -e 's:/var/spool/mail:/var/mail:'                   \
    -e '/PATH=/{s@/sbin:@@;s@/bin:@@}'                  \
    -i etc/login.defs

准备编译Shadow

touch /usr/bin/passwd
./configure --sysconfdir=/etc   \
            --disable-static    \
            --with-{b,yes}crypt \
            --without-libbsd    \
            --with-group-name-max-length=32

开始编译

make

安装软件包

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

对用户和组启用Shadow加密

pwconv
grpconv

为了修改默认参数,必须创建 /etc/default/useradd 文件,并定制其内容,以满足您的特定需要

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

设置root密码

passwd root

GCC

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

cd /sources/gcc-14.2.0
rm -rf build/
cat > temp.sh << "EOF"
case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh
mkdir -v build/
cd build/

准备编译GCC

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

开始编译

make

移除或修复若干已知会失败的测试

sed -e '/cpython/d'               -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
sed -e 's/no-pic /&-no-pie /'     -i ../gcc/testsuite/gcc.target/i386/pr113689-1.c
sed -e 's/300000/(1|300000)/'     -i ../libgomp/testsuite/libgomp.c-c++-common/pr109062.c
sed -e 's/{ target nonpic } //' \
    -e '/GOTPCREL/d'              -i ../gcc/testsuite/gcc.target/i386/fentryname3.c

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

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

查看测试结果

../contrib/test_summary

安装软件包

make install

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

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

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

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

创建一个软链接cc指向C编译器

ln -sv gcc.1 /usr/share/man/man1/cc.1

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

ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/14.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/14.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crtn.o succeeded

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

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

以下是期望输出

#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/14.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");

确认使用了正确的 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

Ncurses

准备编译Ncurses

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

开始编译

make

安装软件包

make DESTDIR=$PWD/dest install
install -vm755 dest/usr/lib/libncursesw.so.6.5 /usr/lib
rm -v  dest/usr/lib/libncursesw.so.6.5
sed -e 's/^#if.*XOPEN.*$/#if 1/' \
    -i dest/usr/include/curses.h
cp -av dest/* /

许多程序仍然希望链接器能够找到非宽字符版本的 Ncurses 库。通过使用符号链接和链接脚本,诱导它们链接到宽字符库 (注意这里扩展名为 so 的链接只有在已经编辑 curses.h 使之总是使用宽字符 ABI 时才安全)

cat > temp.sh << "EOF"
for lib in ncurses form panel menu ; do
    ln -sfv lib${lib}w.so /usr/lib/lib${lib}.so
    ln -sfv ${lib}w.pc    /usr/lib/pkgconfig/${lib}.pc
done
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh

创建软链接以确保老式程序仍然能构建

ln -sfv libncursesw.so /usr/lib/libcurses.so

安装文档

cp -v -R doc -T /usr/share/doc/ncurses-6.5

Sed

准备编译Sed

cd /sources/sed-4.9
./configure --prefix=/usr

开始编译,并生成HTML文档

make && make html

测试编译结果

chown -R 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

Psmisc

解压Psmisc

cd /sources/
tar -xvf psmisc-23.7.tar.xz
cd psmisc-23.7

准备编译Psmisc

./configure --prefix=/usr

开始编译,然后测试编译结果,最后安装软件包

make
make check
make install

Gettext

准备编译Gettext

cd /sources/
rm -rf gettext-0.22.5
tar -xf gettext-0.22.5.tar.xz
cd gettext-0.22.5
./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/gettext-0.22.5

开始编译,完成后测试编译结果,最后安装软件包

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

Bison

准备编译Bison

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Grep

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

cd /sources/
rm -rf grep-3.11
tar -xf grep-3.11.tar.xz
cd grep-3.11
sed -i "s/echo/#echo/" src/egrep.sh

准备编译Grep

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Bash

准备编译Bash
解压Bash

cd /sources/
rm -rf bash-5.2.32
tar -xvf bash-5.2.32.tar.gz
cd bash-5.2.32
./configure --prefix=/usr             \
            --without-bash-malloc     \
            --with-installed-readline \
            bash_cv_strtold_broken=no \
            --docdir=/usr/share/doc/bash-5.2.32

开始编译

make

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

chown -R 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

Libtool

解压Libtool

cd /sources/
tar -xf libtool-2.4.7.tar.xz 
cd libtool-2.4.7

准备编译Libtool

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包,删除掉无用的静态库

make
make -k check
make install
rm -fv /usr/lib/libltdl.a

GDBM

解压GDBM

cd /sources/
tar -xf gdbm-1.24.tar.gz 
cd gdbm-1.24

准备编译GDBM

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Gperf

解压Gperf

cd /sources/
tar -xf gperf-3.1.tar.gz
cd gperf-3.1

准备编译 Gperf

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

开始编译,完成后测试编译结果,最后安装软件包

make
make -j1 check
make install

Expat

解压Expat

cd /sources/
tar -xf expat-2.6.2.tar.xz
cd expat-2.6.2

准备编译Expat

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

开始编译,完成后测试编译结果,最后安装软件包

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

Inetutils

解压Inetutils

cd /sources/
tar -xf inetutils-2.5.tar.xz
cd inetutils-2.5

使得该软件包能够用 gcc-14.1 或更新版本构建

sed -i 's/def HAVE_TERMCAP_TGETENT/ 1/' telnet/telnet.c

准备编译Inetutils

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

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

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

Less

解压Less

cd /sources/
tar -xf less-661.tar.gz
cd less-661

准备编译 Less

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Perl

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

export BUILD_ZLIB=False
export BUILD_BZIP2=0

准备编译Perl

sh Configure -des                                          \
             -D prefix=/usr                                \
             -D vendorprefix=/usr                          \
             -D privlib=/usr/lib/perl5/5.40/core_perl      \
             -D archlib=/usr/lib/perl5/5.40/core_perl      \
             -D sitelib=/usr/lib/perl5/5.40/site_perl      \
             -D sitearch=/usr/lib/perl5/5.40/site_perl     \
             -D vendorlib=/usr/lib/perl5/5.40/vendor_perl  \
             -D vendorarch=/usr/lib/perl5/5.40/vendor_perl \
             -D man1dir=/usr/share/man/man1                \
             -D man3dir=/usr/share/man/man3                \
             -D pager="/usr/bin/less -isR"                 \
             -D useshrplib                                 \
             -D usethreads

开始编译

make

测试编译结果

TEST_JOBS=$(nproc) make test_harness

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

make install
unset BUILD_ZLIB BUILD_BZIP2

XML::Parser

解压XML::Parser

cd /sources/
tar -xf XML-Parser-2.47.tar.gz
cd XML-Parser-2.47

准备编译 XML::Parser

perl Makefile.PL

开始编译,完成后测试编译结果,最后安装软件包

make
make test
make install

Intltool

解压Intltool

cd /sources/
tar -xf intltool-0.51.0.tar.gz
cd intltool-0.51.0

修复由 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

Autoconf

解压Autoconf

cd /sources/
tar -xf autoconf-2.72.tar.xz
cd autoconf-2.72

准备编译 Autoconf

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Automake

解压 Automake

cd /sources/
tar -xf automake-1.17.tar.xz 
cd automake-1.17

准备编译 Automake

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

开始编译,完成后测试编译结果,最后安装软件包

make
make -j$(($(nproc)>4?$(nproc):4)) check
make install

OpenSSL

解压OpenSSL

cd /sources/
tar -xf openssl-3.3.1.tar.gz
cd openssl-3.3.1

准备编译 OpenSSL

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

开始编译

make

测试编译结果

HARNESS_JOBS=$(nproc) make test

安装软件包

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.3.1

安装文档

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

Kmod

解压Kmod

cd /sources/
tar -xf kmod-33.tar.xz
cd kmod-33

准备编译Kmod

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

开始编译

make

安装软件包

make install

cat > temp.sh << "EOF"
for target in depmod insmod modinfo modprobe rmmod; do
  ln -sfv ../bin/kmod /usr/sbin/$target
  rm -fv /usr/bin/$target
done
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh

Elfutils中的Libelf

解压Elfutils

cd /sources
tar -xf elfutils-0.191.tar.bz2 
cd elfutils-0.191

准备编译Libelf

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

开始编译,然后测试编译结果

make
make check

安装Libelf

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

Libffi

解压Libffi

cd /sources/
tar -xf libffi-3.4.6.tar.gz 
cd libffi-3.4.6.

准备编译 Libffi

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

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Python

解压Python

rm -rf Python-3.12.5
tar -xf Python-3.12.5.tar.xz
cd Python-3.12.5

准备编译 Python

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

开始编译,完成后测试编译结果,最后安装软件包

make
make test TESTOPTS="--timeout 120"
make install

在引导 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

安装文档

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

tar --no-same-owner \
    -xvf ../python-3.12.5-docs-html.tar.bz2
cp -R --no-preserve=mode python-3.12.5-docs-html/* \
    /usr/share/doc/python-3.12.5/html

Flit-Core

解压Flit-Core

cd /sources/
tar -xf flit_core-3.9.0.tar.gz 
cd flit_core-3.9.0

开始构建,然后安装软件包

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --no-user --find-links dist flit_core

Wheel

解压Wheel

cd /sources/
tar -xvf wheel-0.44.0.tar.gz
cd wheel-0.44.0

编译Wheel,然后安装

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links=dist wheel

Setuptools

解压Setuptools

cd /sources
tar -xf setuptools-72.2.0.tar.gz
cd setuptools-72.2.0

开始构建,然后安装软件包

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist setuptools

Ninja

解压Ninja

cd /sources/
tar -xf ninja-1.12.1.tar.gz
cd ninja-1.12.1

开始构建,然后安装软件包

python3 configure.py --bootstrap
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

Meson

解压Meson

cd /sources
tar -xf meson-1.5.1.tar.gz 
cd meson-1.5.1

编译Meson,然后安装软件包

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
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

Coreutils

打patch

cd /sources/coreutils-9.5
patch -Np1 -i ../coreutils-9.5-i18n-2.patch

准备编译 Coreutils

autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
            --prefix=/usr            \
            --enable-no-install-program=kill,uptime

开始编译

make

测试编译结果

make NON_ROOT_USERNAME=tester check-root
groupadd -g 102 dummy -U tester
chown -R tester . 
su tester -c "PATH=$PATH make -k RUN_EXPENSIVE_TESTS=yes check" \
   < /dev/null
groupdel dummy

安装软件包

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

Check

解压Check

cd /sources/
tar -xf check-0.15.2.tar.gz
cd check-0.15.2

准备编译Check

./configure --prefix=/usr --disable-static

开始编译,然后测试编译结果,最后安装软件包

make
make check
make docdir=/usr/share/doc/check-0.15.2 install

Diffutils

解压Diffutils

cd /sources
tar -xf diffutils-3.10.tar.xz
cd diffutils-3.10

准备编译Diffutils

./configure --prefix=/usr

开始编译,然后测试编译结果,最后安装软件包

make
make check
make docdir=/usr/share/doc/check-0.15.2 install

Gawk

确保不安装某些不需要的文件

cd gawk-5.3.0
sed -i 's/extras//' Makefile.in

准备编译 Gawk

./configure --prefix=/usr

开始编译

make

测试编译结果

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

安装软件包

rm -f /usr/bin/gawk-5.3.0
make install

Findutils

解压Findutils

cd /sources
tar -xf findutils-4.10.0.tar.xz 
cd findutils-4.10.0

准备编译 Findutils

./configure --prefix=/usr --localstatedir=/var/lib/locate

开始编译

make

测试编译结果

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

安装软件包

make install

Groff

解压Groff

tar -xf groff-1.23.0.tar.gz

准备编译 Groff

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

GRUB

解压GRUB

cd /sources
tar -xf grub-2.12.tar.xz 
cd grub-2.12

移除所有可能影响构建的环境变量

unset {C,CPP,CXX,LD}FLAGS

补充源码包发布时缺失的一个文件

echo depends bli part_gpt > grub-core/extra_deps.lst

准备编译GRUB

./configure --prefix=/usr          \
            --sysconfdir=/etc      \
            --disable-efiemu       \
            --disable-werror

开始编译,然后安装软件包

make
make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions

Gzip

解压Gzip

cd /sources/
rm -rf gzip-1.13
tar -xf gzip-1.13.tar.xz 
cd gzip-1.13

准备编译Gzip

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

IPRoute2

解压IPRoute2

cd /sources
tar -xf iproute2-6.10.0.tar.xz
cd iproute2-6.10.0

该软件包中的 arpd 程序依赖于 LFS 不安装的 Berkeley DB,因此不会被构建。然而,用于 arpd 的一个目录和它的手册页仍会被安装。运行以下命令以防止它们的安装

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.10.0
cp -v COPYING README* /usr/share/doc/iproute2-6.10.0

Kbd

解压Kbd

cd /sources
tar -xf kbd-2.6.4.tar.xz
cd kbd-2.6.4

打patch

patch -Np1 -i ../kbd-2.6.4-backspace-1.patch

删除多余的 resizecons 程序 (它需要已经不存在的 svgalib 提供视频模式文件 —— 一般使用 setfont 即可调整控制台大小) 及其手册页

sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in

准备编译 Kbd

./configure --prefix=/usr --disable-vlock

开始编译,完成后测试编译结果,最后安装软件包和文档

make
make check
make install
cp -R -v docs/doc -T /usr/share/doc/kbd-2.6.4

Libpipeline

解压Libpipeline

cd /sources
tar -xf libpipeline-1.5.7.tar.gz 
cd libpipeline-1.5.7

准备编译 Libpipeline

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Make

解压Make

cd /sources
rm -rf make-4.4.1
tar -xf make-4.4.1.tar.gz
cd make-4.4.1

准备编译 Make

./configure --prefix=/usr

开始编译

make

测试编译结果

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

安装软件包

make install

Patch

解压Patch

cd /sources
tar -xf patch-2.7.6.tar.xz 
cd patch-2.7.6

准备编译 Patch

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Tar

解压Tar

cd /sources
rm -rf tar-1.35
tar -xf tar-1.35.tar.xz
cd tar-1.35

准备编译 Tar

FORCE_UNSAFE_CONFIGURE=1  \
./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install
make -C doc install-html docdir=/usr/share/doc/tar-1.35

测试出现错误

233: capabilities: binary store/restore              FAILED (capabs_raw01.at:28)

Texinfo

解压Texinfo

cd /sources
rm -rf texinfo-7.1
tar -xf texinfo-7.1.tar.xz
cd texinfo-7.1

准备编译Texinfo

./configure --prefix=/usr

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Vim

解压Vim

cd /sources/
tar -xf vim-9.1.0660.tar.gz
cd vim-9.1.0660

修改 vimrc 配置文件的默认位置为 /etc

echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h

准备编译 Vim

./configure --prefix=/usr

开始编译

make

测试编译结果

chown -R tester .
su tester -c "TERM=xterm-256color LANG=en_US.UTF-8 make -j1 test" \
   &> vim-test.log

安装软件包

make install

为了在用户习惯性地输入 vi 时能够执行 vim,为二进制程序和各种语言的手册页创建符号链接

ln -sv vim /usr/bin/vi
cat > temp.sh << "EOF"
for L in  /usr/share/man/{,*/}man1/vim.1; do
    ln -sv vim.1 $(dirname $L)/vi.1
done
EOF

chmod +x temp.sh
./temp.sh
rm temp.sh

创建符号链接,使得可以通过 /usr/share/doc/vim-9.1.0660 访问文档,这个路径与其他软件包的文档位置格式一致

ln -sv ../vim/vim91/doc /usr/share/doc/vim-9.1.0660

创建默认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

MarkupSafe

解压MarkupSafe

cd /sources
tar -xf MarkupSafe-2.1.5.tar.gz 
cd MarkupSafe-2.1.5

编译MarkupSafe,然后安装软件包

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --no-user --find-links dist Markupsafe

Jinja2

解压Jinja2

cd /sources
tar -xf jinja2-3.1.4.tar.gz 
cd jinja2-3.1.4

构建Jinja2,然后安装软件包

pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --no-user --find-links dist Jinja2

Systemd中的Udev

解压Systemd

cd /sources/
tar -xf systemd-256.4.tar.gz 
cd systemd-256.4

从默认的 udev 规则中删除不必要的组 render 和 sgx

sed -i -e 's/GROUP="render"/GROUP="video"/' \
       -e 's/GROUP="sgx", //' rules.d/50-udev-default.rules.in

删除一条需要完整安装 Systemd 的 udev 规则

sed '/systemd-sysctl/s/^/#/' -i rules.d/99-systemd.rules.in

调整硬编码的网络配置文件路径,使之适合单独安装 udev

sed '/NETWORK_DIRS/s/systemd/udev/' -i src/basic/path-lookup.h

创建一个用于构建的目录

mkdir -v build
cd build

准备编译Udev

meson setup ..                  \
      --prefix=/usr             \
      --buildtype=release       \
      -D mode=release           \
      -D dev-kvm-mode=0660      \
      -D link-udev-shared=false \
      -D logind=false           \
      -D vconsole=false

获取软件包提供的 udev 辅助程序列表并将其保存到环境变量中

export udev_helpers=$(grep "'name' :" ../src/udev/meson.build | \
                      awk '{print $3}' | tr -d ",'" | grep -v 'udevadm')

只构建 udev 需要的组件

ninja udevadm systemd-hwdb                                           \
      $(ninja -n | grep -Eo '(src/(lib)?udev|rules.d|hwdb.d)/[^ ]*') \
      $(realpath libudev.so --relative-to .)                         \
      $udev_helpers

安装软件包

install -vm755 -d {/usr/lib,/etc}/udev/{hwdb.d,rules.d,network}
install -vm755 -d /usr/{lib,share}/pkgconfig
install -vm755 udevadm                             /usr/bin/
install -vm755 systemd-hwdb                        /usr/bin/udev-hwdb
ln      -svfn  ../bin/udevadm                      /usr/sbin/udevd
cp      -av    libudev.so{,*[0-9]}                 /usr/lib/
install -vm644 ../src/libudev/libudev.h            /usr/include/
install -vm644 src/libudev/*.pc                    /usr/lib/pkgconfig/
install -vm644 src/udev/*.pc                       /usr/share/pkgconfig/
install -vm644 ../src/udev/udev.conf               /etc/udev/
install -vm644 rules.d/* ../rules.d/README         /usr/lib/udev/rules.d/
install -vm644 $(find ../rules.d/*.rules \
                      -not -name '*power-switch*') /usr/lib/udev/rules.d/
install -vm644 hwdb.d/*  ../hwdb.d/{*.hwdb,README} /usr/lib/udev/hwdb.d/
install -vm755 $udev_helpers                       /usr/lib/udev
install -vm644 ../network/99-default.link          /usr/lib/udev/network

安装一些在 LFS 环境中很有用的自定义规则和支持文件

tar -xvf ../../udev-lfs-20230818.tar.xz
make -f udev-lfs-20230818/Makefile.lfs install

安装手册页

tar -xf ../../systemd-man-pages-256.4.tar.xz                            \
    --no-same-owner --strip-components=1                              \
    -C /usr/share/man --wildcards '*/udev*' '*/libudev*'              \
                                  '*/systemd.link.5'                  \
                                  '*/systemd-'{hwdb,udevd.service}.8

sed 's|systemd/network|udev/network|'                                 \
    /usr/share/man/man5/systemd.link.5                                \
  > /usr/share/man/man5/udev.link.5

sed 's/systemd\(\\\?-\)/udev\1/' /usr/share/man/man8/systemd-hwdb.8   \
                               > /usr/share/man/man8/udev-hwdb.8

sed 's|lib.*udevd|sbin/udevd|'                                        \
    /usr/share/man/man8/systemd-udevd.service.8                       \
  > /usr/share/man/man8/udevd.8

rm /usr/share/man/man*/systemd*

移除 udev_helpers 变量

unset udev_helpers

硬件设备的相关信息被维护在 /etc/udev/hwdb.d 和 /usr/lib/udev/hwdb.d 目录中。Udev 需要将这些信息编译到二进制数据库 /etc/udev/hwdb.bin 中。初始化该数据库

udev-hwdb update

Man-DB

解压Man-DB

cd /sources
tar -xf man-db-2.12.1.tar.xz 
cd man-db-2.12.1

准备编译 Man-DB

./configure --prefix=/usr                         \
            --docdir=/usr/share/doc/man-db-2.12.1 \
            --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=

开始编译,完成后测试编译结果,最后安装软件包

make
make check
make install

Procps-ng

解压Procps-ng

cd /sources
tar -xf procps-ng-4.0.4.tar.xz
cd procps-ng-4.0.4

准备编译 Procps-ng

./configure --prefix=/usr                           \
            --docdir=/usr/share/doc/procps-ng-4.0.4 \
            --disable-static                        \
            --disable-kill

开始编译

make

测试编译结果

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

安装软件包

make install

Util-Linux

解压Util-Linux

cd /sources
rm -rf util-linux-2.40.2
tar -xf util-linux-2.40.2.tar.xz 
cd util-linux-2.40.2

准备编译 Util-linux

./configure --bindir=/usr/bin     \
            --libdir=/usr/lib     \
            --runstatedir=/run    \
            --sbindir=/usr/sbin   \
            --disable-chfn-chsh   \
            --disable-login       \
            --disable-nologin     \
            --disable-su          \
            --disable-setpriv     \
            --disable-runuser     \
            --disable-pylibmount  \
            --disable-liblastlog2 \
            --disable-static      \
            --without-python      \
            --without-systemd     \
            --without-systemdsystemunitdir        \
            ADJTIME_PATH=/var/lib/hwclock/adjtime \
            --docdir=/usr/share/doc/util-linux-2.40.2

开始编译

make

测试编译结果

touch /etc/fstab
chown -R tester .
su tester -c "make -k check"

安装软件包

make install

E2fsprogs

解压E2fsprogs

cd /sources
tar -xf e2fsprogs-1.47.1.tar.gz
cd e2fsprogs-1.47.1

创建一个用于构建的目录

mkdir -v build
cd       build

准备编译 E2fsprogs

../configure --prefix=/usr           \
             --sysconfdir=/etc       \
             --enable-elf-shlibs     \
             --disable-libblkid      \
             --disable-libuuid       \
             --disable-uuidd         \
             --disable-fsck

开始编译,完成后测试编译结果,最后安装软件包

make
make check
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

/etc/mke2fs.conf 包含 mke2fs 一些命令行选项的默认值。您可以修改这些默认值,使之符合您的需求。例如,一些工具 (未被 LFS 或 BLFS 包含) 无法识别启用了 metadata_csum_seed 特性的 ext4 文件系统。如果需要使用这样的工具,可以执行命令,从默认的 ext4 特性列表中移除该特性

sed 's/metadata_csum_seed,//' -i /etc/mke2fs.conf

Sysklogd

解压Sysklogd

cd /sources
tar -xf sysklogd-2.6.1.tar.gz
cd sysklogd-2.6.1

准备编译Sysklogd

./configure --prefix=/usr      \
            --sysconfdir=/etc  \
            --runstatedir=/run \
            --without-logger

开始编译,然后安装软件包

make
make install

创建一个新的 /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 *

# Do not open any internet ports.
secure_mode 2

# End /etc/syslog.conf
EOF

SysVinit

解压SysVinit

cd /sources
tar -xf sysvinit-3.10.tar.xz 
cd sysvinit-3.10

打patch

patch -Np1 -i ../sysvinit-3.10-consolidated-1.patch

开始编译,然后安装软件包

make
make install

软件包基本安装完毕,这里不进行符号移除,有需要可以查看手册8.84. 移除调试符号

现在清除测试时遗留的一些文件

rm -rf /tmp/{*,.*}
find /usr/lib /usr/libexec -name \*.la -delete
find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf
userdel -r tester
本文作者:NakanoMiku
本文链接:http://nakanomiku39.github.io/2024/10/01/%E6%9E%84%E9%80%A0%E5%9F%BA%E4%BA%8Ex86-64%E7%9A%84LFS%EF%BC%883%EF%BC%89/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可