Milestone 4 (Chapters 8, 9 and 10)

Chapter 8 Installing Basic System Software

8.3. Man-pages-5.13

Install Man-pages by running:

make prefix=/usr install

8.4. Iana-Etc-20220812

For this package, we only need to copy the files into place:

cp services protocols /etc

8.5. Glibc-2.36

Some of the Glibc programs use the non-FHS compliant /var/db directory to store their runtime data. Apply the following patch to make such programs store their runtime data in the FHS-compliant locations:

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

The Glibc documentation recommends building Glibc in a dedicated build directory:

mkdir -v build
cd       build

Ensure that the ldconfig and sln utilities will be installed into /usr/sbin:

echo "rootsbindir=/usr/sbin" > configparms

Prepare Glibc for compilation:

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

Compile the package:

make

Generally a few tests do not pass. The test failures listed below are usually safe to ignore.

make check

Though it is a harmless message, the install stage of Glibc will complain about the absence of /etc/ld.so.conf. Prevent this warning with:

touch /etc/ld.so.conf

Fix the Makefile to skip an unneeded sanity check that fails in the LFS partial environment:

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

Install the package:

make install

Fix hard coded path to the executable loader in ldd script:

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

Install the configuration file and runtime directory for nscd:

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

Individual locales can be installed using the localedef program. E.g., the second localedef command below combines the /usr/share/i18n/locales/cs_CZ charset-independent locale definition with the /usr/share/i18n/charmaps/UTF-8.gz charmap definition and appends the result to the /usr/lib/locale/locale-archive file. The following instructions will install the minimum set of locales necessary for the optimal coverage of tests:

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

Alternatively, install all locales listed in the glibc-2.36/localedata/SUPPORTED file (it includes every locale listed above and many more) at once with the following time-consuming command:

make localedata/install-locales

Then use the localedef command to create and install locales not listed in the glibc-2.36/localedata/SUPPORTED file when you need them. For instance, the following two locales are needed for some tests later in this chapter:

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

8.5.2. Configuring Glibc

Create a new file /etc/nsswitch.conf by running the following:

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

Install and set up the time zone data with the following:

tar -xf ../../tzdata2022c.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

Had an error here and had to make /dev/null not a file

mknod /dev/newnull c 1 3
chmod 777 /dev/newnull
mv -f /dev/newnull /dev/null

Then create the /etc/localtime file by running:

ln -sfv /usr/share/zoneinfo/America/New_York /etc/localtime

Create a new file /etc/ld.so.conf by running the following:

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

If desired, the dynamic loader can also search a directory and include the contents of files found there. Generally the files in this include directory are one line specifying the desired library path. To add this capability run the following commands:

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

8.6. Zlib-1.2.12

Prepare Zlib for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

Remove a useless static library:

rm -fv /usr/lib/libz.a

8.7. Bzip2-1.0.8

Apply a patch that will install the documentation for this package:

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

The following command ensures installation of symbolic links are relative:

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

Ensure the man pages are installed into the correct location:

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

Prepare Bzip2 for compilation with:

make -f Makefile-libbz2_so
make clean

8.8. Xz-5.2.6

Prepare Xz for compilation with:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.9. Zstd-1.5.2

Apply a patch to fix some issues identified by upstream:

patch -Np1 -i ../zstd-1.5.2-upstream_fixes-1.patch

Compile the package:

make prefix=/usr

To test the results, issue:

make check

Install the package:

make prefix=/usr install

Remove the static library:

rm -v /usr/lib/libzstd.a

8.10. File-5.42

Prepare File for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.11. Readline-8.1.2

Reinstalling Readline will cause the old libraries to be moved to <libraryname>.old. While this is normally not a problem, in some cases it can trigger a linking bug in ldconfig. This can be avoided by issuing the following two seds:

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

Prepare Readline for compilation:

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

Compile the package:

make SHLIB_LIBS="-lncursesw"

Install the package:

make SHLIB_LIBS="-lncursesw" install

If desired, install the documentation:

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

8.12. M4-1.4.19

Prepare M4 for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.13. Bc-6.0.1

Prepare Bc for compilation:

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

Compile the package:

make

To test bc, run:

make test

Install the package:

make install

8.14. Flex-2.6.4

Prepare Flex for compilation:

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

Compile the package:

make

To test the results (about 0.5 SBU), issue:

make check

Install the package:

make install

A few programs do not know about flex yet and try to run its predecessor, lex. To support those programs, create a symbolic link named lex that runs flex in lex emulation mode:

ln -sv flex /usr/bin/lex

8.15. Tcl-8.6.12

First, unpack the documentation by issuing the following command:

tar -xf ../tcl8.6.12-html.tar.gz --strip-components=1

Prepare Tcl for compilation:

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

Build the package:

make
 
sed -e "s|$SRCDIR/unix|/usr/lib|" \
    -e "s|$SRCDIR|/usr/include|"  \
    -i tclConfig.sh
 
sed -e "s|$SRCDIR/unix/pkgs/tdbc1.1.3|/usr/lib/tdbc1.1.3|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.3/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/tdbc1.1.3/library|/usr/lib/tcl8.6|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.3|/usr/include|"            \
    -i pkgs/tdbc1.1.3/tdbcConfig.sh
 
sed -e "s|$SRCDIR/unix/pkgs/itcl4.2.2|/usr/lib/itcl4.2.2|" \
    -e "s|$SRCDIR/pkgs/itcl4.2.2/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/itcl4.2.2|/usr/include|"            \
    -i pkgs/itcl4.2.2/itclConfig.sh
 
unset SRCDIR

To test the results, issue:

make test

Install the package:

make install

Make the installed library writable so debugging symbols can be removed later:

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

Install Tcl’s headers. The next package, Expect, requires them.

make install-private-headers

Now make a necessary symbolic link:

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

Rename a man page that conflicts with a Perl man page:

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

If you downloaded the optional documentation, install it by issuing the following commands:

mkdir -v -p /usr/share/doc/tcl-8.6.12
cp -v -r  ../html/* /usr/share/doc/tcl-8.6.12

8.16. Expect-5.45.4

Prepare Expect for compilation:

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

Build the package:

make

To test the results, issue:

make test

Install the package:

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

8.17. DejaGNU-1.6.3

The upstream recommends building DejaGNU in a dedicated build directory:

mkdir -v build
cd       build

Prepare DejaGNU for compilation:

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

Build and install the package:

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

To test the results, issue:

make check

8.18. Binutils-2.39

Verify that the PTYs are working properly inside the chroot environment by performing a simple test:

expect -c "spawn ls"

This command should output the following:

spawn ls

I got the output of.

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

To fix this I did

mknod /dev/ptmx c 5 2
chmod 777 /dev/ptmx

The Binutils documentation recommends building Binutils in a dedicated build directory:

mkdir -v build
cd       build

Prepare Binutils for compilation:

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

Compile the package:

make tooldir=/usr

Test the results:

make -k check

Install the package:

make tooldir=/usr install

Remove useless static libraries:

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

8.19. GMP-6.2.1

Prepare GMP for compilation:

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

Compile the package and generate the HTML documentation:

make
make html

Test the results:

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

Ensure that all 197 tests in the test suite passed. Check the results by issuing the following command:

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

Install the package and its documentation:

make install
make install-html

8.20. MPFR-4.1.0

Prepare MPFR for compilation:

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

Compile the package and generate the HTML documentation:

make
make html

Test the results and ensure that all tests passed:

make check

Install the package and its documentation:

make install
make install-html

8.21. MPC-1.2.1

Prepare MPC for compilation:

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

Compile the package and generate the HTML documentation:

make
make html

To test the results, issue:

make check

Install the package and its documentation:

make install
make install-html

8.22. Attr-2.5.1

Prepare Attr for compilation:

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

Compile the package:

make

The tests need to be run on a filesystem that supports extended attributes such as the ext2, ext3, or ext4 filesystems. To test the results, issue:

make check

Install the package:

make install

8.24. Libcap-2.65

Prevent static libraries from being installed:

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

Compile the package:

make prefix=/usr lib=lib

To test the results, issue:

make test

Install the package:

make prefix=/usr lib=lib install

8.25. Shadow-4.12.2

Disable the installation of the groups program and its man pages, as Coreutils provides a better version. Also, prevent the installation of manual pages that were already installed in Section 8.3, “Man-pages-5.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:/var/spool/mail:/var/mail:'                 \
    -e '/PATH=/{s@/sbin:@@;s@/bin:@@}'                \
    -i etc/login.defs
sed -i 's:DICTPATH.*:DICTPATH\t/lib/cracklib/pw_dict:' etc/login.defs
touch /usr/bin/passwd
./configure --sysconfdir=/etc \
            --disable-static  \
            --with-group-name-max-length=32

Compile the package:

make

Install the package:

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

To enable shadowed passwords, run the following command:

pwconv

To enable shadowed group passwords, run:

grpconv

Choose a password for user root and set it by running:

passwd root

I had an error here the solution was leaving chroot and re-entering

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)
fi
 
chroot "$LFS" /usr/bin/env -i   \
    HOME=/root                  \
    TERM="$TERM"                \
    PS1='(lfs chroot) \u:\w\$ ' \
    PATH=/usr/bin:/usr/sbin     \
    /bin/bash --login

8.26. GCC-12.2.0

If building on x86_64, change the default directory name for 64-bit libraries to “lib”:

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

The GCC documentation recommends building GCC in a dedicated build directory:

mkdir -v build
cd       build

Prepare GCC for compilation:

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

Compile the package:

make

One set of tests in the GCC test suite is known to exhaust the default stack, so increase the stack size prior to running the tests:

ulimit -s 32768

Test the results as a non-privileged user, but do not stop at errors:

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

To receive a summary of the test suite results, run:

../contrib/test_summary

Install the package:

make install

The GCC build directory is owned by tester now and the ownership of the installed header directory (and its content) will be incorrect. Change the ownership to root user and group:

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

Create a symlink required by the FHS for “historical” reasons.

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

Add a compatibility symlink to enable building programs with Link Time Optimization (LTO):

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

Now that our final toolchain is in place, it is important to again ensure that compiling and linking will work as expected. We do this by performing some sanity checks:

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

There should be no errors, and the output of the last command will be (allowing for platform-specific differences in the dynamic linker name):

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

Now make sure that we’re setup to use the correct start files:

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

The output of the last command should be:

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

Verify that the compiler is searching for the correct header files:

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

This command should return the following output:

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

Next, verify that the new linker is being used with the correct search paths:

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

References to paths that have components with ‘-linux-gnu’ should be ignored, but otherwise the output of the last command should be:

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");

Next make sure that we’re using the correct libc:

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

The output of the last command should be:

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

Make sure GCC is using the correct dynamic linker:

grep found dummy.log

The output of the last command should be (allowing for platform-specific differences in dynamic linker name):

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

Once everything is working correctly, clean up the test files:

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

Finally, move a misplaced file:

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

8.27. Pkg-config-0.29.2

Prepare Pkg-config for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.28. Ncurses-6.3

Prepare Ncurses for compilation:

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

Compile the package:

make

The installation of this package will overwrite libncursesw.so.6.3 in-place. It may crash the shell process which is using code and data from the library file. Install the package with DESTDIR, and replace the library file correctly using install command. A useless static archive which is not handled by configure is also removed:

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

Many applications still expect the linker to be able to find non-wide-character Ncurses libraries. Trick such applications into linking with wide-character libraries by means of symlinks and linker scripts:

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

Finally, make sure that old applications that look for -lcurses at build time are still buildable:

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

If desired, install the Ncurses documentation:

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

8.29. Sed-4.8

Prepare Sed for compilation:

./configure --prefix=/usr

Compile the package and generate the HTML documentation:

make
make html

To test the results, issue:

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

Install the package and its documentation:

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

8.30. Psmisc-23.5

Prepare Psmisc for compilation:

./configure --prefix=/usr

Compile the package:

make

Install the package:

make install

8.31. Gettext-0.21

Prepare Gettext for compilation:

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

Compile the package:

make

To test the results (this takes a long time, around 3 SBUs), issue:

make check

Install the package:

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

8.32. Bison-3.8.2

Prepare Bison for compilation:

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

Compile the package:

make

To test the results (about 5.5 SBU), issue:

make check

Install the package:

make install

8.33. Grep-3.7

Prepare Grep for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.34. Bash-5.1.16

Prepare Bash for compilation:

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

Compile the package:

make

To prepare the tests, ensure that the tester user can write to the sources tree:

chown -Rv tester .

The testsuite of the package is designed to be run as a non-root user that owns the terminal connected to standard input. To satisfy the requirement, spawn a new pseudo terminal using Expect and run the tests as the tester user:

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

Install the package:

make install

Run the newly compiled bash program (replacing the one that is currently being executed):

exec /usr/bin/bash --login

8.35. Libtool-2.4.7

Prepare Libtool for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

Remove a useless static library:

rm -fv /usr/lib/libltdl.a

8.36. GDBM-1.23

Prepare GDBM for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.37. Gperf-3.1

Prepare Gperf for compilation:

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

Compile the package:

make

The tests are known to fail if running multiple simultaneous tests (-j option greater than 1). To test the results, issue:

make -j1 check

Install the package:

make install

8.38. Expat-2.4.8

Prepare Expat for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

If desired, install the documentation:

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

8.39. Inetutils-2.3

Prepare Inetutils for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

Move a program to the proper location:

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

8.40. Less-590

Prepare Less for compilation:

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

Compile the package:

make

Install the package:

make install

8.41. Perl-5.36.0

This version of Perl now builds the Compress::Raw::Zlib and Compress::Raw::BZip2 modules. By default Perl will use an internal copy of the sources for the build. Issue the following command so that Perl will use the libraries installed on the system:

export BUILD_ZLIB=False
export BUILD_BZIP2=0

To have full control over the way Perl is set up, you can remove the “-des” options from the following command and hand-pick the way this package is built. Alternatively, use the command exactly as below to use the defaults that Perl auto-detects:

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

Compile the package:

make

To test the results (approximately 11 SBU), issue:

make test

Install the package and clean up:

make install
unset BUILD_ZLIB BUILD_BZIP2

8.42. XML::Parser-2.46

Prepare XML::Parser for compilation:

perl Makefile.PL

Compile the package:

make

To test the results, issue:

make test

Install the package:

make install

8.43. Intltool-0.51.0

First fix a warning that is caused by perl-5.22 and later:

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

Prepare Intltool for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

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

8.44. Autoconf-2.71

Prepare Autoconf for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.45. Automake-1.16.5

Prepare Automake for compilation:

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

Compile the package:

make

Using the -j4 make option speeds up the tests, even on systems with only one processor, due to internal delays in individual tests. To test the results, issue:

make -j4 check

The test t/subobj.sh is known to fail.
Install the package:

make install

8.46. OpenSSL-3.0.5

Prepare OpenSSL for compilation:

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

Compile the package:

make

To test the results, issue:

make test

Install the package:

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

Add the version to the documentation directory name, to be consistent with other packages:

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

If desired, install some additional documentation:

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

8.47. Kmod-30

Prepare Kmod for compilation:

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

Compile the package:

make

Install the package and create symlinks for compatibility with Module-Init-Tools (the package that previously handled Linux kernel modules):

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

8.48. Libelf from Elfutils-0.187

Libelf is part of elfutils-0.187 package. Use the elfutils-0.187.tar.bz2 as the source tarball.
Prepare Libelf for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install only Libelf:

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

8.49. Libffi-3.4.2

Prepare libffi for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.50. Python-3.10.8

Prepare Python for compilation:

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

Compile the package:

make

Install the package:

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

If desired, install the preformatted documentation:

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

8.51. Wheel-0.37.1

Install wheel with the following command:

pip3 install --no-index $PWD

8.52. Ninja-1.11.0

Using the optional procedure below allows a user to limit the number of parallel processes via an environment variable, NINJAJOBS. For example, setting:

export NINJAJOBS=4

If desired, add the capability to use the environment variable NINJAJOBS by running:

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

Build Ninja with:

python3 configure.py --bootstrap

To test the results, issue:

./ninja ninja_test
./ninja_test --gtest_filter=-SubprocessTest.SetWithLots

Install the package:

install -vm755 ninja /usr/bin/
install -vDm644 misc/bash-completion /usr/share/bash-completion/completions/ninja
install -vDm644 misc/zsh-completion  /usr/share/zsh/site-functions/_ninja

8.53. Meson-0.63.1

Compile Meson with the following command:

pip3 wheel -w dist --no-build-isolation --no-deps $PWD

Install the package:

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

8.54. Coreutils-9.1

POSIX requires that programs from Coreutils recognize character boundaries correctly even in multibyte locales. The following patch fixes this non-compliance and other internationalization-related bugs.

patch -Np1 -i ../coreutils-9.1-i18n-1.patch

Now prepare Coreutils for compilation:

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

Compile the package:

make

Now the test suite is ready to be run. First, run the tests that are meant to be run as user root:

make NON_ROOT_USERNAME=tester check-root

We’re going to run the remainder of the tests as the tester user. Certain tests require that the user be a member of more than one group. So that these tests are not skipped, add a temporary group and make the user tester a part of it:

echo "dummy:x:102:tester" >> /etc/group

Fix some of the permissions so that the non-root user can compile and run the tests:

chown -Rv tester . 

Now run the tests:

su tester -c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"

Remove the temporary group:

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

Install the package:

make install

Move programs to the locations specified by the FHS:

mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' /usr/share/man/man8/chroot.8

8.55. Check-0.15.2

Prepare Check for compilation:

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

Build the package:

make

Compilation is now complete. To run the Check test suite, issue the following command:

make check

Install the package:

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

8.56. Diffutils-3.8

Prepare Diffutils for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.57. Gawk-5.1.1

First, ensure some unneeded files are not installed:

sed -i 's/extras//' Makefile.in

Prepare Gawk for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

If desired, install the documentation:

mkdir -pv /usr/share/doc/gawk-5.1.1
cp -v doc/{awkforai.txt,*.{eps,pdf,jpg}} /usr/share/doc/gawk-5.1.1

8.58. Findutils-4.9.0

Prepare Findutils for compilation:

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

Compile the package:

make

To test the results, issue:

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

Install the package:

make install

8.59. Groff-1.22.4

Prepare Groff for compilation:

PAGE=<paper_size> ./configure --prefix=/usr

This package does not support parallel build. Compile the package:

make -j1

Install the package:

make install

8.60. GRUB-2.06

Prepare GRUB for compilation:

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

Compile the package:

make

Install the package:

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

8.61. Gzip-1.12

Prepare Gzip for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.62. IPRoute2-5.19.0

sed -i /ARPD/d Makefile
rm -fv man/man8/arpd.8
 
make NETNS_RUN_DIR=/run/netns
make SBINDIR=/usr/sbin install

8.63. Kbd-2.5.1

The behaviour of the backspace and delete keys is not consistent across the keymaps in the Kbd package. The following patch fixes this issue for i386 keymaps:

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

Remove the redundant resizecons program (it requires the defunct svgalib to provide the video mode files - for normal use setfont sizes the console appropriately) together with its manpage.

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

Prepare Kbd for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

If desired, install the documentation:

mkdir -pv /usr/share/doc/kbd-2.5.1
cp -R -v docs/doc/* /usr/share/doc/kbd-2.5.1

8.64. Libpipeline-1.5.6

Prepare Libpipeline for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.65. Make-4.3

Prepare Make for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.66. Patch-2.7.6

Prepare Patch for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.67. Tar-1.34

Prepare Tar for compilation:

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

Compile the package:

make

To test the results, issue:

make check

Install the package:

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

8.68. Texinfo-6.8

Prepare Texinfo for compilation:

./configure --prefix=/usr

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

Optionally, install the components belonging in a TeX installation:

make TEXMF=/usr/share/texmf install-tex

The Info documentation system uses a plain text file to hold its list of menu entries. The file is located at /usr/share/info/dir. Unfortunately, due to occasional problems in the Makefiles of various packages, it can sometimes get out of sync with the info pages installed on the system. If the /usr/share/info/dir file ever needs to be recreated, the following optional commands will accomplish the task:

pushd /usr/share/info
  rm -v dir
  for f in *
    do install-info $f dir 2>/dev/null
  done
popd

8.69. Vim-9.0.0228

tar xf vim-9.0.0228.tar.gz 
cd vim-9.0.0228
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
./configure --prefix=/usr; make; 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.0228

8.70. Eudev-3.2.11

Prepare Eudev for compilation:

./configure --prefix=/usr           \
            --bindir=/usr/sbin      \
            --sysconfdir=/etc       \
            --enable-manpages       \
            --disable-static

Compile the package:

make

Create some directories now that are needed for tests, but will also be used as a part of installation:

mkdir -pv /usr/lib/udev/rules.d
mkdir -pv /etc/udev/rules.d

To test the results, issue:

make check

Install the package:

make install

Install some custom rules and support files useful in an LFS environment:

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

Configuring Eudev

udevadm hwdb --update

8.70 MarkupSafe

tar -xf MarkupSafe-2.1.1.tar.gz 
cd MarkupSafe-2.1.1
pip3 wheel -w dist --no-build-isolation --no-deps $PWD
pip3 install --no-index --no-user --find-links dist Markupsafe

8.71 Jinja2

tar xf Jinja2-3.1.2.tar.gz 
cd Jinja2-3.1.2
pip3 wheel -w dist --no-build-isolation --no-deps $PWD
pip3 install --no-index --no-user --find-links dist Jinja2

8.72. Systemd-251

First, fix an issue introduced by glibc-2.36.

patch -Np1 -i ../systemd-251-glibc_2.36_fix-1.patch

Remove two unneeded groups, render and sgx, from the default udev rules:

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

Prepare systemd for compilation:

mkdir -p build
cd       build
 
meson --prefix=/usr                 \
      --buildtype=release           \
      -Ddefault-dnssec=no           \
      -Dfirstboot=false             \
      -Dinstall-tests=false         \
      -Dldconfig=false              \
      -Dsysusers=false              \
      -Drpmmacrosdir=no             \
      -Dhomed=false                 \
      -Duserdb=false                \
      -Dman=false                   \
      -Dmode=release                \
      -Dpamconfdir=no               \
      -Ddocdir=/usr/share/doc/systemd-251 \
      ..

Compile the package:

ninja

Install the package:

ninja install

Install the man pages:

tar -xf ../../systemd-man-pages-251.tar.xz --strip-components=1 -C /usr/share/man

Create the /etc/machine-id file needed by systemd-journald:

systemd-machine-id-setup

Setup the basic target structure:

systemctl preset-all

Disable a service for upgrading binary distros. It’s useless for a basic Linux system built from source, and it will report an error if it’s enabled but not configured:

systemctl disable systemd-sysupdate

8.73. D-Bus-1.14.0

Prepare D-Bus for compilation:

./configure --prefix=/usr                        \
            --sysconfdir=/etc                    \
            --localstatedir=/var                 \
            --runstatedir=/run                   \
            --disable-static                     \
            --disable-doxygen-docs               \
            --disable-xml-docs                   \
            --docdir=/usr/share/doc/dbus-1.14.0 \
            --with-system-socket=/run/dbus/system_bus_socket

Compile the package:

make

Install the package:

make install

Create a symlink so that D-Bus and systemd can use the same machine-id file:

ln -sfv /etc/machine-id /var/lib/dbus

8.74. Man-DB-2.10.2

Prepare Man-DB for compilation:

./configure --prefix=/usr                         \
            --docdir=/usr/share/doc/man-db-2.10.2 \
            --sysconfdir=/etc                     \
            --disable-setuid                      \
            --enable-cache-owner=bin              \
            --with-browser=/usr/bin/lynx          \
            --with-vgrind=/usr/bin/vgrind         \
            --with-grap=/usr/bin/grap

Compile the package:

make

To test the results, issue:

make check

Install the package:

make install

8.75. Procps-ng-4.0.0

Prepare procps-ng for compilation:

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

Compile the package:

make

To run the test suite, run:

make check

Install the package:

make install

8.76. Util-linux-2.38.1

Prepare Util-linux for compilation:

./configure ADJTIME_PATH=/var/lib/hwclock/adjtime   \
            --bindir=/usr/bin    \
            --libdir=/usr/lib    \
            --sbindir=/usr/sbin  \
            --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

Compile the package:

make

Install the package:

make install

8.77. E2fsprogs-1.46.5

The e2fsprogs documentation recommends that the package be built in a subdirectory of the source tree:

mkdir -v build
cd       build

Prepare e2fsprogs for compilation:

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

Compile the package:

make

To run the tests, issue:

make check

Install the package:

make install

Skipped over stripping

8.80. Cleaning Up

Finally, clean up some extra files left around from running tests:

rm -rf /tmp/*
find /usr/lib /usr/libexec -name \*.la -delete

The compiler built in Chapter 6 and Chapter 7 is still partially installed and not needed anymore. Remove it with:

find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf

Finally, remove the temporary ‘tester’ user account created at the beginning of the previous chapter.

userdel -r tester

Chapter 9 System Configuration

9.2 Networking Configuration

9.2.1.3. DHCP Configuration

The command below creates a basic configuration file for an IPv4 DHCP setup:

cat > /etc/systemd/network/10-eth-dhcp.network << "EOF"
[Match]
Name=<network-device-name>
 
[Network]
DHCP=ipv4
 
[DHCP]
UseDomains=true
EOF

9.2.3 Hostname

echo "lfs-paul" > /etc/hostname

9.2.4 /etc/hosts

cat > /etc/hosts << "EOF"
# Begin /etc/hosts
 
127.0.0.1 localhost.localdomain localhost
127.0.1.1 lfs-paul
::1       localhost ip6-localhost ip6-loopback
ff02::1   ip6-allnodes
ff02::2   ip6-allrouters
 
# End /etc/hosts
EOF

9.5 System Clock

systemctl disable systemd-timesyncd

9.7 Locale

cat > /etc/locale.conf << "EOF"
LANG=EN_US.UTF-8
EOF

9.8 inputrc

cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>
 
# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off
 
# Enable 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

9.9 shells

cat > /etc/shells << "EOF"
# Begin /etc/shells
 
/bin/sh
/bin/bash
 
# End /etc/shells
EOF

9.10 Systemd configuration

mkdir -pv /etc/systemd/system/getty@tty1.service.d
 
cat > /etc/systemd/system/getty@tty1.service.d/noclear.conf << EOF
[Service]
TTYVTDisallocate=no
EOF

Chapter 10 Making LFS Bootable

10.2 /etc/fstab

cat > /etc/fstab << "EOF"
# Begin /etc/fstab
 
# file system  mount-point  type     options         dump  fsck
#                                                          order
 
/dev/sda3     /            ext4   defaults            1     1
/dev/sda4     /home        ext4   defaults            1     1
/dev/sda5     swap         swap     pri=1             0     0
 
# End /etc/fstab
EOF

10.3.1 Linux Kernel

tar xf linux-5.19.2.tar.xz 
cd tar xf linux-5.19.2
make mrproper
make defconfig
 
make
make modules_install
 
mount /dev/sdb2 /boot
 
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-5.19.2-lfs-11.2-systemd
cp -iv System.map /boot/System.map-5.19.2
cp -iv .config /boot/config-5.19.2
install -d /usr/share/doc/linux-5.19.2

10.3.2 Module load order

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

10.4 Grub

Powered off snapshot

mount /dev/sdb2 /boot
grub-install /dev/sdb
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 5.19.2-lfs-11.2-systemd" {
        linux  /vmlinuz-5.19.2-lfs-11.2-systemd root=/dev/sda3 ro
}
EOF

Chapter 11 The End

echo 11.2-systemd > /etc/lfs-release
cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="11.2-systemd"
DISTRIB_CODENAME="lfs-paul"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF
cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="11.2-systemd"
ID=lfs
PRETTY_NAME="Linux From Scratch 11.2-systemd"
VERSION_CODENAME="lfs-paul"
EOF