Bash script to build LFS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2476 lines
79 KiB

#!/usr/bin/env bash
cat > /tmp/lfsdev_sudo << EOF
lfsdev ALL = NOPASSWD: /usr/bin/chown * /mnt/lfsdev*
lfsdev ALL = NOPASSWD: /usr/bin/mount * /mnt/lfsdev*
lfsdev ALL = NOPASSWD: /usr/bin/install * /mnt/lfsdev*
lfsdev ALL = NOPASSWD: /usr/sbin/chroot /mnt/lfsdev*
EOF
add_lfsdev_user()
{
echo "4.3. Adding the lfsdev User"
echo "# groupadd lfsdev"
echo "# useradd -s /bin/bash -g lfsdev -m -k /dev/null lfsdev"
echo "# passwd lfsdev"
echo "And add sudo rights"
echo "# cp /tmp/lfsdev_sudo /etc/sudoers.d/lfsdev"
echo "Now connect as lfsdev and execute the script"
echo "$ su - lfsdev"
echo "$ cd <lfsdev build git repo>"
echo "$ bash build.sh"
}
if [ "$(whoami)" != "lfsdev" ]
then
echo "Please execute this script as user lfsdev"
grep -q lfsdev /etc/passwd || add_lfsdev_user
exit 1
fi
set -ueEo pipefail
export LFS=/mnt/lfsdev
# shellcheck source=/dev/null
if [ ! -e /home/lfsdev/.lfsdevbuild_config ]
then
cat > /home/lfsdev/.lfsdevbuild_config << EOSF
# location of local package sources
LFS_PACKAGE_DIR=/home/lfsdev/packages
# Number of processors to use
LFS_NPROC=$(nproc)
# Bypass step by step validation until a breakpoint
LFS_BREAKPOINT=1
# strip binaries or not
LFS_STRIP_BINARIES=true
# bypass network config validation by taking network config from host
LFS_NETWORKSAMEASHOST=false
# bypass network configuration for full offline build
LFS_NETWORKOFFLINE=false
# bypass linux config validation by taking linux config from host
LFS_LINUXCONFIGPROVIDED=false
EOSF
fi
# shellcheck source=/dev/null
source /home/lfsdev/.lfsdevbuild_config
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
LFS_PACKAGE_DIR=${LFS_PACKAGE_DIR:-/home/lfsdev/packages}
LFS_NPROC=${LFS_NPROC:-$(nproc)}
LFS_BREAKPOINT=${LFS_BREAKPOINT:-1}
LFS_STRIP_BINARIES=${LFS_STRIP_BINARIES:-false}
LFS_NETWORK=${LFS_NETWORKSAMEASHOST:-false}
LFS_OFFLINE=${LFS_NETWORKOFFLINE:-false}
LFS_LINUXCONFIG=${LFS_LINUXCONFIGPROVIDED:-false}
ask_for_exit()
{
echo "----- call ask_for_exit $1"
echo "find ${SCRIPT_DIR}/build/ \( -name \"*.sh\" -or -name \"*.txt\" \) -print |sort |grep --context=1 \$(cat ${HLFSB})"
find "${SCRIPT_DIR}/build/" \( -name "*.sh" -or -name "*.txt" \) -print |sort |grep --context=1 "$(cat "${HLFSB}")"
echo "ask_for_exit : args = $* && $1 < ${LFS_BREAKPOINT} (LFS_BREAKPOINT) || $1 < $(cat "${HLFSB}") (HLFSB) || ${LFS_BREAKPOINT} (LFS_BREAKPOINT) > $(cat "${HLFSB}") (HLFSB) "
if [[ $# -eq 1 ]] && [[ $1 -ge 10000 ]] && [[ $1 -lt 10000000 ]] && [[ $1 -lt ${LFS_BREAKPOINT} ]]
then
echo "LFS_BREAKPOINT : validation disabled"
return 0
elif [[ $# -eq 1 ]] && [[ $1 -ge 10000 ]] && [[ $1 -lt 10000000 ]] && [[ $1 -lt $(cat "${HLFSB}") ]]
then
echo "STEP_COUNTER : already done. validation disabled"
return 0
elif [[ $# -eq 1 ]] && [[ $1 -ge 10000 ]] && [[ $1 -lt 10000000 ]] && [[ ${LFS_BREAKPOINT} -gt $(cat "${HLFSB}") ]]
then
echo "LFS_BREAKPOINT : validation forced"
return 0
else
USER_ANSWER="?";
while [ "${USER_ANSWER}" != "n" ] && [ "${USER_ANSWER}" != "y" ] ; do
echo -n "Continue ? [y/n]"
read -r -n 1 USER_ANSWER
echo "";
done
if [ "$USER_ANSWER" == "n" ]
then
exit 0
fi
fi
}
ask_for_execution() {
USER_ANSWER="?";
while [ "${USER_ANSWER}" != "n" ] && [ "${USER_ANSWER}" != "y" ] && [ "${USER_ANSWER}" != "q" ]
do
echo -n "Execute ? [y/n/q]"
read -r -n 1 USER_ANSWER
echo "";
done
if [ "$USER_ANSWER" == "y" ]
then
return 0
elif [ "$USER_ANSWER" == "n" ]
then
return 1
elif [ "$USER_ANSWER" == "q" ]
then
exit 0
else
exit 0
fi
}
# 2.2
cat > /tmp/lfsdev_version-check.sh << "EOF"
#!/bin/bash
# A script to list version numbers of critical development tools
# If you have tools installed in other directories, adjust PATH here AND
# in ~lfsdev/.bashrc (section 4.4) as well.
LC_ALL=C
PATH=/usr/bin:/bin
bail() { echo "FATAL: $1"; exit 1; }
grep --version > /dev/null 2> /dev/null || bail "grep does not work"
sed '' /dev/null || bail "sed does not work"
sort /dev/null || bail "sort does not work"
ver_check()
{
if ! type -p $2 &>/dev/null
then
echo "ERROR: Cannot find $2 ($1)"; return 1;
fi
v=$($2 --version 2>&1 | grep -E -o '[0-9]+\.[0-9\.]+[a-z]*' | head -n1)
if printf '%s\n' $3 $v | sort --version-sort --check &>/dev/null
then
printf "OK: %-9s %-6s >= $3\n" "$1" "$v"; return 0;
else
printf "ERROR: %-9s is TOO OLD ($3 or later required)\n" "$1";
return 1;
fi
}
ver_kernel()
{
kver=$(uname -r | grep -E -o '^[0-9\.]+')
if printf '%s\n' $1 $kver | sort --version-sort --check &>/dev/null
then
printf "OK: Linux Kernel $kver >= $1\n"; return 0;
else
printf "ERROR: Linux Kernel ($kver) is TOO OLD ($1 or later required)\n" "$kver";
return 1;
fi
}
version_check()
{
# Coreutils first because --version-sort needs Coreutils >= 7.0
ver_check Coreutils sort 8.1 || bail "Coreutils too old, stop"
ver_check Bash bash 3.2
ver_check Binutils ld 2.13.1
ver_check Bison bison 2.7
ver_check Diffutils diff 2.8.1
ver_check Findutils find 4.2.31
ver_check Gawk gawk 4.0.1
ver_check GCC gcc 5.4
ver_check "GCC (C++)" g++ 5.4
ver_check Grep grep 2.5.1a
ver_check Gzip gzip 1.3.12
ver_check M4 m4 1.4.10
ver_check Make make 4.0
ver_check Patch patch 2.5.4
ver_check Perl perl 5.8.8
ver_check Python python3 3.4
ver_check Sed sed 4.1.5
ver_check Tar tar 1.22
ver_check Texinfo texi2any 5.0
ver_check Xz xz 5.0.0
ver_kernel 5.4
if mount | grep -q 'devpts on /dev/pts' && [ -e /dev/ptmx ]
then echo "OK: Linux Kernel supports UNIX 98 PTY";
else echo "ERROR: Linux Kernel does NOT support UNIX 98 PTY"; fi
alias_check() {
if $1 --version 2>&1 | grep -qi $2
then printf "OK: %-4s is $2\n" "$1";
else printf "ERROR: %-4s is NOT $2\n" "$1"; fi
}
echo "Aliases:"
alias_check awk GNU
alias_check yacc Bison
alias_check sh Bash
echo "Compiler check:"
if printf "int main(){}" | g++ -x c++ -o /tmp/lfsdev_a.out -
then echo "OK: g++ works";
else echo "ERROR: g++ does NOT work"; fi
rm -f /tmp/lfsdev_a.out
if [ "$(nproc)" = "" ]; then
echo "ERROR: nproc is not available or it produces empty output"
else
echo "OK: nproc reports $(nproc) logical cores are available"
fi
}
EOF
# shellcheck source=/dev/null
source /tmp/lfsdev_version-check.sh
# 2.6. Setting the $LFS Variable and the Umask
# 4.4. Setting Up the Environment
cat > ~/.bashrc << EOF
set +h
umask 022
export LFS=/mnt/lfsdev
export PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
export PATH=/mnt/lfsdev/tools/bin:$PATH:/usr/sbin
export CONFIG_SITE=$LFS/usr/share/config.site
export MAKEFLAGS=-j${LFS_NPROC}
export ARCH=$(uname -m)
export LC_ALL=POSIX
export LFS_VERSION=13.0
export LFS_CODENAME=lfsdev # change this to whatever you want
export LFS_KERNEL_VERSION=6.18.10
export LFS_TGT=$(uname -m)-lfsdev-linux-gnu
export LFS_ZONEINFO=$(realpath --relative-to=/usr/share/zoneinfo /etc/localtime)
export LFS_HOSTNAME=${LFS_HOSTNAME:-lfsdev} # change this to whatever you want
export SOURCES=$LFS/sources
export HLFSB=/home/lfsdev/lfsdev_build
export SLFSB=/mnt/lfsdev/sources/lfsdev_build
export RLFSB=/sources/lfsdev_build
export STEMP=/mnt/lfsdev/tmp
EOF
# shellcheck source=/dev/null
source ~/.bashrc
# cat > ~/.bash_profile << "EOF"
# exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
# EOF
## shellcheck source=/dev/null
# source ~/.bash_profile
cat > "${HOME}"/lfsdev_chroot.sh <<EOSF
if ! mount |grep -q "proc on /mnt/lfsdev/proc type proc"
then
echo "chroot is not available at this step"
exit 1
fi
sudo /usr/sbin/chroot $LFS /usr/bin/env -i \
HOME=/root \
TERM="${TERM}" \
PS1='(lfsdev chroot) \u:\w\$ ' \
PATH=/usr/bin:/usr/sbin \
LFS_NPROC=${LFS_NPROC} \
MAKEFLAGS="-j${LFS_NPROC}" \
TESTSUITEFLAGS="-j${LFS_NPROC}" \
/bin/bash --login
EOSF
describe()
{
case $1 in
acl)
echo "Acl : This package contains utilities to administer Access Control Lists, which are used to define fine-grained discretionary access rights for files and directories."
;;
attr)
echo "Attr : This package contains programs for managing extended attributes on file system objects."
;;
autoconf)
echo "Autoconf : This package supplies programs for producing shell scripts that can automatically configure source code from a developer's template. It is often needed to rebuild a package after the build procedure has been updated."
;;
automake)
echo "Automake : This package contains programs for generating Make files from a template. It is often needed to rebuild a package after the build procedure has been updated."
;;
bash)
echo "Bash : This package satisfies an LSB core requirement to provide a Bourne Shell interface to the system. It was chosen over other shell packages because of its common usage and extensive capabilities."
;;
bc)
echo "Bc : This package provides an arbitrary precision numeric processing language. It satisfies a requirement for building the Linux kernel."
;;
binutils)
echo "Binutils : This package supplies a linker, an assembler, and other tools for handling object files. The programs in this package are needed to compile most of the packages in an LFS system."
;;
bison)
echo "Bison : This package contains the GNU version of yacc (Yet Another Compiler Compiler) needed to build several of the LFS programs."
;;
bzip2)
echo "Bzip2 : This package contains programs for compressing and decompressing files. It is required to decompress many LFS packages."
;;
coreutils)
echo "Coreutils : This package contains a number of essential programs for viewing and manipulating files and directories. These programs are needed for command line file management, and are necessary for the installation procedures of every package in LFS."
;;
dbus)
echo "D-Bus : This package contains programs to implement a message bus system, a simple way for applications to talk to one another."
;;
dejagnu)
echo "DejaGNU : This package supplies a framework for testing other programs."
;;
diffutils)
echo "Diffutils : This package contains programs that show the differences between files or directories. These programs can be used to create patches, and are also used in many packages' build procedures."
;;
e2fsprogs)
echo "E2fsprogs : This package supplies utilities for handling the ext2, ext3 and ext4 file systems. These are the most common and thoroughly tested file systems that Linux supports."
;;
expat)
echo "Expat : This package yields a relatively small XML parsing library. It is required by the XML::Parser Perl module."
;;
expact)
echo "Expect : This package contains a program for carrying out scripted dialogues with other interactive programs. It is commonly used for testing other packages."
;;
file)
echo "File : This package contains a utility for determining the type of a given file or files. A few packages need it in their build scripts."
;;
findutils)
echo "Findutils : This package provides programs to find files in a file system. It is used in many packages' build scripts."
;;
flex)
echo "Flex : This package contains a utility for generating programs that recognize patterns in text. It is the GNU version of the lex (lexical analyzer) program. It is required to build several LFS packages."
;;
gawk)
echo "Gawk : This package supplies programs for manipulating text files. It is the GNU version of awk (Aho-Weinberg-Kernighan). It is used in many other packages' build scripts."
;;
gcc)
echo "GCC : This is the Gnu Compiler Collection. It contains the C and C++ compilers as well as several others not built by LFS."
;;
gdbm)
echo "GDBM : This package contains the GNU Database Manager library. It is used by one other LFS package, Man-DB."
;;
gettext)
echo "Gettext : This package provides utilities and libraries for the internationalization and localization of many packages."
;;
glibc)
echo "Glibc : This package contains the main C library. Linux programs will not run without it."
;;
gmp)
echo "GMP : This package supplies math libraries that provide useful functions for arbitrary precision arithmetic. It is needed to build GCC."
;;
gperf)
echo "Gperf : This package produces a program that generates a perfect hash function from a set of keys. It is required by Systemd."
;;
grep)
echo "Grep : This package contains programs for searching through files. These programs are used by most packages' build scripts."
;;
groff)
echo "Groff : This package contributes programs for processing and formatting text. One important function of these programs is to format man pages."
;;
grub)
echo "GRUB : This is the Grand Unified Boot Loader. It is the most flexible of several boot loaders available."
;;
gzip)
echo "Gzip : This package contains programs for compressing and decompressing files. It is needed to decompress many packages in LFS."
;;
iana-etc)
echo "Iana-etc : This package provides data for network services and protocols. It is needed to enable proper networking capabilities."
;;
inetutils)
echo "Inetutils : This package supplies programs for basic network administration."
;;
intltools)
echo "Intltool : This package contributes tools for extracting translatable strings from source files."
;;
iproute2)
echo "IProute2 : This package contains programs for basic and advanced IPv4 and IPv6 networking. It was chosen over the other common network tools package (net-tools) for its IPv6 capabilities."
;;
jinja2)
echo "Jinja2 : This package is a Python module for text templating. It's required to build Systemd."
;;
kbd)
echo "Kbd : This package produces key-table files, keyboard utilities for non-US keyboards, and a number of console fonts."
;;
kmod)
echo "Kmod : This package supplies programs needed to administer Linux kernel modules."
;;
less)
echo "Less : This package contains a very nice text file viewer that allows scrolling up or down when viewing a file. Many packages use it for paging the output."
;;
libpcap)
echo "Libcap : This package implements the userspace interfaces to the POSIX 1003.1e capabilities available in Linux kernels."
;;
libelf)
echo "Libelf : The elfutils project provides libraries and tools for ELF files and DWARF data. Most utilities in this package are available in other packages, but the library is needed to build the Linux kernel using the default (and most efficient) configuration."
;;
libffi)
echo "Libffi : This package implements a portable, high level programming interface to various calling conventions. Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. Libffi can be used in such programs to provide a bridge from the interpreter program to compiled code."
;;
libpipeline)
echo "Libpipeline : The Libpipeline package supplies a library for manipulating pipelines of subprocesses in a flexible and convenient way. It is required by the Man-DB package."
;;
libtool)
echo "Libtool : This package contains the GNU generic library support script. It wraps the complexity of using shared libraries into a consistent, portable interface. It is needed by the test suites in other LFS packages."
;;
libxcrypt)
echo "Libxcrypt : This package provides the libcrypt library needed by various packages (notably, Shadow) for hashing passwords. It replaces the obsolete libcrypt implementation in Glibc."
;;
linux)
echo "Linux Kernel : This package is the Operating System. It is the Linux in the GNU/Linux environment."
;;
m4)
echo "M4 : This package provides a general text macro processor useful as a build tool for other programs."
;;
make)
echo "Make : This package contains a program for directing the building of packages. It is required by almost every package in LFS."
;;
markupsafe)
echo "MarkupSafe : This package is a Python module for processing strings in HTML/XHTML/XML safely. Jinja2 requires this package."
;;
mandb)
echo "Man-DB : This package contains programs for finding and viewing man pages. It was chosen instead of the man package because of its superior internationalization capabilities. It supplies the man program."
;;
man-pages)
echo "Man-pages: This package provides the actual contents of the basic Linux man pages."
;;
meson)
echo "Meson : This package provides a software tool for automating the building of software. The main goal of Meson is to minimize the amount of time that software developers need to spend configuring a build system. It's required to build Systemd, as well as many BLFS packages."
;;
mpc)
echo "MPC : This package supplies arithmetic functions for complex numbers. It is required by GCC."
;;
mpfr)
echo "MPFR : This package contains functions for multiple precision arithmetic. It is required by GCC."
;;
ninja)
echo "Ninja : This package furnishes a small build system with a focus on speed. It is designed to have its input files generated by a higher-level build system, and to run builds as fast as possible. This package is required by Meson."
;;
ncurses)
echo "Ncurses : This package contains libraries for terminal-independent handling of character screens. It is often used to provide cursor control for a menuing system. It is needed by a number of the packages in LFS."
;;
openssl)
echo "Openssl : This package provides management tools and libraries relating to cryptography. These supply cryptographic functions to other packages, including the Linux kernel."
;;
patch)
echo "Patch : This package contains a program for modifying or creating files by applying a patch file typically created by the diff program. It is needed by the build procedure for several LFS packages."
;;
pcre2)
echo "Pcre2 : This package provides a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5."
;;
perl)
echo "Perl : This package is an interpreter for the runtime language PERL. It is needed for the installation and test suites of several LFS packages."
;;
pkgconf)
echo "Pkgconf : This package contains a program which helps to configure compiler and linker flags for development libraries. The program can be used as a drop-in replacement of pkg-config, which is needed by the building system of many packages. It's maintained more actively and slightly faster than the original Pkg-config package."
;;
procps)
echo "Procps-NG : This package contains programs for monitoring processes. These programs are useful for system administration, and are also used by the LFS Bootscripts."
;;
psmisc)
echo "Psmisc : This package produces programs for displaying information about running processes. These programs are useful for system administration."
;;
Python)
echo "Python 3 : This package provides an interpreted language that has a design philosophy emphasizing code readability."
;;
readline)
echo "Readline : This package is a set of libraries that offer command-line editing and history capabilities. It is used by Bash."
;;
sed)
echo "Sed : This package allows editing of text without opening it in a text editor. It is also needed by many LFS packages' configure scripts."
;;
shadow)
echo "Shadow : This package contains programs for handling passwords securely."
;;
sqlite)
echo "Sqlite : This package provides a serverless, zero-configuration, transactional SQL database engine."
;;
systemd)
echo "Systemd : This package provides an init program and several additional boot and system control capabilities as an alternative to SysVinit. It is used by many Linux distributions."
;;
tar)
echo "Tar : This package provides archiving and extraction capabilities of virtually all the packages used in LFS."
;;
tcl)
echo "Tcl : This package contains the Tool Command Language used in many test suites."
;;
texinfo)
echo "Texinfo : This package supplies programs for reading, writing, and converting info pages. It is used in the installation procedures of many LFS packages."
;;
util-linux)
echo "Util-linux : This package contains miscellaneous utility programs. Among them are utilities for handling file systems, consoles, partitions, and messages."
;;
vim)
echo "Vim : This package provides an editor. It was chosen because of its compatibility with the classic vi editor and its huge number of powerful capabilities. An editor is a very personal choice for many users. Any other editor can be substituted, if you wish."
;;
wheel)
echo "Wheel : This package supplies a Python module that is the reference implementation of the Python wheel packaging standard."
;;
xmlparser)
echo "XML::Parser : This package is a Perl module that interfaces with Expat."
;;
xz)
echo "XZ Utils : This package contains programs for compressing and decompressing files. It provides the highest compression generally available and is useful for decompressing packages in XZ or LZMA format."
;;
zlib)
echo "Zlib : This package contains compression and decompression routines used by some programs."
0 ;;
zstd)
echo "Zstd : This package supplies compression and decompression routines used by some programs. It provides high compression ratios and a very wide range of compression / speed trade-offs."
;;
*)
echo "Unknown package"
exit 1
;;
esac
}
check_installed()
{
chapter=$1
package=$2
check()
{
proof=$1
echo "$ find ${LFS}/usr -name ${proof} (${package})"
if [ ! -e ${LFS}/"${proof}" ]
then
echo "FAILED: ${proof} not found"
describe "${package}"
exit 1
fi
}
case ${package} in
acl)
check /usr/lib/libacl.so.1.1.2302
;;
attr)
check /usr/lib/libattr.so.1.1.2502
;;
autoconf)
check /usr/bin/autoconf
;;
automake)
check /usr/bin/automake-1.18
;;
bash)
check /usr/bin/bash
check /usr/lib/bash/truefalse
;;
bc)
check /usr/bin/bc
;;
binutils)
check /usr/bin/strings
;;
bison)
check /usr/bin/bison
;;
bzip2)
check /usr/lib/libbz2.so.1.0.8
;;
coreutils)
check /usr/sbin/chroot
;;
dbus)
check /usr/lib/libdbus-1.so.3.38.3
;;
dejagnu)
check /usr/bin/dejagnu
;;
diffutils)
check /usr/bin/diff3
;;
elfutils)
check /usr/lib/libelf-0.194.so
;;
expat)
check /usr/lib/libexpat.so.1.11.2
;;
expect)
check /usr/lib/expect5.45.4/libexpect5.45.4.so
;;
e2fsprogs)
check /usr/sbin/mkfs.ext4
;;
file)
check /usr/bin/file
check /usr/lib/libmagic.so.1.0.0
;;
findutils)
check /usr/bin/updatedb
;;
flex)
check /usr/bin/flex
;;
flit)
check /usr/lib/python3.14/site-packages/flit_core/config.py
;;
gawk)
check /usr/bin/gawk
check /usr/lib/gawk/fnmatch.so
;;
gdbm)
check /usr/lib/libgdbm.so.6.0.0
;;
gcc)
case "${chapter}" in
6)
check /usr/bin/gcc
check /usr/lib/libgcc_s.so.1
;;
8)
check /usr/lib/libcc1.so.0.0.0
;;
esac
;;
gettext)
case "${chapter}" in
7)
check /usr/bin/xgettext
;;
8)
check /usr/lib/libgettextlib-1.0.so
;;
esac
;;
glibc)
check /usr/lib/libc.so.6
;;
gmp)
check /usr/lib/libgmp.so.10.5.0
;;
gperf)
check /usr/bin/gperf
;;
gprof)
check /usr/lib/libgprofng.so.0.0.0
;;
grep)
check /usr/bin/egrep
;;
groff)
check /usr/bin/groff
;;
grub)
check /usr/lib/grub/i386-pc/linux.module
check /usr/sbin/grub-probe
;;
gzip)
check /usr/bin/gunzip
;;
iana-etc)
check /etc/services
;;
inetutils)
check /usr/bin/traceroute
;;
intltool)
check /usr/bin/intltoolize
;;
iproute2)
check /usr/sbin/ip
check /usr/sbin/ss
;;
jinja2)
check /usr/lib/python3.14/site-packages/jinja2/utils.py
;;
kbd)
check /usr/bin/kbdinfo
;;
kmod)
check /usr/lib/libkmod.so.2.5.1
;;
less)
check /usr/bin/lessecho
;;
libffi)
check /usr/lib/libffi.so.8.2.0
;;
libcap)
check /usr/lib/libcap.so.2.77
;;
libpipeline)
check /usr/lib/libpipeline.so.1.5.8
;;
libtool)
check /usr/lib/libltdl.so.7.3.3
;;
libxcrypt)
check /usr/lib/libcrypt.so.2.0.0
;;
lz4)
check /usr/lib/liblz4.so.1.10.0
;;
make)
check /usr/bin/make
;;
man-db)
check /usr/sbin/accessdb
;;
man-pages)
check /usr/bin/pdfman
;;
markupsafe)
check /usr/lib/python3.14/site-packages/markupsafe/py.typed
;;
meson)
check /usr/lib/python3.14/site-packages/mesonbuild/mesonlib.py
;;
mpc)
check /usr/lib/libmpc.so.3.3.1
;;
mpfr)
check /usr/lib/libmpfr.so.6.2.2
;;
m4)
check /usr/bin/m4
;;
ncurses)
check /usr/bin/ncursesw6-config
check /usr/lib/libncursesw.so.6.6
;;
ninja)
check /usr/bin/ninja
;;
openssl)
check /usr/lib/libssl.so.3
;;
packaging)
check /usr/lib/python3.14/site-packages/packaging/requirements.py
;;
patch)
check /usr/bin/patch
;;
pcre2)
check /usr/lib/libpcre2-posix.so.3.0.7
;;
perl)
check /usr/bin/perl
check /usr/bin/perlbug
;;
pkgconf)
check /usr/lib/libpkgconf.so.7.0.0
;;
procps)
check /usr/sbin/sysctl
;;
psmisc)
check /usr/bin/pstree
;;
Python)
case "${chapter}" in
7)
check /usr/bin/python3.14
;;
8)
check /usr/lib/libpython3.14.so.1.0
;;
esac
;;
readline)
check /usr/lib/libreadline.so.8.3
;;
sed)
check /usr/bin/sed
;;
setuptools)
check /usr/lib/python3.14/site-packages/setuptools/installer.py
;;
shadow)
check /usr/lib/libsubid.so.5.0.0
;;
sqlite-autoconf)
check /usr/lib/libsqlite3.so.3.51.2
;;
systemd)
check /usr/lib/libsystemd.so.0.42.0
;;
tar)
check /usr/bin/tar
;;
tcl8.6.17-src)
check /usr/lib/libtcl8.6.so
;;
texinfo)
check /usr/bin/texi2any
;;
util-linux)
check /usr/bin/renice
check /usr/sbin/agetty
;;
vim)
check /usr/bin/vimtutor
;;
wheel)
check /usr/lib/python3.14/site-packages/wheel/wheelfile.py
;;
xz)
check /usr/bin/xzdiff
check /usr/bin/xzless
;;
XML-Parser)
check /usr/lib/perl5/5.42/site_perl/XML/Parser/Expat.pm
;;
zlib)
check /usr/lib/libz.so.1.3.2
;;
zstd)
check /usr/lib/libzstd.so.1.5.7
;;
*)
echo "Unkwnown package : ${package}"
exit 1
;;
esac
}
check_installed5()
{
check_installed 5 "$1"
}
check_installed6()
{
check_installed 6 "$1"
}
check_installed7()
{
check_installed 7 "$1"
}
check_installed8()
{
check_installed 8 "$1"
}
check_sources()
{
echo "call check_sources"
while IFS= read -r line
do
echo "Line: $line"
local packagefilename=${line##*/}
echo "${packagefilename}"
[ -d "${LFS_PACKAGE_DIR}" ] && mkdir -v "${LFS_PACKAGE_DIR}"
pushd "${LFS_PACKAGE_DIR}"
md5sum --check "${SCRIPT_DIR}/md5sums"
ret=$?
popd
return ${ret}
done < "${SCRIPT_DIR}/wget-list-systemd.txt"
}
check_download()
{
echo "call check_download"
wget --input-file=wget-list-systemd.txt --continue --directory-prefix="${LFS_PACKAGE_DIR}"
ret=$?
return ${ret}
}
check_errors()
{
echo "call check_errors $1"
if [[ $# -ne 1 ]]
then
echo "bad argument in function call"
return 1
fi
logfile=$1
if grep "Permission denied" "${logfile}"
then
echo "Rights error"
exit 1
fi
if grep "configure: error" "${logfile}"
then
echo "Configure Error"
cat "${buildpath}"/config.log
exit 1
fi
if grep "^make: .* Error .*$" "${logfile}"
then
echo "Make Error"
exit 1
fi
}
copy_sources()
{
mkdir --verbose ${LFS}/sources
echo "call copy_sources"
echo cp --verbose "${LFS_PACKAGE_DIR}"/* ${LFS}/sources/
if cp --verbose "${LFS_PACKAGE_DIR}"/* ${LFS}/sources/
then
return 0
else
return 1
fi
}
copy_scripts()
{
echo "call copy_scripts"
echo cp --verbose "${SCRIPT_DIR}"/build/* ${LFS}/sources/
if cp --verbose "${SCRIPT_DIR}"/build/* ${LFS}/sources/
then
return 0
else
return 1
fi
}
create_directories()
{
echo "call create_directories"
echo "sudo operation : /usr/bin/chown lfsdev:root $LFS"
sudo /usr/bin/chown lfsdev:root $LFS || return 1
mkdir --parents --verbose $LFS/{etc,var,tools,dev,proc,sys,run} $LFS/usr/{bin,lib,sbin}
pushd $LFS
for i in bin lib sbin; do
ln --symbolic --verbose usr/$i $LFS/$i
done
popd
case $(uname -m) in
x86_64) mkdir -pv $LFS/lib64 ;;
esac
return 0
}
cross_toolchain()
{
echo "call cross_toolchain $1"
if [[ $# -ne 1 ]]
then
echo "bad argument in function call"
return 1
fi
section=$1
for package in $(find "${SOURCES}" -name "[${section}][0-9][0-9][0-9][0-9]_*.sh" -print | sort)
do
scriptname=$(basename "${package}")
step=${scriptname%%_*}
echo "Test if $(cat "${SLFSB}") -ge ${step}"
if [[ $(cat "${SLFSB}") -ge ${step} ]]
then
echo "${scriptname} already done"
echo "Test : $(cat "${SLFSB}") < ${step} ;"
ask_for_exit "${step}"
continue
fi
unnumbered=${scriptname##*_}
packagename=${unnumbered%.*}
echo "pkkname: ${packagename}"
if find "${SOURCES}" -name "${packagename}*.tar.*" -print
then
archivepath=$(find "${SOURCES}" -name "${packagename}*.tar.*" -print)
else
echo "There is no archive with this name !!!"
exit 1
fi
echo "archpath: ${archivepath}"
archivename=$(basename "${archivepath}")
echo "archname: ${archivename}"
buildpath="$SOURCES/${packagename}"
if [ -d "${buildpath}" ]
then
rm --recursive --verbose --force "${buildpath}"
mkdir "${buildpath}"
else
mkdir "${buildpath}"
fi
if [ ! -e "${buildpath}"/COPYING ]
then
tar --extract --file="${archivepath}" --directory="${buildpath}" --strip-components=1
fi
pushd "${buildpath}"
set -ueExo pipefail
if ! eval "$(cat ../"${scriptname}")" | tee "/tmp/lfsdev_${step}.log"
then
echo "compilation error"
exit 1
else
echo "compilation ok"
cp -v "/tmp/lfsdev_${step}.log" "${HOME}"
fi
popd
set -ueEo pipefail
check_errors "/tmp/lfsdev_${step}.log"
rm --recursive --verbose --force "${buildpath}"
echo "${step}" > "${SLFSB}"
ask_for_exit "${step}"
done
return 0
}
building_temporary_tools()
{
echo "call building_temporary_tools $1"
if [[ $# -ne 1 ]]
then
echo "bad argument in function call"
return 1
fi
section=$1
for package in $(find "${SOURCES}" -name "[${section}][0-9][0-9][0-9][0-9]_*.sh" -print | sort)
do
scriptname=$(basename "${package}")
step=${scriptname%%_*}
echo "Test if $(cat "${SLFSB}") -ge ${step}"
if [[ $(cat "${SLFSB}") -ge ${step} ]]
then
echo "${scriptname} already done"
continue
fi
unnumbered=${scriptname##*_}
packagename=${unnumbered%.*}
echo "pkgname: ${packagename}"
if find "${SOURCES}" -name "${packagename}*.tar.*" -print
then
archivepath=$(find "${SOURCES}" -name "${packagename}*.tar.*" -print)
echo "archpath: ${archivepath}"
archivesubpath=${archivepath##/mnt/lfsdev}
echo "archivesubpath: ${archivesubpath}"
archivename=$(basename "${archivepath}")
echo "archname: ${archivename}"
buildpath=/sources/"${packagename}"
else
echo "There is no archive with this name !!!"
exit 1
fi
sudofile=/tmp/lfsdev_${step}.sh
cat > "${sudofile}" << EOSF
if [ -d "${buildpath}" ]
then
rm -r "${buildpath}"
mkdir -p "${buildpath}"
else
mkdir -p "${buildpath}"
fi
if [ ! -e "${buildpath}"/COPYING ]
then
tar -xf "${archivesubpath}" -C "${buildpath}" --strip-components=1
fi
pushd "${buildpath}"
set -ueExo pipefail
eval "\$(cat ../"${scriptname}")" | tee "/tmp/lfsdev_${step}.log"
popd
rm -rf "${buildpath}"
set -ueEo pipefail
EOSF
if ! lfsdev_chroot "${sudofile}"
then
echo "compilation error"
exit 1
else
echo "compilation ok"
fi
check_errors "${STEMP}/lfsdev_${step}.log"
echo "${step}" > "${SLFSB}"
cp -v "${STEMP}/lfsdev_${step}.log" "${HOME}"
ask_for_exit "${step}"
done
}
check_virtual_kernel_filesystems()
{
echo "call check_virtual_kernel_filesystems"
if mount |grep -q "udev on /mnt/lfsdev/dev type devtmpfs" && \
mount |grep -q "devpts on /mnt/lfsdev/dev/pts type devpts" && \
mount |grep -q "proc on /mnt/lfsdev/proc type proc" && \
mount |grep -q "sysfs on /mnt/lfsdev/sys type sysfs" && \
mount |grep -q "tmpfs on /mnt/lfsdev/run type tmpfs" && \
mount |grep -q "tmpfs on /mnt/lfsdev/dev/shm type tmpfs"
then
echo "Ok, Filesystems are ready for chroot"
return 0
else
echo "7.3. Preparing Virtual Kernel File Systems"
echo "Warning : Not ready for chroot !!!"
return 1
fi
}
mount_virtual_kernel_filesystem()
{
echo "call mount_virtual_kernel_filesystem"
echo "sudo operation : mount dev sys proc sys run /dev/shm"
echo /usr/bin/mount -v --bind /dev $LFS/dev || return 1
sudo /usr/bin/mount -v --bind /dev $LFS/dev || return 1
echo /usr/bin/mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts || return 1
sudo /usr/bin/mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts || return 1
echo /usr/bin/mount -vt proc proc $LFS/proc || return 1
sudo /usr/bin/mount -vt proc proc $LFS/proc || return 1
echo /usr/bin/mount -vt sysfs sysfs $LFS/sys || return 1
sudo /usr/bin/mount -vt sysfs sysfs $LFS/sys || return 1
echo /usr/bin/mount -vt tmpfs tmpfs $LFS/run || return 1
sudo /usr/bin/mount -vt tmpfs tmpfs $LFS/run || return 1
echo "Content of $LFS/dev :"
ls -l $LFS/dev/
echo "Content of $LFS/dev/shm :"
ls -l $LFS/dev/shm
if [ -h $LFS/dev/shm ]
then
echo /usr/bin/install -v -d -m 1777 $LFS"$(realpath /dev/shm)" || return 1
sudo /usr/bin/install -v -d -m 1777 $LFS"$(realpath /dev/shm)" || return 1
else
echo /usr/bin/mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm || return 1
sudo /usr/bin/mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm || return 1
fi
return 0
}
lfsdev_chroot()
{
echo "call lfsdev_chroot $1"
CHROOTFILE=$1
sed "1iif [[ ! \"\${UID\}\" -eq 0 ]] && [ ! -e ${CHROOTFILE} ] && [ -e /sources/lfsdev_build ]" -i "${CHROOTFILE}"
sed "2ithen" -i "${CHROOTFILE}"
sed "3iecho \"bad chroot\"" -i "${CHROOTFILE}"
sed "4iexit 1" -i "${CHROOTFILE}"
sed "5ielse" -i "${CHROOTFILE}"
sed "\$afi" -i "${CHROOTFILE}"
if cat "${CHROOTFILE}" | sudo /usr/sbin/chroot "$LFS" /usr/bin/env -i \
HOME=/root \
TERM="$TERM" \
PS1='(lfsdev chroot) \u:\w\$ ' \
PATH=/usr/bin:/usr/sbin \
LFS_NPROC="${LFS_NPROC}" \
MAKEFLAGS="-j${LFS_NPROC}" \
TESTSUITEFLAGS="-j${LFS_NPROC}" \
/bin/bash
then
echo "command succeed"
return 0
else
return 1
fi
}
main() {
cd "$SCRIPT_DIR"
if [ ! -d "$LFS/sources" ]
then
rm --force --verbose "${HLFSB}"
echo "10000" > "${HLFSB}"
fi
### CHECK LOCAL HOST ###
echo "2.2 Host System Requirements"
if [[ $(cat "${HLFSB}") -lt 22000 ]]
then
set +e
version_check | tee /tmp/lfsdev_version_check.log
echo "=== Check for errors ==="
grep ERROR /tmp/lfsdev_version_check.log && exit 1
if [ -e /etc/bash.bashrc ]
then
echo "Please disable /etc/bash.bashrc for compilation"
echo "# mv -v /etc/bash.bashrc /etc/bash.bashrc.NOUSE"
exit 1
fi
echo "22000" > "${HLFSB}"
fi
echo "2.7. Mounting the New Partition"
if ! mount |grep -q "/mnt/lfsdev type ext4"
then
echo "2.4. Creating a New Partition"
echo "2.5. Creating a File System on the Partition"
echo "2.7. Mounting the New Partition"
echo "You have to mount a ext4 partition under /mnt/lfsdev"
echo "Think to create a swap partition on the target device"
exit 1
fi
if [ "${LFS}" != "/mnt/lfsdev" ]
then
echo "2.6. Setting the \$LFS Variable and the Umask"
echo "LFS is not /mnt/lfsdev"
exit 1
fi
ask_for_exit 27000
### DOWNLOAD PACKAGES ###
echo "3.2. All Packages"
if [[ $(cat "${HLFSB}") -lt 31000 ]]
then
if ! check_sources
then
echo "3.1. Introduction"
echo "3.2. All Packages"
echo "Some package are missing"
if ! download
then
echo "3.1. Introduction"
echo "Some package are unavailable"
echo "Try manually"
exit 1
fi
else
echo "31000" > "${HLFSB}"
fi
fi
if [[ $(cat "${HLFSB}") -lt 32000 ]]
then
if ! check_sources
then
echo "3.1. Introduction"
echo "Some package are unavailable"
echo "Fix it manually"
exit 1
else
echo "32000" > "${HLFSB}"
fi
fi
ask_for_exit 42000
### PREPARE LFS DIRECTORIES ###
echo "4.2. Creating a Limited Directory Layout in the LFS Filesystem"
if [[ $(cat "${HLFSB}") -lt 42000 ]] && [ ! -e "${SLFSB}" ]
then
if [ ! -d "$LFS/tools" ]
then
echo "Time to create some directories on $LFS"
if create_directories
then
echo "42000" > "${HLFSB}"
else
echo "4.2. Creating a Limited Directory Layout in the LFS Filesystem"
echo "III. Building the LFS Cross Toolchain and Temporary Tools"
echo "Failed to create directories on $LFS"
echo "The user lfsdev has not sufficient rights"
echo "If not, you can fix it manually"
echo "Or the file /tmp/lfsdev_sudo may be copied under /etc/sudoers.d/lfsdev"
echo "And execute the following command as root to valide syntax"
echo "# visudo /etc/sudoers.d/lfsdev"
exit 1
fi
else
echo "42000" > "${HLFSB}"
fi
fi
echo "4.7. Copy sources"
if [[ $(cat "${HLFSB}") -lt 47000 ]]
then
if ! copy_sources
then
echo "3.1. Introduction"
echo "Copy packages to sources failed"
exit 1
else
echo "47000" > "${HLFSB}"
fi
fi
ask_for_exit 48000
echo "4.8. Copy scripts"
if [[ $(cat "${HLFSB}") -lt 48000 ]]
then
if ! copy_scripts
then
echo "5. Compiling a Cross-Toolchain"
echo "Copy scripts to sources failed"
exit 1
else
if [[ ! $(du /mnt/lfsdev/sources/ |cut -f 1) -gt 500000 ]]
then
echo "check /mnt/lfsdev/sources content failed"
exit 1
fi
echo "48000" > "${HLFSB}"
fi
fi
#########################################
### Begin to follow steps on target #####
#########################################
if [ ! -e "${SLFSB}" ]
then
echo "Initialize lfsdev_build on /mnt/lfsdev"
echo "48000" > "${SLFSB}"
rm --force --verbose "${HLFSB}"
ln --symbolic --force --verbose "${SLFSB}" "${HLFSB}"
fi
ask_for_exit 50000
### CROSS TOOLCHAIN ###
echo "5. Compiling a Cross-Toolchain"
if [[ $(cat "${SLFSB}") -lt 52500 ]]
then
echo "Chapter 5. Compiling a Cross-Toolchain"
if cross_toolchain 5
then
echo "52500" > "${SLFSB}"
else
echo "Cross Toolchain Failure"
exit 1
fi
fi
if [[ $(cat "${SLFSB}") -gt 50000 ]] && [[ $(cat "${SLFSB}") -lt 71310 ]]
then
case $(uname -m) in
x86_64)
if [ ! -e /mnt/lfsdev/tools/x86_64-lfsdev-linux-gnu/bin/ld ] || \
[ ! -e /mnt/lfsdev/tools/bin/x86_64-lfsdev-linux-gnu-gcc ] || \
[ ! -e /mnt/lfsdev/usr/include/asm/fcntl.h ] || \
[ ! -e /mnt/lfsdev/usr/sbin/ldconfig ] || \
[ ! -e /mnt/lfsdev/usr/lib/libstdc++.so.6.0.34 ]
then
echo "Some binaries are missing from cross_toolchain 5xxxx"
exit 1
fi
;;
i686)
if [ ! -e /mnt/lfsdev/tools/bin/i686-lfsdev-linux-gnu-ld ] || \
[ ! -e /mnt/lfsdev/tools/bin/i686-lfsdev-linux-gnu-gcc ] || \
[ ! -e /mnt/lfsdev/usr/include/asm/fcntl.h ] || \
[ ! -e /mnt/lfsdev/usr/sbin/ldconfig ] || \
[ ! -e /mnt/lfsdev/usr/lib/libstdc++.so.6.0.34 ]
then
echo "Some binaries are missing from cross_toolchain 5xxxx"
exit 1
fi
;;
*)
echo "Architecture $(uname -m) is not supported"
;;
esac
fi
ask_for_exit 60000
### CROSS TOOLCHAIN ###
echo "6. Cross Compiling Temporary Tools"
if [[ $(cat "${SLFSB}") -lt 61810 ]]
then
echo "Chapter 5. Compiling a Cross-Toolchain"
if cross_toolchain 6
then
echo "61810" > "${SLFSB}"
fi
fi
if [[ $(cat "${SLFSB}") -gt 50000 ]] && [[ $(cat "${SLFSB}") -lt 90000 ]]
then
check_installed6 m4
check_installed6 ncurses
check_installed6 bash
check_installed6 coreutils
check_installed6 diffutils
check_installed6 file
check_installed6 findutils
check_installed6 gawk
check_installed6 grep
check_installed6 gzip
check_installed6 make
check_installed6 patch
check_installed6 sed
check_installed6 tar
check_installed6 xz
check_installed6 binutils
check_installed6 gcc
fi
ask_for_exit 70200
### PREPARE CHROOT ###
echo "7.2. Changing Ownership"
if [[ $(cat "${SLFSB}") -lt 70200 ]]
then
echo "Preparing for chroot step."
echo "/mnt/lfsdev will be closed for chroot"
echo "Do you validate preceding steps ?"
if ask_for_exit 61810
then
case $(uname -m) in
x86_64)
if ! sudo /usr/bin/chown -R root:root $LFS/lib64
then
echo "Rights error"
exit 1
fi
;;
esac
if sudo /usr/bin/chown -R root:root $LFS/{usr,var,etc,tools}
then
sudo /usr/bin/chown lfsdev "${SLFSB}" || exit 1
echo "70200" > "${SLFSB}"
else
echo "Rights error"
exit 1
fi
fi
fi
ask_for_exit 61810
echo "7.3. Preparing Virtual Kernel File Systems"
if [[ $(cat "${SLFSB}") -ge 70200 ]]
then
if ! check_virtual_kernel_filesystems
then
if ! mount_virtual_kernel_filesystem
then
echo "7.3. Preparing Virtual Kernel File Systems"
echo "Mount failure. Please fix it!"
exit 1
fi
if ! check_virtual_kernel_filesystems
then
echo "7.3. Preparing Virtual Kernel File Systems"
echo "Mount failure. Please fix it!"
exit 1
fi
fi
fi
ask_for_exit 61810
### CHROOT FIRST CONFIGURATION ###
echo "7.5. Creating Directories"
if [[ $(cat "${SLFSB}") -lt 70500 ]]
then
sudofile=/tmp/lfsdev_70500.sh
cat > ${sudofile} << "EOSF"
mkdir -pv /{boot,home,mnt,opt,srv}
mkdir -pv /etc/{opt,sysconfig}
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{include,src}
mkdir -pv /usr/lib/locale
mkdir -pv /usr/local/{bin,lib,sbin}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}
ln -sfv /run /var/run
ln -sfv /run/lock /var/lock
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "70500" > "${SLFSB}"
fi
fi
ask_for_exit 61810
echo "7.6. Creating Essential Files and Symlinks"
if [[ $(cat "${SLFSB}") -lt 70600 ]]
then
sudofile=/tmp/lfsdev_70600.sh
cat > ${sudofile} << "EOSF"
ln -sv /proc/self/mounts /etc/mtab
cat > /etc/hosts << EOF
127.0.0.1 localhost $(hostname)
::1 localhost
EOF
cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/usr/bin/false
systemd-journal-remote:x:74:74:systemd Journal Remote:/:/usr/bin/false
systemd-journal-upload:x:75:75:systemd Journal Upload:/:/usr/bin/false
systemd-network:x:76:76:systemd Network Management:/:/usr/bin/false
systemd-resolve:x:77:77:systemd Resolver:/:/usr/bin/false
systemd-timesync:x:78:78:systemd Time Synchronization:/:/usr/bin/false
systemd-coredump:x:79:79:systemd Core Dumper:/:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
systemd-oom:x:81:81:systemd Out Of Memory Daemon:/:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF
cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
clock:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
kvm:x:61:
systemd-journal-gateway:x:73:
systemd-journal-remote:x:74:
systemd-journal-upload:x:75:
systemd-network:x:76:
systemd-resolve:x:77:
systemd-timesync:x:78:
systemd-coredump:x:79:
uuidd:x:80:
systemd-oom:x:81:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF
echo "tester:x:101:101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester
touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "70600" > "${SLFSB}"
fi
fi
ask_for_exit 61810
### CHROOT COMPILATION ###
echo "7.7 Building Additional Temporary Tools"
if [[ $(cat "${SLFSB}") -lt 71300 ]]
then
if building_temporary_tools 7
then
echo "71210" > "${SLFSB}"
fi
fi
if [[ $(cat "${SLFSB}") -gt 70700 ]] && [[ $(cat "${SLFSB}") -lt 90000 ]]
then
check_installed7 gettext
check_installed7 bison
check_installed7 perl
check_installed7 Python
check_installed7 texinfo
check_installed7 util-linux
fi
ask_for_exit 71210
echo "7.13. Cleaning up and Saving the Temporary System"
if [[ $(cat "${SLFSB}") -lt 71310 ]]
then
sudofile=/tmp/lfsdev_71310.sh
cat > ${sudofile} << "EOSF"
rm -rf /usr/share/{info,man,doc}/*
find /usr/{lib,libexec} -name \*.la -delete
# rm -rf /tools
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "71310" > "${SLFSB}"
fi
fi
ask_for_exit 71310
echo "8. Installing Basic System Software"
if [[ $(cat "${SLFSB}") -lt 88410 ]]
then
# Fix timezone for glibc with the same timezone as build computer
sed "sqAmerica/New_Yorkq$(realpath --relative-to=/usr/share/zoneinfo /etc/localtime)q" -i "$SOURCES"/80510_glibc.sh
if building_temporary_tools 8
then
echo "88310" > "${SLFSB}"
fi
fi
if [[ $(cat "${SLFSB}") -gt 70700 ]] && [[ $(cat "${SLFSB}") -lt 90000 ]]
then
check_installed8 man-pages
check_installed8 iana-etc
check_installed8 glibc
check_installed8 zlib
check_installed8 bzip2
check_installed8 xz
check_installed8 lz4
check_installed8 zstd
check_installed8 file
check_installed8 readline
check_installed8 pcre2
check_installed8 m4
check_installed8 bc
check_installed8 flex
check_installed8 tcl8.6.17-src
check_installed8 expect
check_installed8 dejagnu
check_installed8 pkgconf
check_installed8 gprof
check_installed8 gmp
check_installed8 mpfr
check_installed8 mpc
check_installed8 attr
check_installed8 acl
check_installed8 libcap
check_installed8 libxcrypt
check_installed8 shadow
check_installed8 gcc
check_installed8 ncurses
check_installed8 sed
check_installed8 psmisc
check_installed8 gettext
check_installed8 bison
check_installed8 grep
check_installed8 bash
check_installed8 libtool
check_installed8 gdbm
check_installed8 gperf
check_installed8 expat
check_installed8 inetutils
check_installed8 less
check_installed8 perl
check_installed8 XML-Parser
check_installed8 intltool
check_installed8 autoconf
check_installed8 automake
check_installed8 openssl
check_installed8 elfutils
check_installed8 libffi
check_installed8 sqlite-autoconf
check_installed8 Python
check_installed8 flit
check_installed8 packaging
check_installed8 wheel
check_installed8 setuptools
check_installed8 ninja
check_installed8 meson
check_installed8 kmod
check_installed8 coreutils
check_installed8 diffutils
check_installed8 gawk
check_installed8 findutils
check_installed8 groff
check_installed8 grub
check_installed8 gzip
check_installed8 iproute2
check_installed8 kbd
check_installed8 libpipeline
check_installed8 make
check_installed8 patch
check_installed8 tar
check_installed8 texinfo
check_installed8 vim
check_installed8 markupsafe
check_installed8 jinja2
check_installed8 systemd
check_installed8 dbus
check_installed8 man-db
check_installed8 procps
check_installed8 util-linux
check_installed8 e2fsprogs
fi
ask_for_exit 88510
echo "8.85. Stripping"
if [[ $(cat "${SLFSB}") -lt 88510 ]]
then
sudofile=/tmp/lfsdev_88510.sh
cat > ${sudofile} << "EOSF"
save_usrlib="$(cd /usr/lib; ls ld-linux*[^g])
libc.so.6
libthread_db.so.1
libquadmath.so.0.0.0
libstdc++.so.6.0.34
libitm.so.1.0.0
libatomic.so.1.2.0"
cd /usr/lib
for LIB in $save_usrlib; do
objcopy --only-keep-debug --compress-debug-sections=zstd $LIB $LIB.dbg
cp $LIB /tmp/$LIB
strip --strip-debug /tmp/$LIB
objcopy --add-gnu-debuglink=$LIB.dbg /tmp/$LIB
install -vm755 /tmp/$LIB /usr/lib
rm /tmp/$LIB
done
online_usrbin="bash find strip"
online_usrlib="libbfd-2.46.0.20260210.so
libsframe.so.3.0.0
libhistory.so.8.3
libncursesw.so.6.6
libm.so.6
libreadline.so.8.3
libz.so.1.3.2
libzstd.so.1.5.7
$(cd /usr/lib; find libnss*.so* -type f)"
for BIN in $online_usrbin; do
cp /usr/bin/$BIN /tmp/$BIN
strip --strip-debug /tmp/$BIN
install -vm755 /tmp/$BIN /usr/bin
rm /tmp/$BIN
done
for LIB in $online_usrlib; do
cp /usr/lib/$LIB /tmp/$LIB
strip --strip-debug /tmp/$LIB
install -vm755 /tmp/$LIB /usr/lib
rm /tmp/$LIB
done
for i in $(find /usr/lib -type f -name \*.so* ! -name \*dbg) \
$(find /usr/lib -type f -name \*.a) \
$(find /usr/{bin,sbin,libexec} -type f); do
case "$online_usrbin $online_usrlib $save_usrlib" in
*$(basename $i)* )
;;
* ) strip --strip-debug $i
;;
esac
done
unset BIN LIB save_usrlib online_usrbin online_usrlib
EOSF
echo "Do you want to strip binaries ?"
if ${LFS_STRIP_BINARIES}
then
if lfsdev_chroot "${sudofile}"
then
echo "88510" > "${SLFSB}"
fi
else
echo "Skip stripping"
echo "88510" > "${SLFSB}"
fi
fi
ask_for_exit 88610
echo "8.86. Cleaning Up"
if [[ $(cat "${SLFSB}") -lt 88610 ]]
then
sudofile=/tmp/lfsdev_88610.sh
cat > ${sudofile} << "EOSF"
#rm -rf /tmp/{*,.*}
find /usr/lib /usr/libexec -name \*.la -delete
find /usr -depth -name $(uname -m)-lfsdev-linux-gnu\* | xargs rm -rf
userdel -r tester
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "88610" > "${SLFSB}"
fi
fi
ask_for_exit 90210
echo "9.2.GeneralNetworkConfiguration"
if [[ $(cat "${SLFSB}") -lt 90210 ]]
then
if ${LFS_OFFLINE}
then
echo "Offline Build -- no network"
echo "90210" > "${SLFSB}"
elif ${LFS_NETWORK}
then
sudofile=/tmp/lfsdev_90210.sh
INTERFACE=$(ip route |grep default |cut --delimiter=' ' --fields=5)
GATEWAY=$(ip route |grep default |cut --delimiter=' ' --fields=3)
IPADDRESS=$(ip address show dev "${INTERFACE}" |grep "${INTERFACE}$" |cut --delimiter=' ' --fields=6)
if ip address show dev "${INTERFACE}" |grep "${INTERFACE}$" |grep dynamic
then
IPORIGIN=dynamic
elif ip address show dev "${INTERFACE}" |grep "${INTERFACE}$" |grep static
then
IPORIGIN=static
else
echo "Network configuration error"
fi
DNSADDRESS=$(grep nameserver /etc/resolv.conf | cut --delimiter=' ' --fields=2)
case "${IPORIGIN}" in
dynamic)
cat > ${sudofile} << EOSF
echo "Set dynamic address"
cat > /etc/systemd/network/10-eth-dhcp.network << "EOF"
[Match]
Name=${INTERFACE}
[Network]
DHCP=ipv4
[DHCPv4]
UseDomains=true
EOF
echo "$(cat /etc/hostname)" > /etc/hostname
echo "$(cat /etc/hosts)" > /etc/hosts
EOSF
;;
static)
cat > ${sudofile} << EOSF
echo "Set static address"
cat > /etc/systemd/network/10-eth-static.network << "EOF"
[Match]
Name=${INTERFACE}
[Network]
Address=${IPADDRESS}
Gateway=${GATEWAY}
DNS=${DNSADDRESS}
#Domains=<Your Domain Name>
EOF
echo "$(cat /etc/hostname)" > /etc/hostname
echo "$(cat /etc/hosts)" > /etc/hosts
EOSF
;;
*)
echo "Unknown configuration. Network configuration error"
exit 1
;;
esac
echo "Configure network (same as host)"
if lfsdev_chroot "${sudofile}"
then
echo "90210" > "${SLFSB}"
else
echo "Network configuration error"
exit 1
fi
else
echo "Script is stopped for networking configuration"
echo "90210" > "${SLFSB}"
exit 0
fi
fi
ask_for_exit 90610
echo "9.6. Configuring the Linux Console"
if [[ $(cat "${SLFSB}") -lt 90610 ]]
then
VCONSOLE=/mnt/lfsdev/tmp/vconsole.conf
cat > ${VCONSOLE} << EOSF
KEYMAP=XX
FONT=XX
XKBLAYOUT=XX
EOSF
# try with KEYMAP from vconsole host
if grep --silent 'KEYMAP' /etc/vconsole.conf
then
keymap=$(grep --silent 'KEYMAP' /etc/vconsole.conf |cut --delimiter='=' --fields=2 |sed 's/ //g')
if [[ "${keymap}" =~ ^[a-z][a-z]$ ]]
then
sed /KEYMAP/s/KEYMAP=XX/KEYMAP="${keymap}"/ -i ${VCONSOLE}
fi
fi
# try with FONT from vconsole host
if grep -q 'FONT' /etc/vconsole.conf
then
font=$(grep --silent 'FONT' /etc/vconsole.conf |cut --delimiter='=' --fields=2 |sed 's/ //g')
if [[ "${font}" =~ ^[a-z0-9][a-z0-9]+$ ]]
then
sed /FONT/s/FONT=XX/FONT="${font}"/ -i ${VCONSOLE}
fi
fi
# try with XKBLAYOUT from vconsole host
if grep -q 'XKBLAYOUT' /etc/vconsole.conf
then
xkblayout=$(grep --silent 'XKBLAYOUT' /etc/vconsole.conf | cut --delimiter='=' --fields=2 |sed 's/ //g')
if [[ "${xkblayout}" =~ ^[a-z0-9][a-z0-9]+$ ]]
then
sed /XKBLAYOUT/s/XKBLAYOUT=XX/XKBLAYOUT="${xkblayout}"/ -i ${VCONSOLE}
fi
fi
# try with VC KEYMAP from localctl host
localectl status | while IFS= read -r localectls
do
if echo "${localectls}" | grep --silent "VC Keymap"
then
keymap=$(echo "${localectls}" | cut --delimiter=':' --fields=2 |sed 's/ //g')
if [[ "${keymap}" =~ ^[a-z][a-z]$ ]]
then
sed /KEYMAP/s/KEYMAP=XX/KEYMAP="${keymap}"/ -i ${VCONSOLE}
fi
fi
done
# try with X11 Layout from localectl host
localectl status | while IFS= read -r localectls
do
if echo "${localectls}" | grep --silent "X11 Layout"
then
xkblayout=$(echo "${localectls}" | cut --delimiter=':' --fields=2 | sed 's/ //g')
if [[ "${xkblayout}" =~ ^[a-z][a-z]$ ]]
then
sed /KEYMAP/s/KEYMAP=XX/KEYMAP="${xkblayout}"/ -i ${VCONSOLE}
sed /XKBLAYOUT/s/XKBLAYOUT=XX/XKBLAYOUT="${xkblayout}"/ -i ${VCONSOLE}
fi
fi
done
# retry with VC KEYMAP from localectl host
localectl status | while IFS= read -r localectls
do
if echo "${localectls}" | grep --silent "VC Keymap"
then
keymap=$(echo "${localectls}" | cut --delimiter=':' --fields=2 |sed 's/ //g')
if [[ "${keymap}" =~ ^[a-z][a-z]$ ]]
then
sed /KEYMAP/s/KEYMAP=XX/KEYMAP="${keymap}"/ -i ${VCONSOLE}
sed /XKBLAYOUT/s/XKBLAYOUT=XX/XKBLAYOUT="${keymap}"/ -i ${VCONSOLE}
fi
fi
done
# default if nothing is set (if KEYMAP=XX)
sed "/KEYMAP/s/KEYMAP=XX/KEYMAP=fr/" --in-place ${VCONSOLE}
sed "/FONT/s/FONT=XX/FONT=Lat2-Terminus16/" --in-place ${VCONSOLE}
sed "/XKBLAYOUT/s/XKBLAYOUT=XX/XKBLAYOUT=fr/" --in-place ${VCONSOLE}
# building chroot
sudofile=/tmp/lfsdev_90610.sh
cat > ${sudofile} << "EOSF"
cp -v /tmp/vconsole.conf /etc/vconsole.conf
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "90610" > "${SLFSB}"
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 90710
echo "9.7. Configuring the System Locale"
if [[ $(cat "${SLFSB}") -lt 90710 ]]
then
LOCALECONF=/mnt/lfsdev/tmp/locale.conf
cat > ${LOCALECONF} << EOSF
LANG=XX
EOSF
# try with KEYMAP from vconsole host
if grep --silent 'LANG' /etc/locale.conf
then
language=$(grep --silent 'LANG' /etc/locale.conf | cut --delimiter='=' --fields=2 |sed 's/ //g')
if [[ "${language}" =~ ^["][a-z][a-zA-Z0-9_@.-]+["]$ ]]
then
sed /LANG/s/LANG=XX/LANG="${language}"/ --in-place "${LOCALECONF}"
fi
fi
# default if nothing is set (if LANG=XX)
sed /LANG/s/LANG=XX/LANG="fr_FR.UTF-8"/ --in-place "${LOCALECONF}"
sudofile=/tmp/lfsdev_90710.sh
cat > ${sudofile} << "EOSF"
cp -v /tmp/locale.conf /etc/locale.conf
cat > /etc/profile << "EOF"
# Begin /etc/profile
for i in $(locale); do
unset ${i%=*}
done
if [[ "$TERM" = linux ]]; then
export LANG=C.UTF-8
else
source /etc/locale.conf
for i in $(locale); do
key=${i%=*}
if [[ -v $key ]]; then
export $key
fi
done
fi
# End /etc/profile
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "90710" > "${SLFSB}"
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 90810
echo "9.8. Creating the /etc/inputrc File "
if [[ $(cat "${SLFSB}") -lt 90810 ]]
then
sudofile=/tmp/lfsdev_90810.sh
cat > ${sudofile} << "EOSF"
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
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "90810" > "${SLFSB}"
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 90910
echo "9.9. Creating the /etc/shells File"
if [[ $(cat "${SLFSB}") -lt 90910 ]]
then
sudofile=/tmp/lfsdev_90910.sh
cat > ${sudofile} << "EOSF"
cat > /etc/shells << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "90910" > "${SLFSB}"
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 91010
echo "9.10. Systemd Usage and Configuration"
if [[ $(cat "${SLFSB}") -lt 91010 ]]
then
sudofile=/tmp/lfsdev_91010.sh
cat > ${sudofile} << "EOSF"
mkdir -pv /etc/systemd/system/getty@tty1.service.d
cat > /etc/systemd/system/getty@tty1.service.d/noclear.conf << EOF
[Service]
TTYVTDisallocate=no
# ln -sfv /dev/null /etc/systemd/system/tmp.mount
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "91010" > "${SLFSB}"
cat <<EOF
#########################################################################################################################
# /tmp : 3 methods
# 1. systemd create /tmp as tmpfs by default
# 2. if /tmp is a separate partition, add corresponding entry in fstab
# 3. if you want /tmp on the / partition and not mounted as tmpfs, execute the following command in the chrooted env :
# ln -sfv /dev/null /etc/systemd/system/tmp.mount
#########################################################################################################################
EOF
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 100200
echo "10.2. Creating the /etc/fstab File"
if [[ $(cat "${SLFSB}") -lt 100200 ]]
then
FSTAB=${LFS}/tmp/fstab
if [ -e ${FSTAB} ]
then
rm ${FSTAB}
fi
blockdevice="$(mount |grep '/mnt/lfsdev type ext4' |cut --delimiter=' ' --fields=1 |cut --delimiter='/' --fields=3)"
for link in /dev/disk/by-uuid/*
do
# readlink "${link}"
# echo "case test with *${blockdevice}"
case $(readlink "${link}") in
*${blockdevice})
# echo "found ${blockdevice} with link ${link}"
blockuuid=$(basename "${link}")
if [[ ! "${blockuuid}" =~ ^[a-zA-Z0-9-]+$ ]]
then
echo "Can't init /etc/fstab"
echo "Fix it by ourself"
exit 1
else
cat > ${FSTAB} << EOSF
UUID=${blockuuid} / ext4 defaults 0 0
EOSF
fi
;;
*)
continue
;;
esac
done
if [ ! -e ${FSTAB} ]
then
echo "Can't init /etc/fstab"
echo "Fix it by ourself"
exit 1
fi
swapuuid=$(lsblk --output UUID,MOUNTPOINTS |grep SWAP |head -1 |cut --delimiter=' ' --fields=1)
if [[ "${blockuuid}" =~ ^[a-zA-Z0-9-]+$ ]]
then
cat >> ${FSTAB} << EOSF
UUID=${swapuuid} none swap sw 0 0
EOSF
echo "The first swap partition found of the host was written in /etc/fstab"
echo "Fix it of you have/want another swap"
else
echo "Can't init swap /etc/fstab"
echo "Fix it by ourself"
fi
sudofile=/tmp/lfsdev_100200.sh
cat > ${sudofile} << "EOSF"
cp -v /tmp/fstab /etc/fstab
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "100200" > "${SLFSB}"
echo "Please check /etc/fstab in /mnt/lfsdev"
echo "Check root and swap"
echo "Add /boot and other mount point if necessary"
else
echo "Configuration error"
exit 1
fi
fi
ask_for_exit 103100
echo "10.3.1. Installation of the kernel"
if [[ $(cat "${SLFSB}") -lt 103100 ]]
then
step=103100
scriptname=${step}_linux.sh
unnumbered=${scriptname##*_}
packagename=${unnumbered%.*}
archivepath=$(find "${SOURCES}" -name "${packagename}*.tar.*" -print)
archivesubpath=${archivepath##/mnt/lfsdev}
archivename=$(basename "${archivepath}")
package=${archivename%%.tar.xz}
buildpath=/sources/"${package}"
linuxversion=${package##*-}
sudofile=/tmp/lfsdev_103100.sh
cat > "${sudofile}" << EOSF
if [ ! -d "${buildpath}" ]
then
mkdir -p "${buildpath}"
fi
if [ ! -e "${buildpath}"/COPYING ]
then
if ! tar -xf "${archivesubpath}" -C "${buildpath}" --strip-components=1
then
echo "untar error"
exit 1
fi
fi
pushd "${buildpath}"
set -ueExo pipefail
eval "\$(cat ../"${scriptname}")" | tee "/tmp/lfsdev_103100.log"
popd
EOSF
if ! lfsdev_chroot "${sudofile}"
then
echo "compilation error"
exit 1
else
echo "compilation ok"
fi
check_errors "${STEMP}/lfsdev_103100.log"
echo 103100 > "${SLFSB}"
fi
ask_for_exit 103110
echo "10.3.1. Installation of the kernel"
if [[ $(cat "${SLFSB}") -lt 103110 ]]
then
step=103100
scriptname=${step}_linux.sh
unnumbered=${scriptname##*_}
packagename=${unnumbered%.*}
archivepath=$(find "${SOURCES}" -name "${packagename}*.tar.*" -print)
archivename=$(basename "${archivepath}")
package=${archivename%%.tar.xz}
buildpath=/sources/"${package}"
linuxversion=${package##*-}
if ${LFS_LINUXCONFIG}
then
if cp --verbose "${SCRIPT_DIR}/linux-config-${ARCH}.txt" /mnt/lfsdev/tmp/linux-config-host
then
sudofile=/tmp/lfsdev_103110.sh
cat > ${sudofile} << EOSF
cp --verbose /tmp/linux-config-host ${buildpath}/.config
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "copy ok"
echo "103110" > "${SLFSB}"
else
echo "copy error"
exit 1
fi
else
echo "Can't find a linux configuration"
echo "Fix it !"
exit 1
fi
fi
if [ -e /mnt/lfsdev/sources/"${package}"/.config ]
then
echo "103110" > "${SLFSB}"
echo "A config file for kernel compilation exist"
else
echo "103110" > "${SLFSB}"
echo "Script is stopped for linux configuration"
echo "It's time to configure kernel compilation"
echo "LFS recommand to compile the kernel by youself"
echo "Please execute as lfsdev :"
echo "$ bash $HOME/lfsdev_chroot.sh"
echo "(lfsdev chroot) root:/$ cd /sources/linux-6.8.10"
echo "(lfsdev chroot) root:/$ make menuconfig"
echo "you can try this at minimal :"
echo "(lfsdev chroot) root:/$ make defconfig"
exit 0
fi
fi
ask_for_exit 103120
echo "10.3.1. Installation of the kernel"
if [[ $(cat "${SLFSB}") -lt 103120 ]]
then
step=103100
scriptname=${step}_linux.sh
unnumbered=${scriptname##*_}
packagename=${unnumbered%.*}
archivepath=$(find "${SOURCES}" -name "${packagename}*.tar.*" -print)
archivename=$(basename "${archivepath}")
package=${archivename%%.tar.xz}
buildpath=/sources/"${package}"
linuxversion=${package##*-}
if [ ! -e "${LFS}"/"${buildpath}"/.config ]
then
echo "Seems kernel was not configured"
echo "Please execute as lfsdev :"
echo "$ bash /tmp/lfsdev_chroot.sh"
echo "(lfsdev chroot) root:/$ cd ${buildpath}"
echo "(lfsdev chroot) root:/$ make menuconfig"
echo "you can try too :"
echo "(lfsdev chroot) root:/$ make defconfig"
exit 1
fi
sudofile=/tmp/lfsdev_103120.sh
cat > ${sudofile} << EOSF
cd "${buildpath}"
make
if grep "CONFIG_MODULES=y" "${buildpath}"/.config
then
make modules
fi
cp -v arch/x86/boot/bzImage /boot/vmlinuz-${linuxversion}-lfsdev-13.0-systemd
cp -v System.map /boot/System.map-${linuxversion}
cp -v .config /boot/config-${linuxversion}
cp -r Documentation -T /usr/share/doc/${package}
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
EOSF
if ! lfsdev_chroot "${sudofile}"
then
echo "compilation error"
exit 1
else
echo "compilation ok"
echo "103120" > "${SLFSB}"
fi
fi
ask_for_exit 104000
echo "10.4. Using GRUB to Set Up the Boot Process "
if [[ $(cat "${SLFSB}") -lt 104000 ]]
then
# get "linux-6.8.10"
archivepath=$(find "${SOURCES}" -name "linux-*.tar.*" -print)
archivename=$(basename "${archivepath}")
package=${archivename%%.tar.xz}
buildpath=/sources/"${package}"
linuxversion=${package##*-}
# get root device uuid
blockdevice=$(mount |grep '/mnt/lfsdev type ext4' | cut --delimiter=' ' --fields=1)
#for link in /dev/disk/by-uuid/*
#do
# case $(readlink "${link}") in
# *${blockdevice})
# echo "found ${blockdevice} with link ${link}"
# blockuuid=$(basename "${link}")
# if [[ ! "${blockuuid}" =~ ^[a-zA-Z0-9-]+$ ]]
# then
# echo "Can't init grub.conf"
# echo "Fix it by ourself"
# exit 1
# fi
# ;;
# *)
# continue
# ;;
# esac
#done
#
if [ ! -e "$LFS/boot/vmlinuz-${linuxversion}-lfsdev-13.0-systemd" ]
then
echo "Kernel file absent from /boot"
exit 1
fi
uuidfilesystem=$(lsblk -o UUID,PARTUUID,PATH,MOUNTPOINT |grep /mnt/lfsdev$ |cut --delimiter=' ' --fields=1)
if [[ ! "${uuidfilesystem}" =~ ^[a-z0-9-]+$ ]]
then
echo "UUID seems bad"
exit 1
fi
uuidpartition=$(lsblk -o UUID,PARTUUID,PATH,MOUNTPOINT |grep /mnt/lfsdev$ |sed -e "s/ */ /g" |cut --delimiter=' ' --fields=2)
if [[ ! "${uuidpartition}" =~ ^[a-z0-9-]+$ ]]
then
echo "PARTUUID seems bad"
exit 1
fi
sudofile=/tmp/lfsdev_104000.sh
cat > ${sudofile} << EOSF
mkdir --verbose /boot/grub
cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod part_gpt
insmod ext2
search --set=root --fs-uuid=${uuidfilesystem}
set gfxpayload=1024x768x32
menuentry "GNU/Linux, Linux ${linuxversion}-lfsdev-13.0-systemd with blockdevice" {
linux /boot/vmlinuz-${linuxversion}-lfsdev-13.0-systemd root=${blockdevice} ro
}
menuentry "GNU/Linux, Linux ${linuxversion}-lfsdev-13.0-systemd with partuuid" {
linux /boot/vmlinuz-${linuxversion}-lfsdev-13.0-systemd root=PARTUUID=${uuidpartition} ro
}
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "104000" > "${SLFSB}"
else
echo "grub config error"
exit 1
fi
fi
ask_for_exit 110100
echo "11.1. The End"
if [[ $(cat "${SLFSB}") -lt 110100 ]]
then
sudofile=/tmp/lfsdev_110100.sh
cat > ${sudofile} << EOSF
echo 13.0-systemd > /etc/lfsdev-release
cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="13.0-systemd"
DISTRIB_CODENAME="<your name here>"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF
cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="13.0-systemd"
ID=lfsdev
PRETTY_NAME="Linux From Scratch 13.0-systemd"
VERSION_CODENAME="<your name here>"
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "104000" > "${SLFSB}"
else
echo "grub config error"
exit 1
fi
fi
ask_for_exit 110100
echo "11.1. The End"
if [[ $(cat "${SLFSB}") -lt 110100 ]]
then
sudofile=/tmp/lfsdev_110100.sh
cat > ${sudofile} << EOSF
echo 13.0-systemd > /etc/lfsdev-release
cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="13.0-systemd"
DISTRIB_CODENAME="<your name here>"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF
cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="13.0-systemd"
ID=lfsdev
PRETTY_NAME="Linux From Scratch 13.0-systemd"
VERSION_CODENAME="<your name here>"
HOME_URL="https://www.linuxfromscratch.org/lfs/"
RELEASE_TYPE="stable"
EOF
EOSF
if lfsdev_chroot "${sudofile}"
then
echo "You can edit /etc/lsb-release and /etc/os-release and edit your name"
echo "110100" > "${SLFSB}"
else
echo "release file creation error"
exit 1
fi
fi
echo "Finish successfully"
echo "Adapt /boot/grub/grub.cfg to your configuration"
echo "And install the bootloader if needed with the appropriate boot device"
echo "(lfsdev chroot) root:/$ grub-install /dev/xda"
}
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main "$@"
fi