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 install8.4. Iana-Etc-20220812
For this package, we only need to copy the files into place:
cp services protocols /etc8.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.patchThe Glibc documentation recommends building Glibc in a dedicated build directory:
mkdir -v build
cd buildEnsure that the ldconfig and sln utilities will be installed into /usr/sbin:
echo "rootsbindir=/usr/sbin" > configparmsPrepare Glibc for compilation:
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=3.2 \
--enable-stack-protector=strong \
--with-headers=/usr/include \
libc_cv_slibdir=/usr/libCompile the package:
makeGenerally a few tests do not pass. The test failures listed below are usually safe to ignore.
make checkThough 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.confFix the Makefile to skip an unneeded sanity check that fails in the LFS partial environment:
sed '/test-installation/s@$(PERL)@echo not running@' -i ../MakefileInstall the package:
make installFix hard coded path to the executable loader in ldd script:
sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/lddInstall the configuration file and runtime directory for nscd:
cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscdIndividual 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-8Alternatively, 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-localesThen 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 || true8.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
EOFInstall 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 ZONEINFOHad 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/nullThen create the /etc/localtime file by running:
ln -sfv /usr/share/zoneinfo/America/New_York /etc/localtimeCreate 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
EOFIf 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.d8.6. Zlib-1.2.12
Prepare Zlib for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installRemove a useless static library:
rm -fv /usr/lib/libz.a8.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.patchThe following command ensures installation of symbolic links are relative:
sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' MakefileEnsure the man pages are installed into the correct location:
sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" MakefilePrepare Bzip2 for compilation with:
make -f Makefile-libbz2_so
make clean8.8. Xz-5.2.6
Prepare Xz for compilation with:
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/xz-5.2.6Compile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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.patchCompile the package:
make prefix=/usrTo test the results, issue:
make checkInstall the package:
make prefix=/usr installRemove the static library:
rm -v /usr/lib/libzstd.a8.10. File-5.42
Prepare File for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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-installPrepare Readline for compilation:
./configure --prefix=/usr \
--disable-static \
--with-curses \
--docdir=/usr/share/doc/readline-8.1.2Compile the package:
make SHLIB_LIBS="-lncursesw"Install the package:
make SHLIB_LIBS="-lncursesw" installIf desired, install the documentation:
install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-8.1.28.12. M4-1.4.19
Prepare M4 for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.13. Bc-6.0.1
Prepare Bc for compilation:
CC=gcc ./configure --prefix=/usr -G -O3 -rCompile the package:
makeTo test bc, run:
make testInstall the package:
make install8.14. Flex-2.6.4
Prepare Flex for compilation:
./configure --prefix=/usr \
--docdir=/usr/share/doc/flex-2.6.4 \
--disable-staticCompile the package:
makeTo test the results (about 0.5 SBU), issue:
make checkInstall the package:
make installA 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/lex8.15. Tcl-8.6.12
First, unpack the documentation by issuing the following command:
tar -xf ../tcl8.6.12-html.tar.gz --strip-components=1Prepare Tcl for compilation:
SRCDIR=$(pwd)
cd unix
./configure --prefix=/usr \
--mandir=/usr/share/manBuild 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 SRCDIRTo test the results, issue:
make testInstall the package:
make installMake the installed library writable so debugging symbols can be removed later:
chmod -v u+w /usr/lib/libtcl8.6.soInstall Tcl’s headers. The next package, Expect, requires them.
make install-private-headersNow make a necessary symbolic link:
ln -sfv tclsh8.6 /usr/bin/tclshRename a man page that conflicts with a Perl man page:
mv /usr/share/man/man3/{Thread,Tcl_Thread}.3If 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.128.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/includeBuild the package:
makeTo test the results, issue:
make testInstall the package:
make install
ln -svf expect5.45.4/libexpect5.45.4.so /usr/lib8.17. DejaGNU-1.6.3
The upstream recommends building DejaGNU in a dedicated build directory:
mkdir -v build
cd buildPrepare 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.texiBuild 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.3To test the results, issue:
make check8.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 lsI 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/ptmxThe Binutils documentation recommends building Binutils in a dedicated build directory:
mkdir -v build
cd buildPrepare 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-zlibCompile the package:
make tooldir=/usrTest the results:
make -k checkInstall the package:
make tooldir=/usr installRemove useless static libraries:
rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes}.a8.19. GMP-6.2.1
Prepare GMP for compilation:
./configure --prefix=/usr \
--enable-cxx \
--disable-static \
--docdir=/usr/share/doc/gmp-6.2.1Compile the package and generate the HTML documentation:
make
make htmlTest the results:
make check 2>&1 | tee gmp-check-logEnsure 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-logInstall the package and its documentation:
make install
make install-html8.20. MPFR-4.1.0
Prepare MPFR for compilation:
./configure --prefix=/usr \
--disable-static \
--enable-thread-safe \
--docdir=/usr/share/doc/mpfr-4.1.0Compile the package and generate the HTML documentation:
make
make htmlTest the results and ensure that all tests passed:
make checkInstall the package and its documentation:
make install
make install-html8.21. MPC-1.2.1
Prepare MPC for compilation:
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/mpc-1.2.1Compile the package and generate the HTML documentation:
make
make htmlTo test the results, issue:
make checkInstall the package and its documentation:
make install
make install-html8.22. Attr-2.5.1
Prepare Attr for compilation:
./configure --prefix=/usr \
--disable-static \
--sysconfdir=/etc \
--docdir=/usr/share/doc/attr-2.5.1Compile the package:
makeThe 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 checkInstall the package:
make install8.24. Libcap-2.65
Prevent static libraries from being installed:
sed -i '/install -m.*STA/d' libcap/MakefileCompile the package:
make prefix=/usr lib=libTo test the results, issue:
make testInstall the package:
make prefix=/usr lib=lib install8.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.defssed -i 's:DICTPATH.*:DICTPATH\t/lib/cracklib/pw_dict:' etc/login.defstouch /usr/bin/passwd
./configure --sysconfdir=/etc \
--disable-static \
--with-group-name-max-length=32Compile the package:
makeInstall the package:
make exec_prefix=/usr install
make -C man install-manTo enable shadowed passwords, run the following command:
pwconvTo enable shadowed group passwords, run:
grpconvChoose a password for user root and set it by running:
passwd rootI 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 --login8.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
;;
esacThe GCC documentation recommends building GCC in a dedicated build directory:
mkdir -v build
cd buildPrepare GCC for compilation:
../configure --prefix=/usr \
LD=ld \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlibCompile the package:
makeOne 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 32768Test 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_summaryInstall the package:
make installThe 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/libAdd 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.logThe 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 succeededVerify that the compiler is searching for the correct header files:
grep -B4 '^ /usr/include' dummy.logThis 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/includeNext, 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.logThe output of the last command should be:
attempt to open /usr/lib/libc.so.6 succeededMake sure GCC is using the correct dynamic linker:
grep found dummy.logThe 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.2Once everything is working correctly, clean up the test files:
rm -v dummy.c a.out dummy.logFinally, 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/lib8.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.2Compile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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/pkgconfigCompile the package:
makeThe 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
doneFinally, 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.soIf desired, install the Ncurses documentation:
mkdir -pv /usr/share/doc/ncurses-6.3
cp -v -R doc/* /usr/share/doc/ncurses-6.38.29. Sed-4.8
Prepare Sed for compilation:
./configure --prefix=/usrCompile the package and generate the HTML documentation:
make
make htmlTo 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.88.30. Psmisc-23.5
Prepare Psmisc for compilation:
./configure --prefix=/usrCompile the package:
makeInstall the package:
make install8.31. Gettext-0.21
Prepare Gettext for compilation:
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-0.21Compile the package:
makeTo test the results (this takes a long time, around 3 SBUs), issue:
make checkInstall the package:
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so8.32. Bison-3.8.2
Prepare Bison for compilation:
./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.8.2Compile the package:
makeTo test the results (about 5.5 SBU), issue:
make checkInstall the package:
make install8.33. Grep-3.7
Prepare Grep for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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-readlineCompile the package:
makeTo 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
EOFInstall the package:
make installRun the newly compiled bash program (replacing the one that is currently being executed):
exec /usr/bin/bash --login8.35. Libtool-2.4.7
Prepare Libtool for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installRemove a useless static library:
rm -fv /usr/lib/libltdl.a8.36. GDBM-1.23
Prepare GDBM for compilation:
./configure --prefix=/usr \
--disable-static \
--enable-libgdbm-compatCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.37. Gperf-3.1
Prepare Gperf for compilation:
./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1Compile the package:
makeThe tests are known to fail if running multiple simultaneous tests (-j option greater than 1). To test the results, issue:
make -j1 checkInstall the package:
make install8.38. Expat-2.4.8
Prepare Expat for compilation:
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/expat-2.4.8Compile the package:
makeTo test the results, issue:
make checkInstall the package:
make installIf desired, install the documentation:
install -v -m644 doc/*.{html,css} /usr/share/doc/expat-2.4.88.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-serversCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installMove a program to the proper location:
mv -v /usr/{,s}bin/ifconfig8.40. Less-590
Prepare Less for compilation:
./configure --prefix=/usr --sysconfdir=/etcCompile the package:
makeInstall the package:
make install8.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=0To 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 \
-DusethreadsCompile the package:
makeTo test the results (approximately 11 SBU), issue:
make testInstall the package and clean up:
make install
unset BUILD_ZLIB BUILD_BZIP28.42. XML::Parser-2.46
Prepare XML::Parser for compilation:
perl Makefile.PLCompile the package:
makeTo test the results, issue:
make testInstall the package:
make install8.43. Intltool-0.51.0
First fix a warning that is caused by perl-5.22 and later:
sed -i 's:\\\${:\\\$\\{:' intltool-update.inPrepare Intltool for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install
install -v -Dm644 doc/I18N-HOWTO /usr/share/doc/intltool-0.51.0/I18N-HOWTO8.44. Autoconf-2.71
Prepare Autoconf for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.45. Automake-1.16.5
Prepare Automake for compilation:
./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.16.5Compile the package:
makeUsing 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 checkThe test t/subobj.sh is known to fail.
Install the package:
make install8.46. OpenSSL-3.0.5
Prepare OpenSSL for compilation:
./config --prefix=/usr \
--openssldir=/etc/ssl \
--libdir=lib \
shared \
zlib-dynamicCompile the package:
makeTo test the results, issue:
make testInstall the package:
sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile
make MANSUFFIX=ssl installAdd 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.5If desired, install some additional documentation:
cp -vfr doc/* /usr/share/doc/openssl-3.0.58.47. Kmod-30
Prepare Kmod for compilation:
./configure --prefix=/usr \
--sysconfdir=/etc \
--with-openssl \
--with-xz \
--with-zstd \
--with-zlibCompile the package:
makeInstall 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/lsmod8.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=dummyCompile the package:
makeTo test the results, issue:
make checkInstall only Libelf:
make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
rm /usr/lib/libelf.a8.49. Libffi-3.4.2
Prepare libffi for compilation:
./configure --prefix=/usr \
--disable-static \
--with-gcc-arch=native \
--disable-exec-static-trampCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.50. Python-3.10.8
Prepare Python for compilation:
./configure --prefix=/usr \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--enable-optimizationsCompile the package:
makeInstall the package:
make installcat > /etc/pip.conf << EOF
[global]
root-user-action = ignore
disable-pip-version-check = true
EOFIf 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.bz28.51. Wheel-0.37.1
Install wheel with the following command:
pip3 install --no-index $PWD8.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=4If 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.ccBuild Ninja with:
python3 configure.py --bootstrapTo test the results, issue:
./ninja ninja_test
./ninja_test --gtest_filter=-SubprocessTest.SetWithLotsInstall 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/_ninja8.53. Meson-0.63.1
Compile Meson with the following command:
pip3 wheel -w dist --no-build-isolation --no-deps $PWDInstall 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/_meson8.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.patchNow prepare Coreutils for compilation:
autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix=/usr \
--enable-no-install-program=kill,uptimeCompile the package:
makeNow 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-rootWe’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/groupFix 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/groupInstall the package:
make installMove 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.88.55. Check-0.15.2
Prepare Check for compilation:
./configure --prefix=/usr --disable-staticBuild the package:
makeCompilation is now complete. To run the Check test suite, issue the following command:
make checkInstall the package:
make docdir=/usr/share/doc/check-0.15.2 install8.56. Diffutils-3.8
Prepare Diffutils for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.57. Gawk-5.1.1
First, ensure some unneeded files are not installed:
sed -i 's/extras//' Makefile.inPrepare Gawk for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installIf 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.18.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 ;;
esacCompile the package:
makeTo test the results, issue:
chown -Rv tester .
su tester -c "PATH=$PATH make check"Install the package:
make install8.59. Groff-1.22.4
Prepare Groff for compilation:
PAGE=<paper_size> ./configure --prefix=/usrThis package does not support parallel build. Compile the package:
make -j1Install the package:
make install8.60. GRUB-2.06
Prepare GRUB for compilation:
./configure --prefix=/usr \
--sysconfdir=/etc \
--disable-efiemu \
--disable-werrorCompile the package:
makeInstall the package:
make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions8.61. Gzip-1.12
Prepare Gzip for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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 install8.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.patchRemove 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.inPrepare Kbd for compilation:
./configure --prefix=/usr --disable-vlockCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installIf desired, install the documentation:
mkdir -pv /usr/share/doc/kbd-2.5.1
cp -R -v docs/doc/* /usr/share/doc/kbd-2.5.18.64. Libpipeline-1.5.6
Prepare Libpipeline for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.65. Make-4.3
Prepare Make for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.66. Patch-2.7.6
Prepare Patch for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.67. Tar-1.34
Prepare Tar for compilation:
FORCE_UNSAFE_CONFIGURE=1 \
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install
make -C doc install-html docdir=/usr/share/doc/tar-1.348.68. Texinfo-6.8
Prepare Texinfo for compilation:
./configure --prefix=/usrCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make installOptionally, install the components belonging in a TeX installation:
make TEXMF=/usr/share/texmf install-texThe 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
popd8.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.02288.70. Eudev-3.2.11
Prepare Eudev for compilation:
./configure --prefix=/usr \
--bindir=/usr/sbin \
--sysconfdir=/etc \
--enable-manpages \
--disable-staticCompile the package:
makeCreate 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.dTo test the results, issue:
make checkInstall the package:
make installInstall 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 installConfiguring Eudev
udevadm hwdb --update8.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 Markupsafe8.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 Jinja28.72. Systemd-251
First, fix an issue introduced by glibc-2.36.
patch -Np1 -i ../systemd-251-glibc_2.36_fix-1.patchRemove 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.inPrepare 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:
ninjaInstall the package:
ninja installInstall the man pages:
tar -xf ../../systemd-man-pages-251.tar.xz --strip-components=1 -C /usr/share/manCreate the /etc/machine-id file needed by systemd-journald:
systemd-machine-id-setupSetup the basic target structure:
systemctl preset-allDisable 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-sysupdate8.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_socketCompile the package:
makeInstall the package:
make installCreate a symlink so that D-Bus and systemd can use the same machine-id file:
ln -sfv /etc/machine-id /var/lib/dbus8.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/grapCompile the package:
makeTo test the results, issue:
make checkInstall the package:
make install8.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-systemdCompile the package:
makeTo run the test suite, run:
make checkInstall the package:
make install8.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-pythonCompile the package:
makeInstall the package:
make install8.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 buildPrepare e2fsprogs for compilation:
../configure --prefix=/usr \
--sysconfdir=/etc \
--enable-elf-shlibs \
--disable-libblkid \
--disable-libuuid \
--disable-uuidd \
--disable-fsckCompile the package:
makeTo run the tests, issue:
make checkInstall the package:
make installSkipped 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 -deleteThe 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 -rfFinally, remove the temporary ‘tester’ user account created at the beginning of the previous chapter.
userdel -r testerChapter 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
EOF9.2.3 Hostname
echo "lfs-paul" > /etc/hostname9.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
EOF9.5 System Clock
systemctl disable systemd-timesyncd9.7 Locale
cat > /etc/locale.conf << "EOF"
LANG=EN_US.UTF-8
EOF9.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
EOF9.9 shells
cat > /etc/shells << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF9.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
EOFChapter 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
EOF10.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.210.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
EOF10.4 Grub
Powered off snapshot
mount /dev/sdb2 /bootgrub-install /dev/sdbcat > /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
}
EOFChapter 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"
EOFcat > /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