基于LFS11.3从源码构建Linux系统-实践篇

在 Hyper-V 中根据 LFS11.3 从源码构建 Linux 系统。

准备宿主虚拟机

所有的构建将在 Hyper-V 虚拟机中完成。

创建虚拟机

使用Hyper-V新建虚拟机,选择第一代虚拟机,使用16384MB(16G)启动内存,并关闭动态内存,使用默认交换机,创建127GB虚拟硬盘,安装选项使用Rocky8.8镜像文件。

调整虚拟机设置,将虚拟处理器数量设置为8,关闭检查点功能。

安装虚拟机系统(使用Rocky Linux 8),仅使用30GB ext4分区,挂载为根分区,软件选择为Server,关闭Kdump,使用Asia/Shanghai时区,开启网络,使用toor作为root用户密码。

替换为阿里云镜像源、安装缺失的软件包。(使用SSH登录,方便粘贴命令)

1
2
3
4
5
6
7
8
9
10
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak \
/etc/yum.repos.d/Rocky-*.repo
dnf makecache
dnf config-manager --set-enabled devel
dnf groupinstall -y "Development Tools"
dnf install -y python3 texinfo
mv /usr/bin/yacc /usr/bin/yacc.bak
ln -s bison /usr/bin/yacc

配置宿主虚拟机

检查依赖的软件包是否缺失。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
cat > version-check.sh << "EOF"
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH

echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1

if [ -h /usr/bin/yacc ]; then
echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`";
elif [ -x /usr/bin/yacc ]; then
echo yacc is `/usr/bin/yacc --version | head -n1`
else
echo "yacc not found"
fi

echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1

if [ -h /usr/bin/awk ]; then
echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`";
elif [ -x /usr/bin/awk ]; then
echo awk is `/usr/bin/awk --version | head -n1`
else
echo "awk not found"
fi

gcc --version | head -n1
g++ --version | head -n1
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
python3 --version
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1 # texinfo version
xz --version | head -n1

echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
then echo "g++ compilation OK";
else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF

bash version-check.sh

创建分区。

prepare-lfs-partition

准备环境变量、创建文件系统、准备软件包、准备LFS文件系统结构、创建lfs用户。

Note: 需提前将lfs-packages-11.3.tar下载到当前工作目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
export LFS=/mnt/lfs
echo $LFS

mkfs -v -t ext4 /dev/sda2
mkdir -pv $LFS
mount -v -t ext4 /dev/sda2 $LFS
mkdir -v $LFS/sources
chmod -v a+wt $LFS/sources

tar xf lfs-packages-11.3.tar
mv 11.3/* $LFS/sources
pushd $LFS/sources
md5sum -c md5sums
popd
chown root:root $LFS/sources/*

mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}
for i in bin lib sbin; do
ln -sv usr/$i $LFS/$i
done
case $(uname -m) in
x86_64) mkdir -pv $LFS/lib64 ;;
esac
mkdir -pv $LFS/tools

groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
chown -v lfs $LFS/{usr{,/*},lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -v lfs $LFS/lib64 ;;
esac

作为lfs用户登录。

1
su - lfs

配置lfs用户环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
EOF
[ ! -e /etc/bash.bashrc ] || mv -v /etc/bash.bashrc /etc/bash.bashrc.NOUSE
source ~/.bash_profile

构建交叉编译工具链

LFS采用交叉编译的方式防止新系统中的软件被错误地链接到宿主系统上。这里我们首先构建一个交叉编译工具链。这些工具链会放在 $LFS/tools 中临时使用。

构建过程

在交叉编译工具链的构造中,需要完成一些前置条件。如果需要在中断后继续,需要完成这些配置工作。这里MAKEFLAGS环境变量是为了使用多线程来加速构建过程,其中的参数需要根据CPU核心数设置,以充分利用CPU。

1
2
3
4
5
# run as root
export LFS=/mnt/lfs
echo $LFS
mount -v -t ext4 /dev/sda2 $LFS
su - lfs
1
2
3
# run as lfs
export MAKEFLAGS='-j8'
cd $LFS/sources

Binutils-2.40 - 第一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
tar xf binutils-2.40.tar.xz
pushd binutils-2.40
mkdir -v build
cd build
../configure --prefix=$LFS/tools \
--with-sysroot=$LFS \
--target=$LFS_TGT \
--disable-nls \
--enable-gprofng=no \
--disable-werror
make
make install
popd
rm -rf binutils-2.40

GCC-12.2.0 - 第一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
tar xf gcc-12.2.0.tar.xz
pushd gcc-12.2.0
tar -xf ../mpfr-4.2.0.tar.xz
mv -v mpfr-4.2.0 mpfr
tar -xf ../gmp-6.2.1.tar.xz
mv -v gmp-6.2.1 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
../configure \
--target=$LFS_TGT \
--prefix=$LFS/tools \
--with-glibc-version=2.37 \
--with-sysroot=$LFS \
--with-newlib \
--without-headers \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
make
make install
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/install-tools/include/limits.h
popd
rm -rf gcc-12.2.0

Linux-6.1.11 API 头文件

1
2
3
4
5
6
7
8
tar xf linux-6.1.11.tar.xz
pushd linux-6.1.11
make mrproper
make headers
find usr/include -type f ! -name '*.h' -delete
cp -rv usr/include $LFS/usr
popd
rm -rf linux-6.1.11

Glibc-2.37

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
tar xf glibc-2.37.tar.xz
pushd glibc-2.37
case $(uname -m) in
i?86) ln -sfv ld-linux.so.2 $LFS/lib/ld-lsb.so.3
;;
x86_64) ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64
ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64/ld-lsb-x86-64.so.3
;;
esac
patch -Np1 -i ../glibc-2.37-fhs-1.patch
mkdir -v build
cd build
echo "rootsbindir=/usr/sbin" > configparms
../configure \
--prefix=/usr \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=3.2 \
--with-headers=$LFS/usr/include \
libc_cv_slibdir=/usr/lib
make
make DESTDIR=$LFS install
sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd
echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux
rm -v a.out
$LFS/tools/libexec/gcc/$LFS_TGT/12.2.0/install-tools/mkheaders
popd
rm -rf glibc-2.37

GCC-12.2.0 中的 Libstdc++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tar xf gcc-12.2.0.tar.xz
pushd gcc-12.2.0
mkdir -v build
cd build
../libstdc++-v3/configure \
--host=$LFS_TGT \
--build=$(../config.guess) \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/12.2.0
make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/lib{stdc++,stdc++fs,supc++}.la
popd
rm -rf gcc-12.2.0

构建临时工具

这里构建的临时工具将放到最终的安装目录,在正式构建时将会被覆盖。

在宿主虚拟机上构建临时工具

在临时工具的构建中,需要完成一些前置条件。如果需要在中断后继续,需要完成这些配置工作。这里MAKEFLAGS环境变量是为了使用多线程来加速构建过程,其中的参数需要根据CPU核心数设置,以充分利用CPU。

1
2
3
4
5
# run as root
export LFS=/mnt/lfs
echo $LFS
mount -v -t ext4 /dev/sda2 $LFS
su - lfs
1
2
3
# run as lfs
export MAKEFLAGS='-j8'
cd $LFS/sources

M4-1.4.19

1
2
3
4
5
6
7
8
9
tar xf m4-1.4.19.tar.xz
pushd m4-1.4.19
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf m4-1.4.19

Ncurses-6.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
tar xf ncurses-6.4.tar.gz
pushd ncurses-6.4
sed -i s/mawk// configure
mkdir build
pushd build
../configure
make -C include
make -C progs tic
popd
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(./config.guess) \
--mandir=/usr/share/man \
--with-manpage-format=normal \
--with-shared \
--without-normal \
--with-cxx-shared \
--without-debug \
--without-ada \
--disable-stripping \
--enable-widec
make
make DESTDIR=$LFS TIC_PATH=$(pwd)/build/progs/tic install
echo "INPUT(-lncursesw)" > $LFS/usr/lib/libncurses.so
popd
rm -rf ncurses-6.4

Bash-5.2.15

1
2
3
4
5
6
7
8
9
10
11
tar xf bash-5.2.15.tar.gz
pushd bash-5.2.15
./configure --prefix=/usr \
--build=$(sh support/config.guess) \
--host=$LFS_TGT \
--without-bash-malloc
make
make DESTDIR=$LFS install
ln -sv bash $LFS/bin/sh
popd
rm -rf bash-5.2.15

Coreutils-9.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tar xf coreutils-9.1.tar.xz
pushd coreutils-9.1
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess) \
--enable-install-program=hostname \
--enable-no-install-program=kill,uptime
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/chroot $LFS/usr/sbin
mkdir -pv $LFS/usr/share/man/man8
mv -v $LFS/usr/share/man/man1/chroot.1 $LFS/usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' $LFS/usr/share/man/man8/chroot.8
popd
rm -rf coreutils-9.1

Diffutils-3.9

1
2
3
4
5
6
7
tar xf diffutils-3.9.tar.xz
pushd diffutils-3.9
./configure --prefix=/usr --host=$LFS_TGT
make
make DESTDIR=$LFS install
popd
rm -rf diffutils-3.9

File-5.44

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tar xf file-5.44.tar.gz
pushd file-5.44
mkdir build
pushd build
../configure --disable-bzlib \
--disable-libseccomp \
--disable-xzlib \
--disable-zlib
make
popd
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)
make FILE_COMPILE=$(pwd)/build/src/file
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/libmagic.la
popd
rm -rf file-5.44

Findutils-4.9.0

1
2
3
4
5
6
7
8
9
10
tar xf findutils-4.9.0.tar.xz
pushd findutils-4.9.0
./configure --prefix=/usr \
--localstatedir=/var/lib/locate \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf findutils-4.9.0

Gawk-5.2.1

1
2
3
4
5
6
7
8
9
10
tar xf gawk-5.2.1.tar.xz
pushd gawk-5.2.1
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf gawk-5.2.1

Grep-3.8

1
2
3
4
5
6
7
8
tar xf grep-3.8.tar.xz
pushd grep-3.8
./configure --prefix=/usr \
--host=$LFS_TGT
make
make DESTDIR=$LFS install
popd
rm -rf grep-3.8

Gzip-1.12

1
2
3
4
5
6
7
tar xf gzip-1.12.tar.xz
pushd gzip-1.12
./configure --prefix=/usr --host=$LFS_TGT
make
make DESTDIR=$LFS install
popd
rm -rf gzip-1.12

Make-4.4

1
2
3
4
5
6
7
8
9
10
11
12
13
tar xf make-4.4.tar.gz
pushd make-4.4
sed -e '/ifdef SIGPIPE/,+2 d' \
-e '/undef FATAL_SIG/i FATAL_SIG (SIGPIPE);' \
-i src/main.c
./configure --prefix=/usr \
--without-guile \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf make-4.4

Patch-2.7.6

1
2
3
4
5
6
7
8
9
tar xf patch-2.7.6.tar.xz
pushd patch-2.7.6
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf patch-2.7.6

Sed-4.9

1
2
3
4
5
6
7
8
tar xf sed-4.9.tar.xz
pushd sed-4.9
./configure --prefix=/usr \
--host=$LFS_TGT
make
make DESTDIR=$LFS install
popd
rm -rf sed-4.9

Tar-1.34

1
2
3
4
5
6
7
8
9
tar xf tar-1.34.tar.xz
pushd tar-1.34
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
popd
rm -rf tar-1.34

Xz-5.4.1

1
2
3
4
5
6
7
8
9
10
11
12
tar xf xz-5.4.1.tar.xz
pushd xz-5.4.1
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess) \
--disable-static \
--docdir=/usr/share/doc/xz-5.4.1
make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/liblzma.la
popd
rm -rf xz-5.4.1

Binutils-2.40 - 第二遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tar xf binutils-2.40.tar.xz
pushd binutils-2.40
sed '6009s/$add_dir//' -i ltmain.sh
mkdir -v build
cd build
../configure \
--prefix=/usr \
--build=$(../config.guess) \
--host=$LFS_TGT \
--disable-nls \
--enable-shared \
--enable-gprofng=no \
--disable-werror \
--enable-64-bit-bfd
make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes}.{a,la}
popd
rm -rf binutils-2.40

GCC-12.2.0 - 第二遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
tar xf gcc-12.2.0.tar.xz
pushd gcc-12.2.0
tar -xf ../mpfr-4.2.0.tar.xz
mv -v mpfr-4.2.0 mpfr
tar -xf ../gmp-6.2.1.tar.xz
mv -v gmp-6.2.1 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' -i.orig gcc/config/i386/t-linux64
;;
esac
sed '/thread_header =/s/@.*@/gthr-posix.h/' \
-i libgcc/Makefile.in libstdc++-v3/include/Makefile.in
mkdir -v build
cd build
../configure \
--build=$(../config.guess) \
--host=$LFS_TGT \
--target=$LFS_TGT \
LDFLAGS_FOR_TARGET=-L$PWD/$LFS_TGT/libgcc \
--prefix=/usr \
--with-build-sysroot=$LFS \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-multilib \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--enable-languages=c,c++
make
make DESTDIR=$LFS install
ln -sv gcc $LFS/usr/bin/cc
popd
rm -rf gcc-12.2.0

在Chroot环境下继续构建临时工具

前面的临时工具准备完成后,部分工具就可以在脱离宿主系统的环境下进行构建。

准备进入Chroot环境

1
2
3
4
# run as root
export LFS=/mnt/lfs
echo $LFS
mount -v -t ext4 /dev/sda2 $LFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
chown -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -R root:root $LFS/lib64 ;;
esac
mkdir -pv $LFS/{dev,proc,sys,run}
mount -v --bind /dev $LFS/dev
mount -v --bind /dev/pts $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
mkdir -pv $LFS/$(readlink $LFS/dev/shm)
else
mount -t 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 \
/bin/bash --login

进入Chroot环境

在构建时,如果需要中断后继续,需要重新进入Chroot环境,并完成前置的准备条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
mkdir -pv /{boot,home,mnt,opt,srv}
mkdir -pv /etc/{opt,sysconfig}
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{include,src}
mkdir -pv /usr/local/{bin,lib,sbin}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}

ln -sfv /run /var/run
ln -sfv /run/lock /var/lock

install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp

ln -sv /proc/self/mounts /etc/mtab
cat > /etc/hosts << EOF
127.0.0.1 localhost $(hostname)
::1 localhost
EOF
cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF
cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
input:x:24:
mail:x:34:
kvm:x:61:
uuidd:x:80:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF
echo "tester:x:101:101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester
1
exec /usr/bin/bash --login

这里我们重新登录了Chroot环境,需要重新配置构建中使用的环境变量。

1
2
3
4
5
6
export MAKEFLAGS='-j8'
cd /sources
touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp

Gettext-0.21.1

1
2
3
4
5
6
7
tar xf gettext-0.21.1.tar.xz
pushd gettext-0.21.1
./configure --disable-shared
make
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin
popd
rm -rf gettext-0.21.1

Bison-3.8.2

1
2
3
4
5
6
7
8
tar xf bison-3.8.2.tar.xz
pushd bison-3.8.2
./configure --prefix=/usr \
--docdir=/usr/share/doc/bison-3.8.2
make
make install
popd
rm -rf bison-3.8.2

Perl-5.36.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tar xf perl-5.36.0.tar.xz
pushd perl-5.36.0
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
make
make install
popd
rm -rf perl-5.36.0

Python-3.11.2

1
2
3
4
5
6
7
8
9
tar xf Python-3.11.2.tar.xz
pushd Python-3.11.2
./configure --prefix=/usr \
--enable-shared \
--without-ensurepip
make
make install
popd
rm -rf Python-3.11.2

Texinfo-7.0.2

1
2
3
4
5
6
7
tar xf texinfo-7.0.2.tar.xz
pushd texinfo-7.0.2
./configure --prefix=/usr
make
make install
popd
rm -rf texinfo-7.0.2

Util-linux-2.38.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tar xf util-linux-2.38.1.tar.xz
pushd util-linux-2.38.1
mkdir -pv /var/lib/hwclock
./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
--libdir=/usr/lib \
--docdir=/usr/share/doc/util-linux-2.38.1 \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--without-python \
runstatedir=/run
make
make install
popd
rm -rf util-linux-2.38.1

清理和备份临时系统

1
2
3
4
rm -rf /usr/share/{info,man,doc}/*
find /usr/{lib,libexec} -name \*.la -delete
rm -rf /tools
exit
1
2
3
4
5
mountpoint -q $LFS/dev/shm && umount $LFS/dev/shm
umount $LFS/dev/pts
umount $LFS/{sys,proc,run,dev}
cd $LFS
tar -cJpf $HOME/lfs-temp-tools-11.3.tar.xz .

构建目标系统

由于备份系统时离开了Chroot环境,我们需要重新进入Chroot环境并进行配置环境。

1
2
3
4
# run as root
export LFS=/mnt/lfs
echo $LFS
mount -v -t ext4 /dev/sda2 $LFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# run as lfs
mount -v --bind /dev $LFS/dev
mount -v --bind /dev/pts $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
mkdir -pv $LFS/$(readlink $LFS/dev/shm)
else
mount -t 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 \
/bin/bash --login
1
2
export MAKEFLAGS='-j8'
cd /sources

构建软件包

Man-pages-6.03

1
2
3
4
5
tar xf man-pages-6.03.tar.xz
pushd man-pages-6.03
make prefix=/usr install
popd
rm -rf man-pages-6.03

Iana-Etc-20230202

1
2
3
4
5
tar xf iana-etc-20230202.tar.gz
pushd iana-etc-20230202
cp services protocols /etc
popd
rm -rf iana-etc-20230202

Glibc-2.37

Note: 测试至关重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
tar xf glibc-2.37.tar.xz
pushd glibc-2.37
patch -Np1 -i ../glibc-2.37-fhs-1.patch
sed '/width -=/s/workend - string/number_length/' \
-i stdio-common/vfprintf-process-arg.c
mkdir -v build
cd build
echo "rootsbindir=/usr/sbin" > configparms
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=3.2 \
--enable-stack-protector=strong \
--with-headers=/usr/include \
libc_cv_slibdir=/usr/lib
make
make check
touch /etc/ld.so.conf
sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile
make install
sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/ldd
cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd
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
make localedata/install-locales
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

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

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
ln -sfv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

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

EOF
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
popd
rm -rf glibc-2.37

Zlib-1.2.13

1
2
3
4
5
6
7
8
9
tar xf zlib-1.2.13.tar.xz
pushd zlib-1.2.13
./configure --prefix=/usr
make
make check
make install
rm -fv /usr/lib/libz.a
popd
rm -rf zlib-1.2.13

Bzip2-1.0.8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tar xf bzip2-1.0.8.tar.gz
pushd 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
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
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
popd
rm -rf bzip2-1.0.8

Xz-5.4.1

1
2
3
4
5
6
7
8
9
10
tar xf xz-5.4.1.tar.xz
pushd xz-5.4.1
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/xz-5.4.1
make
make check
make install
popd
rm -rf xz-5.4.1

Zstd-1.5.4

1
2
3
4
5
6
7
8
tar xf zstd-1.5.4.tar.gz
pushd zstd-1.5.4
make prefix=/usr
make check
make prefix=/usr install
rm -v /usr/lib/libzstd.a
popd
rm -rf zstd-1.5.4

File-5.44

1
2
3
4
5
6
7
8
tar xf file-5.44.tar.gz
pushd file-5.44
./configure --prefix=/usr
make
make check
make install
popd
rm -rf file-5.44

Readline-8.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
tar xf readline-8.2.tar.gz
pushd readline-8.2
sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install
patch -Np1 -i ../readline-8.2-upstream_fix-1.patch
./configure --prefix=/usr \
--disable-static \
--with-curses \
--docdir=/usr/share/doc/readline-8.2
make SHLIB_LIBS="-lncursesw"
make SHLIB_LIBS="-lncursesw" install
install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-8.2
popd
rm -rf readline-8.2

M4-1.4.19

1
2
3
4
5
6
7
8
tar xf m4-1.4.19.tar.xz
pushd m4-1.4.19
./configure --prefix=/usr
make
make check
make install
popd
rm -rf m4-1.4.19

Bc-6.2.4

1
2
3
4
5
6
7
8
tar xf bc-6.2.4.tar.xz
pushd bc-6.2.4
CC=gcc ./configure --prefix=/usr -G -O3 -r
make
make test
make install
popd
rm -rf bc-6.2.4

Flex-2.6.4

1
2
3
4
5
6
7
8
9
10
11
tar xf flex-2.6.4.tar.gz
pushd flex-2.6.4
./configure --prefix=/usr \
--docdir=/usr/share/doc/flex-2.6.4 \
--disable-static
make
make check
make install
ln -sv flex /usr/bin/lex
popd
rm -rf flex-2.6.4

Tcl-8.6.13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
tar xf tcl8.6.13-src.tar.gz
pushd tcl8.6.13
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 test
make install
chmod -v u+w /usr/lib/libtcl8.6.so
make install-private-headers
ln -sfv tclsh8.6 /usr/bin/tclsh
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
popd
rm -rf tcl8.6.13

Expect-5.45.4

1
2
3
4
5
6
7
8
9
10
11
12
13
tar xf expect5.45.4.tar.gz
pushd expect5.45.4
./configure --prefix=/usr \
--with-tcl=/usr/lib \
--enable-shared \
--mandir=/usr/share/man \
--with-tclinclude=/usr/include
make
make test
make install
ln -svf expect5.45.4/libexpect5.45.4.so /usr/lib
popd
rm -rf expect5.45.4

DejaGNU-1.6.3

1
2
3
4
5
6
7
8
9
10
11
12
13
tar xf dejagnu-1.6.3.tar.gz
pushd dejagnu-1.6.3
mkdir -v build
cd build
../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
popd
rm -rf dejagnu-1.6.3

Binutils-2.40

Note: 测试至关重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
tar xf binutils-2.40.tar.xz
pushd binutils-2.40
expect -c "spawn ls"
mkdir -v build
cd build
../configure --prefix=/usr \
--sysconfdir=/etc \
--enable-gold \
--enable-ld=default \
--enable-plugins \
--enable-shared \
--disable-werror \
--enable-64-bit-bfd \
--with-system-zlib
make tooldir=/usr
make -k check
grep '^FAIL:' $(find -name '*.log')
make tooldir=/usr install
rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,sframe,opcodes}.a
rm -fv /usr/share/man/man1/{gprofng,gp-*}.1
popd
rm -rf binutils-2.40

GMP-6.2.1

Note: 测试至关重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
tar xf gmp-6.2.1.tar.xz
pushd gmp-6.2.1
./configure --prefix=/usr \
--enable-cxx \
--disable-static \
--docdir=/usr/share/doc/gmp-6.2.1
make
make html
make check 2>&1 | tee gmp-check-log
awk '/# PASS:/{total+=$3} ; END{print total}' gmp-check-log
make install
make install-html
popd
rm -rf gmp-6.2.1

MPFR-4.2.0

Note: 测试至关重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tar xf mpfr-4.2.0.tar.xz
pushd mpfr-4.2.0
sed -e 's/+01,234,567/+1,234,567 /' \
-e 's/13.10Pd/13Pd/' \
-i tests/tsprintf.c
./configure --prefix=/usr \
--disable-static \
--enable-thread-safe \
--docdir=/usr/share/doc/mpfr-4.2.0
make
make html
make check
make install
make install-html
popd
rm -rf mpfr-4.2.0

MPC-1.3.1

1
2
3
4
5
6
7
8
9
10
11
12
tar xf mpc-1.3.1.tar.gz
pushd mpc-1.3.1
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/mpc-1.3.1
make
make html
make check
make install
make install-html
popd
rm -rf mpc-1.3.1

Attr-2.5.1

1
2
3
4
5
6
7
8
9
10
11
tar xf attr-2.5.1.tar.gz
pushd attr-2.5.1
./configure --prefix=/usr \
--disable-static \
--sysconfdir=/etc \
--docdir=/usr/share/doc/attr-2.5.1
make
make check
make install
popd
rm -rf attr-2.5.1

Acl-2.3.1

1
2
3
4
5
6
7
8
9
tar xf acl-2.3.1.tar.xz
pushd acl-2.3.1
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/acl-2.3.1
make
make install
popd
rm -rf acl-2.3.1

Libcap-2.67

1
2
3
4
5
6
7
8
tar xf libcap-2.67.tar.xz
pushd libcap-2.67
sed -i '/install -m.*STA/d' libcap/Makefile
make prefix=/usr lib=lib
make test
make prefix=/usr lib=lib install
popd
rm -rf libcap-2.67

Shadow-4.13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
tar xf shadow-4.13.tar.xz
pushd shadow-4.13
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 / /' {} \;
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
touch /usr/bin/passwd
./configure --sysconfdir=/etc \
--disable-static \
--with-group-name-max-length=32
make
make exec_prefix=/usr install
make -C man install-man

pwconv
grpconv
mkdir -p /etc/default
useradd -D --gid 999
sed -i '/MAIL/s/yes/no/' /etc/default/useradd
popd
rm -rf shadow-4.13
1
passwd root

GCC-12.2.0

Note: 测试至关重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
tar xf gcc-12.2.0.tar.xz
pushd gcc-12.2.0
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
../configure --prefix=/usr \
LD=ld \
--enable-languages=c,c++ \
--enable-default-pie \
--enable-default-ssp \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib
make
ulimit -s 32768
chown -Rv tester .
su tester -c "PATH=$PATH make -k check"
../contrib/test_summary
make install
chown -v -R root:root \
/usr/lib/gcc/$(gcc -dumpmachine)/12.2.0/include{,-fixed}
ln -svr /usr/bin/cpp /usr/lib
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'
grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
rep -B4 '^ /usr/include' dummy.log
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
grep "/lib.*/libc.so.6 " dummy.log
grep found dummy.log
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
popd
rm -rf gcc-12.2.0

Pkg-config-0.29.2

1
2
3
4
5
6
7
8
9
10
11
tar xf pkg-config-0.29.2.tar.gz
pushd pkg-config-0.29.2
./configure --prefix=/usr \
--with-internal-glib \
--disable-host-tool \
--docdir=/usr/share/doc/pkg-config-0.29.2
make
make check
make install
popd
rm -rf pkg-config-0.29.2

Ncurses-6.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
tar xf ncurses-6.4.tar.gz
pushd ncurses-6.4
./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
make
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/* /
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
rm -vf /usr/lib/libcursesw.so
echo "INPUT(-lncursesw)" > /usr/lib/libcursesw.so
ln -sfv libncurses.so /usr/lib/libcurses.so
mkdir -pv /usr/share/doc/ncurses-6.4
cp -v -R doc/* /usr/share/doc/ncurses-6.4
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
popd
rm -rf ncurses-6.4

Sed-4.9

1
2
3
4
5
6
7
8
9
10
11
12
tar xf sed-4.9.tar.xz
pushd sed-4.9
./configure --prefix=/usr
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
popd
rm -rf sed-4.9

Psmisc-23.6

1
2
3
4
5
6
7
tar xf psmisc-23.6.tar.xz
pushd psmisc-23.6
./configure --prefix=/usr
make
make install
popd
rm -rf psmisc-23.6

Gettext-0.21.1

1
2
3
4
5
6
7
8
9
10
11
tar xf gettext-0.21.1.tar.xz
pushd gettext-0.21.1
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-0.21.1
make
make check
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so
popd
rm -rf gettext-0.21.1

Bison-3.8.2

1
2
3
4
5
6
7
8
tar xf bison-3.8.2.tar.xz
pushd bison-3.8.2
./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.8.2
make
make check
make install
popd
rm -rf bison-3.8.2

Grep-3.8

1
2
3
4
5
6
7
8
9
tar xf grep-3.8.tar.xz
pushd grep-3.8
sed -i "s/echo/#echo/" src/egrep.sh
./configure --prefix=/usr
make
make check
make install
popd
rm -rf grep-3.8

Bash-5.2.15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
tar xf bash-5.2.15.tar.gz
pushd bash-5.2.15
./configure --prefix=/usr \
--without-bash-malloc \
--with-installed-readline \
--docdir=/usr/share/doc/bash-5.2.15
make
chown -Rv tester .

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

make install

popd
rm -rf bash-5.2.15
1
exec /usr/bin/bash --login

Libtool-2.4.7

1
2
3
4
5
6
7
8
9
tar xf libtool-2.4.7.tar.xz
pushd libtool-2.4.7
./configure --prefix=/usr
make
make -k check TESTSUITEFLAGS=-j8
make install
rm -fv /usr/lib/libltdl.a
popd
rm -rf libtool-2.4.7

GDBM-1.23

1
2
3
4
5
6
7
8
9
10
tar xf gdbm-1.23.tar.gz
pushd gdbm-1.23
./configure --prefix=/usr \
--disable-static \
--enable-libgdbm-compat
make
make check
make install
popd
rm -rf gdbm-1.23

Gperf-3.1

1
2
3
4
5
6
7
8
tar xf gperf-3.1.tar.gz
pushd gperf-3.1
./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1
make
make -j1 check
make install
popd
rm -rf gperf-3.1

Expat-2.5.0

1
2
3
4
5
6
7
8
9
10
11
tar xf expat-2.5.0.tar.xz
pushd expat-2.5.0
./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
popd
rm -rf expat-2.5.0

Inetutils-2.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tar xf inetutils-2.4.tar.xz
pushd inetutils-2.4
./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
popd
rm -rf inetutils-2.4

Less-608

1
2
3
4
5
6
7
tar xf less-608.tar.gz
pushd less-608
./configure --prefix=/usr --sysconfdir=/etc
make
make install
popd
rm -rf less-608

Perl-5.36.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
tar xf perl-5.36.0.tar.xz
pushd perl-5.36.0
export BUILD_ZLIB=False
export BUILD_BZIP2=0
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
make
make test
make install
unset BUILD_ZLIB BUILD_BZIP2
popd
rm -rf perl-5.36.0

XML::Parser-2.46

1
2
3
4
5
6
7
8
tar xf XML-Parser-2.46.tar.gz
pushd XML-Parser-2.46
perl Makefile.PL
make
make test
make install
popd
rm -rf XML-Parser-2.46

Intltool-0.51.0

1
2
3
4
5
6
7
8
9
10
tar xf intltool-0.51.0.tar.gz
pushd intltool-0.51.0
sed -i 's:\\\${:\\\$\\{:' intltool-update.in
./configure --prefix=/usr
make
make check
make install
install -v -Dm644 doc/I18N-HOWTO /usr/share/doc/intltool-0.51.0/I18N-HOWTO
popd
rm -rf intltool-0.51.0

Autoconf-2.71

1
2
3
4
5
6
7
8
9
10
11
tar xf autoconf-2.71.tar.xz
pushd autoconf-2.71
sed -e 's/SECONDS|/&SHLVL|/' \
-e '/BASH_ARGV=/a\ /^SHLVL=/ d' \
-i.orig tests/local.at
./configure --prefix=/usr
make
make check TESTSUITEFLAGS=-j8
make install
popd
rm -rf autoconf-2.71

Automake-1.16.5

1
2
3
4
5
6
7
8
tar xf automake-1.16.5.tar.xz
pushd automake-1.16.5
./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.16.5
make
make -j4 check
make install
popd
rm -rf automake-1.16.5

OpenSSL-3.0.8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tar xf openssl-3.0.8.tar.gz
pushd openssl-3.0.8
./config --prefix=/usr \
--openssldir=/etc/ssl \
--libdir=lib \
shared \
zlib-dynamic
make
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.0.8
cp -vfr doc/* /usr/share/doc/openssl-3.0.8
popd
rm -rf openssl-3.0.8

Kmod-30

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tar xf kmod-30.tar.xz
pushd kmod-30
./configure --prefix=/usr \
--sysconfdir=/etc \
--with-openssl \
--with-xz \
--with-zstd \
--with-zlib
make
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
popd
rm -rf kmod-30

Elfutils-0.188 中的 Libelf

1
2
3
4
5
6
7
8
9
10
11
12
tar xf elfutils-0.188.tar.bz2
pushd elfutils-0.188
./configure --prefix=/usr \
--disable-debuginfod \
--enable-libdebuginfod=dummy
make
make check
make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
rm /usr/lib/libelf.a
popd
rm -rf elfutils-0.188

Libffi-3.4.4

1
2
3
4
5
6
7
8
9
10
tar xf libffi-3.4.4.tar.gz
pushd libffi-3.4.4
./configure --prefix=/usr \
--disable-static \
--with-gcc-arch=native
make
make check
make install
popd
rm -rf libffi-3.4.4

Python-3.11.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
tar xf Python-3.11.2.tar.xz
pushd Python-3.11.2
./configure --prefix=/usr \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--enable-optimizations
make
make install

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

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

popd
rm -rf Python-3.11.2

Wheel-0.38.4

1
2
3
4
5
6
tar xf wheel-0.38.4.tar.gz
pushd wheel-0.38.4
PYTHONPATH=src pip3 wheel -w dist --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links=dist wheel
popd
rm -rf wheel-0.38.4

Ninja-1.11.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tar xf ninja-1.11.1.tar.gz
pushd ninja-1.11.1

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
python3 configure.py --bootstrap
./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
popd
rm -rf ninja-1.11.1

Meson-1.0.0

1
2
3
4
5
6
7
8
tar xf meson-1.0.0.tar.gz
pushd meson-1.0.0
pip3 wheel -w dist --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
popd
rm -rf meson-1.0.0

Coreutils-9.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tar xf coreutils-9.1.tar.xz
pushd coreutils-9.1
patch -Np1 -i ../coreutils-9.1-i18n-1.patch
autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix=/usr \
--enable-no-install-program=kill,uptime
make
make NON_ROOT_USERNAME=tester check-root
echo "dummy:x:102:tester" >> /etc/group
chown -Rv tester .
su tester -c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"
sed -i '/dummy/d' /etc/group
make install
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
popd
rm -rf coreutils-9.1

Check-0.15.2

1
2
3
4
5
6
7
8
tar xf check-0.15.2.tar.gz
pushd check-0.15.2
./configure --prefix=/usr --disable-static
make
make check
make docdir=/usr/share/doc/check-0.15.2 install
popd
rm -rf check-0.15.2

Diffutils-3.9

1
2
3
4
5
6
7
8
tar xf diffutils-3.9.tar.xz
pushd diffutils-3.9
./configure --prefix=/usr
make
make check
make install
popd
rm -rf diffutils-3.9

Gawk-5.2.1

1
2
3
4
5
6
7
8
9
10
11
tar xf gawk-5.2.1.tar.xz
pushd gawk-5.2.1
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr
make
make check
make LN='ln -f' install
mkdir -pv /usr/share/doc/gawk-5.2.1
cp -v doc/{awkforai.txt,*.{eps,pdf,jpg}} /usr/share/doc/gawk-5.2.1
popd
rm -rf gawk-5.2.1

Findutils-4.9.0

1
2
3
4
5
6
7
8
9
10
11
12
tar xf findutils-4.9.0.tar.xz
pushd findutils-4.9.0
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
make
chown -Rv tester .
su tester -c "PATH=$PATH make check"
make install
popd
rm -rf findutils-4.9.0

Groff-1.22.4

1
2
3
4
5
6
7
tar xf groff-1.22.4.tar.gz
pushd groff-1.22.4
PAGE=A4 ./configure --prefix=/usr
make
make install
popd
rm -rf groff-1.22.4

GRUB-2.06

1
2
3
4
5
6
7
8
9
10
11
12
13
tar xf grub-2.06.tar.xz
pushd grub-2.06
unset {C,CPP,CXX,LD}FLAGS
patch -Np1 -i ../grub-2.06-upstream_fixes-1.patch
./configure --prefix=/usr \
--sysconfdir=/etc \
--disable-efiemu \
--disable-werror
make
make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions
popd
rm -rf grub-2.06

Gzip-1.12

1
2
3
4
5
6
7
8
tar xf gzip-1.12.tar.xz
pushd gzip-1.12
./configure --prefix=/usr
make
make check
make install
popd
rm -rf gzip-1.12

IPRoute2-6.1.0

1
2
3
4
5
6
7
8
9
10
tar xf iproute2-6.1.0.tar.xz
pushd iproute2-6.1.0
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
popd
rm -rf iproute2-6.1.0

Kbd-2.5.1

1
2
3
4
5
6
7
8
9
10
11
12
13
tar xf kbd-2.5.1.tar.xz
pushd kbd-2.5.1
patch -Np1 -i ../kbd-2.5.1-backspace-1.patch
sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in
./configure --prefix=/usr --disable-vlock
make
make check
make install
mkdir -pv /usr/share/doc/kbd-2.5.1
cp -R -v docs/doc/* /usr/share/doc/kbd-2.5.1
popd
rm -rf kbd-2.5.1

Libpipeline-1.5.7

1
2
3
4
5
6
7
8
tar xf libpipeline-1.5.7.tar.gz
pushd libpipeline-1.5.7
./configure --prefix=/usr
make
make check
make install
popd
rm -rf libpipeline-1.5.7

Make-4.4

1
2
3
4
5
6
7
8
9
10
11
tar xf make-4.4.tar.gz
pushd make-4.4
sed -e '/ifdef SIGPIPE/,+2 d' \
-e '/undef FATAL_SIG/i FATAL_SIG (SIGPIPE);' \
-i src/main.c
./configure --prefix=/usr
make
make check
make install
popd
rm -rf make-4.4

Patch-2.7.6

1
2
3
4
5
6
7
8
tar xf patch-2.7.6.tar.xz
pushd patch-2.7.6
./configure --prefix=/usr
make
make check
make install
popd
rm -rf patch-2.7.6

Tar-1.34

1
2
3
4
5
6
7
8
9
10
tar xf tar-1.34.tar.xz
pushd tar-1.34
FORCE_UNSAFE_CONFIGURE=1 \
./configure --prefix=/usr
make
make check
make install
make -C doc install-html docdir=/usr/share/doc/tar-1.34
popd
rm -rf tar-1.34

Texinfo-7.0.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tar xf texinfo-7.0.2.tar.xz
pushd texinfo-7.0.2
./configure --prefix=/usr
make
make check
make install
make TEXMF=/usr/share/texmf install-tex
pushd /usr/share/info
rm -v dir
for f in *
do install-info $f dir 2>/dev/null
done
popd
popd
rm -rf texinfo-7.0.2

Vim-9.0.1273

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
tar xf vim-9.0.1273.tar.xz
pushd vim-9.0.1273
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
./configure --prefix=/usr
make
chown -Rv tester .
su tester -c "LANG=en_US.UTF-8 make -j1 test" &> vim-test.log
make install
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
ln -sv ../vim/vim90/doc /usr/share/doc/vim-9.0.1273
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
popd
rm -rf vim-9.0.1273

Eudev-3.2.11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tar xf eudev-3.2.11.tar.gz
pushd eudev-3.2.11
sed -i '/udevdir/a udev_dir=${udevdir}' src/udev/udev.pc.in
./configure --prefix=/usr \
--bindir=/usr/sbin \
--sysconfdir=/etc \
--enable-manpages \
--disable-static
make
mkdir -pv /usr/lib/udev/rules.d
mkdir -pv /etc/udev/rules.d
make check
make install
tar -xvf ../udev-lfs-20171102.tar.xz
make -f udev-lfs-20171102/Makefile.lfs install
udevadm hwdb --update
popd
rm -rf eudev-3.2.11

Man-DB-2.11.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tar xf man-db-2.11.2.tar.xz
pushd man-db-2.11.2
./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=
make
make check
make install
popd
rm -rf man-db-2.11.2

Procps-ng-4.0.2

1
2
3
4
5
6
7
8
9
10
11
tar xf procps-ng-4.0.2.tar.xz
pushd procps-ng-4.0.2
./configure --prefix=/usr \
--docdir=/usr/share/doc/procps-ng-4.0.2 \
--disable-static \
--disable-kill
make
make check
make install
popd
rm -rf procps-ng-4.0.2

Util-linux-2.38.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
tar xf util-linux-2.38.1.tar.xz
pushd util-linux-2.38.1
./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
make
chown -Rv tester .
su tester -c "make -k check"
make install
popd
rm -rf util-linux-2.38.1

E2fsprogs-1.47.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
tar xf e2fsprogs-1.47.0.tar.gz
pushd e2fsprogs-1.47.0
mkdir -v build
cd build
../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
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
sed 's/metadata_csum_seed,//' -i /etc/mke2fs.conf
popd
rm -rf e2fsprogs-1.47.0

Sysklogd-1.5.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
tar xf sysklogd-1.5.1.tar.gz
pushd sysklogd-1.5.1
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

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

popd
rm -rf sysklogd-1.5.1

Sysvinit-3.06

1
2
3
4
5
6
7
tar xf sysvinit-3.06.tar.xz
pushd sysvinit-3.06
patch -Np1 -i ../sysvinit-3.06-consolidated-1.patch
make
make install
popd
rm -rf sysvinit-3.06

清理系统

1
2
3
4
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

配置系统

这里我们完成了大部分软件包的安装,下面将系统进行一些配置后即可作为新的系统启动。

脚本配置

LFS-Bootscripts-20230101

1
2
3
4
5
tar xf lfs-bootscripts-20230101.tar.xz
pushd lfs-bootscripts-20230101
make install
popd
rm -rf lfs-bootscripts-20230101

设备管理脚本

1
2
bash /usr/lib/udev/init-net-rules.sh
# cat /etc/udev/rules.d/70-persistent-net.rules

网络配置脚本

Note: 这里的本地IP、网关IP、子网掩码、广播IP、本地域、DNS服务器等需要按本地情况进行调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
cd /etc/sysconfig/
cat > ifconfig.eth0 << "EOF"
ONBOOT=yes
IFACE=eth0
SERVICE=ipv4-static
IP=172.27.51.43
GATEWAY=172.27.48.1
PREFIX=20
BROADCAST=172.27.63.255
EOF

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

domain mshome.net
nameserver 172.27.48.1

# End /etc/resolv.conf
EOF

echo "lfs" > /etc/hostname

cat > /etc/hosts << "EOF"
# Begin /etc/hosts

127.0.0.1 localhost.localdomain localhost
127.0.1.1 lfs.mshome.net lfs
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# End /etc/hosts
EOF

System V 引导脚本使用与配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cat > /etc/inittab << "EOF"
# Begin /etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc S

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S06:once:/sbin/sulogin
s1:1:respawn:/sbin/sulogin

1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600

# End /etc/inittab
EOF

cat > /etc/sysconfig/clock << "EOF"
# Begin /etc/sysconfig/clock

UTC=1

# Set this to any options you might need to give to hwclock,
# such as machine hardware clock type for Alphas.
CLOCKPARAMS=

# End /etc/sysconfig/clock
EOF

Bash Shell 启动文件

1
2
3
4
5
6
7
cat > /etc/profile << "EOF"
# Begin /etc/profile

export LANG=en_US.utf8

# End /etc/profile
EOF

创建 /etc/inputrc 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <[email protected]>

# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off

# Enable 8-bit input
set meta-flag On
set input-meta On

# Turns off 8th bit stripping
set convert-meta Off

# Keep the 8th bit for display
set output-meta On

# none, visible or audible
set bell-style none

# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word

# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert

# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line

# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line

# End /etc/inputrc
EOF

创建 /etc/shells 文件

1
2
3
4
5
6
7
8
cat > /etc/shells << "EOF"
# Begin /etc/shells

/bin/sh
/bin/bash

# End /etc/shells
EOF

引导系统

创建 /etc/fstab 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > /etc/fstab << "EOF"
# Begin /etc/fstab

# file system mount-point type options dump fsck
# order

/dev/sda2 / ext4 defaults 1 1
# /dev/<yyy> swap swap pri=1 0 0
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs defaults 0 0
devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
tmpfs /dev/shm tmpfs nosuid,nodev 0 0

# End /etc/fstab
EOF

构建 Linux Kernel

1
2
3
4
5
6
cd /sources
tar xf linux-6.1.11.tar.xz
pushd linux-6.1.11
make mrproper
make defconfig
make menuconfig

按下面代码块中配置项修改内核配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Processor type and features --->
[*] Build a relocatable kernel [CONFIG_RELOCATABLE]
[*] Randomize the address of the kernel image (KASLR) [CONFIG_RANDOMIZE_BASE]
General setup --->
[ ] Compile the kernel with warnings as errors [CONFIG_WERROR]
< > Enable kernel headers through /sys/kernel/kheaders.tar.xz [CONFIG_IKHEADERS]
General architecture-dependent options --->
[*] Stack Protector buffer overflow detection [CONFIG_STACKPROTECTOR]
[*] Strong Stack Protector [CONFIG_STACKPROTECTOR_STRONG]
Device Drivers --->
Graphics support --->
Frame buffer Devices --->
<*> Support for frame buffer devices --->
Console display driver support --->
[*] Framebuffer Console support [CONFIG_FRAMEBUFFER_CONSOLE]
Generic Driver Options --->
[ ] Support for uevent helper [CONFIG_UEVENT_HELPER]
[*] Maintain a devtmpfs filesystem to mount at /dev [CONFIG_DEVTMPFS]
[*] Automount devtmpfs at /dev, after the kernel mounted the rootfs [CONFIG_DEVTMPFS_MOUNT]
1
2
3
4
5
6
7
Processor type and features --->
[*] Support x2apic [CONFIG_X86_X2APIC]
Device Drivers --->
[*] PCI Support ---> [CONFIG_PCI]
[*] Message Signaled Interrupts (MSI and MSI-X) [CONFIG_PCI_MSI]
[*] IOMMU Hardware Support ---> [CONFIG_IOMMU_SUPPORT]
[*] Support for Interrupt Remapping [CONFIG_IRQ_REMAP]

由于我们在 Hyper-V 中进行构建,完成后的系统也将在 Hyper-V 中运行,我们需要调整 Kernel 配置选项,将所需驱动编译到内核中。

这里,我们按下面的代码块将 Hyper-V 使用的网卡驱动编译到内核。

1
2
3
4
5
Device Drivers --->
Microsoft Hyper-V guest support --->
<*> Microsoft Hyper-V client drivers [HYPERV]
[*] Network device support --->
<*> Microsoft Hyper-V virtual network driver [HYPERV_NET]

配置完成后我们可以继续 Kernel 的构建过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    make
make modules_install
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-6.1.11-lfs-11.3
cp -iv System.map /boot/System.map-6.1.11
cp -iv .config /boot/config-6.1.11
install -d /usr/share/doc/linux-6.1.11
cp -r Documentation/* /usr/share/doc/linux-6.1.11
chown -R 0:0 .

install -v -m755 -d /etc/modprobe.d
cat > /etc/modprobe.d/usb.conf << "EOF"
# Begin /etc/modprobe.d/usb.conf

install ohci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i ohci_hcd ; true
install uhci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i uhci_hcd ; true

# End /etc/modprobe.d/usb.conf
EOF

popd

可以看到,这里我们没有删除linux构建目录。这是因为某些软件包的安装需要重新构建linux,我们将其保留以便后续使用。

GRUB配置

1
2
3
4
5
6
7
8
9
10
11
12
13
grub-install /dev/sda
cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5

insmod ext2
set root=(hd0,2)

menuentry "GNU/Linux, Linux 6.1.11-lfs-11.3" {
linux /boot/vmlinuz-6.1.11-lfs-11.3 root=/dev/sda2 ro net.ifnames=0
}
EOF

配置os-release

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
echo 11.3 > /etc/lfs-release

cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="11.3"
DISTRIB_CODENAME="lfs"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF

cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="11.3"
ID=lfs
PRETTY_NAME="Linux From Scratch 11.3"
VERSION_CODENAME="lfs"
EOF

重启系统

1
logout
1
2
3
4
5
6
7
8
9
10
11
12
13
umount -v $LFS/dev/pts
mountpoint -q $LFS/dev/shm && umount $LFS/dev/shm
umount -v $LFS/dev
umount -v $LFS/run
umount -v $LFS/proc
umount -v $LFS/sys

umount -v $LFS/home
umount -v $LFS

umount -v $LFS

reboot

完成结果

完成后登录系统结果如图。

final-result

参考资料