Linux from scratch

by @Entr0phy4 (David Agámez), Software Engineering

LinuxOperating SystemsSystem AdministrationVirtualizationVMwareDebianLFSCommand LineShell ScriptingSystem ProgrammingKernelGNU/LinuxBuild SystemsSoftware DevelopmentSystem ToolsPackage ManagementBootloaderFile SystemsSystem Configuration

Table of contents

Get a look at all of the content covered in this guide. Everything you need to know is inside.

This guide will take you through the step-by-step process of building your own Linux distribution from the ground up, known as "Linux From Scratch" (LFS). The table of contents outlines the key stages involved in setting up a fully functional, custom Linux system. Whether you're looking to deepen your understanding of Linux or create a tailored OS environment, this guide will provide all the instructions you need.

Introduction

Background

Linux From Scratch (LFS) is a project that provides you with step-by-step instructions for building your own custom Linux system, entirely from source code. But why would anyone want to build their own Linux distribution from scratch when there are hundreds of ready-to-use distributions available?

The primary purpose of LFS is educational. By building a Linux system from the ground up, you gain an intimate understanding of how Linux systems work internally. You'll learn:

  • How the different components of a Linux system fit together
  • How the boot process works
  • How system libraries and utilities depend on each other
  • How to compile and configure software packages
  • How to troubleshoot system-level issues effectively

This deep understanding is invaluable for system administrators, Linux enthusiasts, and anyone interested in operating system internals. While the process is time-consuming and challenging, the knowledge gained is well worth the effort.

LFS also offers complete control over your system. You decide exactly which packages to include, how they're configured, and how the system is structured. This level of customization can result in a system that's:

  • Optimized for your specific hardware
  • Stripped of unnecessary components
  • More secure due to reduced attack surface
  • Tailored to your exact needs

This guide will walk you through the entire process, from preparing your host system to configuring the final bootable system. While it may seem daunting at first, we'll break it down into manageable steps, each building upon the previous ones.

Link to the official guide: Linux From Scratch

Recomendations

How create a Snapshot (VMWare Workstation)

It is advisable to create a snapshot of the system so as not to lose our progress in case something goes wrong.

If you are using VMware workstation for virtualization, in the upper menu, you should have the following options:

VMware upper menu

Set a name and description for the snapshot.

Snapshot of machine

And our snapshot has been created, in case we have an error we can always return to this point.

Snapshots timeline

Preparing Host System

Virtualizing Debian

First of all it is necessary to know that we need a linux on which to work. We will be using Debian 12.10.0.

Debian ISO

Once we have the ISO we will continue virtualizing it in our software of choice, in my case I will be using VMware Workstation

With VMware Workstation open, we will click on: Create a New Virtual Machine.

VMware workstation

Once we click on it, we will be in this window, in which we will have to select the image of Debian.

Select debian ISO in VMware

Next, we will have to assign a name to our virtual machine, in our case it will be LFS from Linux From Scratch.

Assign name to virtual machine

Now, we need to select the disk size, I will leave the default value but later we will add another disk to store the LFS.

Select disk size

In the next step, we will have to select the hardware specifications, we will use 8 RAM.

Select RAM size

and 4 processor cores.

Select processor cores

After this our virtual machine should start up without any problems.

Installing Debian

Debian installer menu

We will complicate our life much more later, but for now we will select graphical installation. If you use the North American keyboard layout and you understand English, just need to click next for the first few steps, if this is not your case, select the options of your preference.

In the network configuration it is the same story, you can leave the default hostname and do not set a domain name.

Next step, enter your password for super user.

Set root password

Now, set your user name.

Set username

You must then enter a new password but for your non-administrative user.

Next should be the clock configuration, which again depends on your region.

Then it will ask us about disk partitioning, we will select use the entire disk.

Select partitioning

For the partition scheme we will select All files in one partition.

Selecting partition scheme

Later we will separate /home in another partition.

Finish partitioning

Select Finish partitioning and write changes to disk.

Confirm partitioning

And that's it.

Now, we must wait for the installation of the base system to be completed.

Then it will ask us if we want to use another installation media, select no and continue.

Select if you want another installation media

Next it will ask us for the package manager configuration, select our region if it is there, if it is not, select the nearest one, when it asks us for the debian archive mirror, leave the default one.

Select Debian archive mirror

When asked for the http proxy, we leave it blank.

Then start configuring the package manager (apt).

After, in the popularity contest select no and continue.

After installing some other packages it will ask to select our desktop environment, in my case I will user GNOME.

Select desktop environment

This it could take a few minutes, then ask us if we want to install the bootloader, GRUB, select yes and continue.

Installing GRUB bootloader

Then we will have to indicate where we want to install it, select /dev/sda and continue.

The installation process will start and may take a few minutes, when this is over we should see something like this:

Finish installation

Click on continue, the virtual machine will reboot and the once the system restarts we should see the following.

Start of Debian System

Setting up Debian

Well, so far we already have a base operating system on which to operate comfortably, let's make some modifications.

First, we will soon have quite extensive copilation processes so we want to avoid the automatic suspension of the system.

We are going to Settings > Power > Power Saving Options and we disable everything.

Disable power saving options

Now let's open a terminal and become root.

Become root

Typing:

sudo usermod -aG sudo <YOUR_NON_ADMINISTRATIVE_USER>

And reboot.

With this we add our user to the sudoers file, to be able to execute actions with elevated privileges without needing to be root.

Top tip

If your eyes are bleeding with the white terminal theme you can go to:
Menu > Preferences > General > Terminal variant > dark

Groups of entr0phy4 user

Now, we are part of the sudo group.

System requirements

the official guide provides us with the following script to verify the necessary dependencies.

cat > 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 ~lfs/.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
}

# 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.2
ver_check "GCC (C++)"    g++      5.2
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++ -
then echo "OK:    g++ works";
else echo "ERROR: g++ does NOT work"; fi
rm -f 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

bash version-check.sh

Let's copy it and enter it in the terminal, after press enter we should a output like

Verify check

A few errors and a new .sh file called version-check.

The errors basically indicate that the corresponding package is not installed, and also report some symbolic links that we need to create. You can download each package independently via

sudo apt install <PACKAGE_NAME>

Keep in mind that you will have to download the developer's packages in case it exists, for debian-based distros, they usually have the termination -dev, but on some other systems it is -devel.

But in my case I decided to create a script called install-lfs-deps.sh to automate that process.

#!/bin/bash
set -e

echo "==== [1/5] Updating package list ===="
sudo apt update

# Core packages required for LFS
PACKAGES=(
  bash
  binutils
  bison
  coreutils
  diffutils
  findutils
  gawk
  gcc
  g++
  grep
  gzip
  linux-headers-$(uname -r)
  m4
  make
  patch
  perl
  python3
  sed
  tar
  texinfo
  xz-utils
)

echo "==== [2/5] Installing required base packages ===="
for pkg in "${PACKAGES[@]}"; do
  echo "Installing $pkg..."
  sudo apt install -y "$pkg"
done

echo "==== [3/5] Checking for and installing available development packages (-dev or -devel) ===="
for pkg in "${PACKAGES[@]}"; do
  dev_pkg="${pkg}-dev"
  devel_pkg="${pkg}-devel"

  if apt-cache show "$dev_pkg" >/dev/null 2>&1; then
    echo "Installing development package: $dev_pkg"
    if ! sudo apt install -y "$dev_pkg"; then
      echo "Warning: Failed to install $dev_pkg"
    fi
  elif apt-cache show "$devel_pkg" >/dev/null 2>&1; then
    echo "Installing development package: $devel_pkg"
    if ! sudo apt install -y "$devel_pkg"; then
      echo "Warning: Failed to install $devel_pkg"
    fi
  else
    echo "No development package (-dev or -devel) found for $pkg"
  fi
done

echo "==== [4/5] Creating required LFS symlinks ===="
# Required symlinks for LFS
sudo ln -sf /bin/bash /bin/sh
sudo ln -sf /usr/bin/bison /usr/bin/yacc
sudo ln -sf /usr/bin/gawk /usr/bin/awk

echo "==== [5/5] Verifying g++ compilation ability ===="
if echo "int main(){}" | g++ -x c++ -o /tmp/testprog -; then
  echo "g++ can compile C++ programs"
  rm -f /tmp/testprog
else
  echo "ERROR: g++ failed to compile a simple program"
fi

echo "==== All done! You can now run version-check.sh to verify versions ===="

Once we have the script on the machine we will have to give it execution permissions.

chmod +x install-lfs-deps.sh

and execute.

bash install-lfs-deps.sh
Install LFS dependencies in execution

and if you run version-check.sh again.

bash version-check.sh
Version check success output

We do not get any errors.

Partitioning

Linux From Scratch like most other operating systems is usually installed on a dedicated partition.

At this point, we are going to add a new disk whare we will store our LFS, first we must turn off our virtual machine.

Add new disk

If we are in VMWare, we will double click on Hard Disk (SCSI).

Hardware specifications

Click on the add button.

Select type of disk to add

If ask us for for the type of disk we leave the recommended one (SCSI in my case), after select the option Create a new virtual disk and next.

Then you will be asked to select the size of the new disk.

Select size of new disk

We will allocate 30 GB and leave the default name.

Save new disk

We can click on save and run again our machine.

Once the machine has been started, we are going to use lsblk to display our disks..

sudo lsblk
lsblk print

And we can visualize our new disk sdb.

Create GPT partition table

Let's start by creating a new partition table for the disk with fdisk.

sudo fdisk /dev/sdb
fdisk menu

Displaying the help menu typing m + Return we can see these options.

  Create a new label
   g   create a new empty GPT partition table
   G   create a new empty SGI (IRIX) partition table
   o   create a new empty MBR (DOS) partition table
   s   create a new empty Sun partition table

In most cases, modern systems usually use a UEFI bootloader, which is we will be working with, therefore, GPT is the necessary partitioning scheme for systems booting in UEFI mode. so, option g is the one we are interested in, so we will type it in.

We should see something similar to the following message.

Command (m for help): g
Created a new GPT disklabel (GUID: B3D589A6-3CCE-D44E-88EB-A9276C854317).

Now type w + Return to write the changes and you should see:

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Create partitions

Now we just need to start partitioning the disk, we will be using cfdisk as partition editor.

sudo cfdisk /dev/sdb
Free partition on cfdisk

From now, we will focus on creating four partitions:

  • efi: This partition will store the kernels and other booting information.

  • root: Here's where we will be building our LFS.

  • home: Saves our user customizations.

So, let's start with efi, select the New option and assign 200M, Once created, press tab to move to the option Type and press Return. Change the partition type to EFI System.

Select EFI system partition type

Ready, now the root partition, we will assign 20G in this case. The default type should be Linux filesystem, which is fine.

Finally, to our home partition we will assign the rest of the space and the type will also be Linux filesystem.

Our partitions should look like this:

Partitons created

Now that they are ready, select the write option and type yes.

You should see a message like:

The partition table has been altered.

With lsblk we can see that our sdb disk now has a similar partitioning to our base systems, except for the SWAP that serves as virtual memory to extend the available RAM. Is mostly used for mechanical hard disks.

Compare partitioning of disks

Format partitions

Then we need to assign a ext4 file system to root and home partition, we are going to be using mkfs.

mkfs -v -t ext4 /dev/<YOUR_ROOT_PARTITION>
Setting filesystem to root partition

We do the same for sdb3.

Now for the efi partition, we must format with vfat because this is the file system set by the UEFI specification.

sudo mkfs.vfat -F 32 /dev/<YOUR_EFI_PARTITION>

And we should have the following output:

entr0phy4@debian:~$ sudo mkfs.vfat -F 32 /dev/sdb1
mkfs.fat 4.2 (2021-01-31)

If we see the partitions with their respective file systems (sudo lsblk -f), it would look like this:

Partitions with ther file systems

Once with each partition and its respective file system, let's edit root's, and personalized user .bashrc file to export the following variable for each shell session.

echo "export LFS=/mnt/lfs" | sudo tee -a /root/.bashrc | tee -a ~/.bashrc

If we type source .bashrc and echo $LFS we should obtain from output /mnt/lfs.

echo LFS variable

We will now proceed to create the $LFS directory.

entr0phy4@debian:~$ sudo mkdir -pv $LFS
mkdir: created directory '/mnt/lfs'

Mount partitions

With this we have created the $LFS directory, now we will mount the root partitions to it.

entr0phy4@debian:~$ sudo mount -v -t ext4 /dev/sdb2 $LFS
mount: /dev/sdb2 mounted on /mnt/lfs.

All right, now we will mount the home partition.

entr0phy4@debian:~$ sudo mkdir -pv $LFS/home
mkdir: created directory '/mnt/lfs/home'
entr0phy4@debian:~$ sudo mount -v -t ext4 /dev/sdb3 $LFS/home
mount: /dev/sdb3 mounted on /mnt/lfs/home.

With this we have mounted the partitions to the $LFS directory. If we check the content of /mnt/lfs we should see the following:

Content of $LFS

Base system packages

For this point, let's create a directory to store the packages and patches.

sudo mkdir -pv $LFS/sources

And we make that directory writable and set the sticky bit, this is to only the owner of a file can delete or modify it.

entr0phy4@debian:~$ sudo chmod -v a+wt $LFS/sources
mode of '/mnt/lfs/sources' changed to 0755 (rwxr-xr-x) to 1777 (rwxrwxrwt)

Download packages

Now we will download the packages and patches from the lfs-packages repository.

All packages we need are in wget-list-sysv.

So let's download the list of packages.

wget https://www.linuxfromscratch.org/lfs/view/stable/wget-list-sysv
wget-list-sysv

We now have a file called wget-list-sysv in our current directory.

And we will download the packages sending the list of packages to the wget command and indicating --directory-prefix to specify the directory where the packages will be downloaded.

wget --input-file=wget-list-sysv --continue --directory-prefix=$LFS/sources

This start the download all the packages and we can see the progress.

Download progress

Once the download is finished, we can see this message in the terminal.

FINISHED --2025-05-08 21:37:14--
Total wall clock time: 7m 24s
Downloaded: 92 files, 528M in 6m 24s (1.38 MB/s)

And we can see the packages in the $LFS/sources directory.

Packages in $LFS/sources

Verify downloaded packages

Now, let's verify the integrity of the downloaded packages. First, let's download the MD5 checksums file:

wget https://www.linuxfromscratch.org/lfs/view/stable/md5sums

Once we have the file, we will verify the integrity of the downloaded packages with the following command:

pushd $LFS/sources; md5sum -c ~/md5sums; popd

And we should see something like this:

md5sum verification

Fix expat 2.6.4 error

In our case, all the packages have been downloaded correctly except expat-2.6.4.tar.xz. So we need to download it manually.

The next link is the github repository of the package for expat 2.6.4 release.

So click on the link and download the file expat-2.6.4.tar.xz.

expat-2.6.4.tar.xz

Once we have the file, we will move it to the $LFS/sources directory.

mv ~/Downloads/expat-2.6.4.tar.xz $LFS/sources

and check again the md5sum of the files.

pushd $LFS/sources; md5sum -c ~/md5sums; popd

In this case all packages pass the verification.

Top tip

If you have any problems with the packages, you can find support with download links in the

official guide.

If we donwload the packages being non-root user, we need to change the owner of the packages to root.

sudo chown root:root $LFS/sources/*

You can check the owner of the files with ls -l $LFS/sources.

ls -l $LFS/sources

Final preparations

Now we need to become root user for the rest of the process. This is necessary because we'll be performing operations in $LFS directory that require elevated privileges.

Creating tree directory structure

We need create the tree structure for our LFS.

mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}

for i in bin lib sbin; do
  ln -sv usr/$i $LFS/$i
done

case $(uname -m) in
  x86_64) mkdir -pv $LFS/lib64 ;;
esac

Once we paste the script on our terminal and press Enter we will see the following tree structure in our $LFS directory.

Tree structure of $LFS

If you are Linux user, that looks familiar, right?

Let's create one more directory for the tools where we will compile some tools we need.

mkdir -pv $LFS/tools

Creating lfs user

As a security measure, we will create a new user called lfs and add it to the lfs group.

First, we need to create the group.

groupadd lfs

And then we create the user.

useradd -s /bin/bash -g lfs -m -k /dev/null lfs

and create a password for the user.

passwd lfs

To grant lfs full access to all the directories in $LFS:

chown -v lfs $LFS/{usr{,/*},var,etc,tools}
case $(uname -m) in
  x86_64) chown -v lfs $LFS/lib64 ;;
esac
Giving access to user lfs

Now we become the lfs user.

su - lfs

From now, we will be working as lfs user.

Setting up environment variables

Once we are the user lfs we will modify the .bash_profile and .bashrc for lfs user.

First, we will create a new file called .bash_profile which not should exist, and add the following content:

cat > ~/.bash_profile << "EOF"
  exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

Now, we should have a file called .bash_profile in our home directory with that content.

.bash_profile

Now, we will create the .bashrc file, which should also not exist, and add the following content:

cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
EOF

Now, we should have a file called .bashrc in our home directory with that content.

.bashrc

Now, we will source the .bash_profile and .bashrc files.

source ~/.bash_profile
source ~/.bashrc

With this ready, we can start the compilation of the base system.

Cross Toolchain and Temporary Tools

Compiling a Cross-Toolchain

This is where the real work of building a new system begins.

We are going to place ourselves in the $LFS/sources directory.

cd $LFS/sources

And here we will start the compilation of the base system packages.

Binutils

First, we must unzip the package binutils-2.44.tar.xz.

tar -xf binutils-2.44.tar.xz

And we will enter the directory.

cd binutils-2.44

Once inside, we must create a directory called build and enter it.

mkdir -v build
cd build

Now, we will configure the build.

../configure --prefix=$LFS/tools \
             --with-sysroot=$LFS \
             --target=$LFS_TGT   \
             --disable-nls       \
             --enable-gprofng=no \
             --disable-werror    \
             --enable-new-dtags  \
             --enable-default-hash-style=gnu

We should see a output like this:

Binutils configuration

Now, we will compile the package.

make

This could take a few minutes.

Once finished we will perform the installation.

make install

If no errors occur, we should have the utility installed so go again to the $LFS/sources directory.

GCC

This package depends at the same time on three other packages: mpfr, gmp and mpc.

So once extracted.

tar -xf gcc-14.2.0.tar.xz

We will enter the directory.

cd gcc-14.2.0

And we will bring the three necessary packages.

tar -xf ../mpfr-4.2.1.tar.xz
mv -v mpfr-4.2.1 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
Extracted gcc packages
case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
 ;;
esac

This will set a default directory name for 64-bit libraries to lib.

Now the same story, create a build folder and get into it.

mkdir -v build
cd build

Configure the build.

../configure                  \
    --target=$LFS_TGT         \
    --prefix=$LFS/tools       \
    --with-glibc-version=2.41 \
    --with-sysroot=$LFS       \
    --with-newlib             \
    --without-headers         \
    --enable-default-pie      \
    --enable-default-ssp      \
    --disable-nls             \
    --disable-shared          \
    --disable-multilib        \
    --disable-threads         \
    --disable-libatomic       \
    --disable-libgomp         \
    --disable-libquadmath     \
    --disable-libssp          \
    --disable-libvtv          \
    --disable-libstdcxx       \
    --enable-languages=c,c++

and compile the package.

make

This one could last almost three times longer than the previous one.

Once finished, if no errors occur, the output should be similar to this:

GCC compilation

Now let's install.

make install

Now we are going to create a complete version of the internal system header. This same command is used by the gcc compilation process but his creates the headers in a partial way.

cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h

Linux API Headers

This package is a collection of the internal system header files for the Linux kernel.

So first we unzip the package.

tar -xf linux-6.13.4.tar.xz

And we will enter the directory.

cd linux-6.13.4

Now make sure there are no stale files embedded in the package.

make mrproper

Now we extract the user-visible kernel headers from the source.

make headers
Linux API headers

The headers are saved in the /usr directory, so we need to copy them to the $LFS/usr directory.

find usr/include -type f ! -name '*.h' -delete
cp -rv usr/include $LFS/usr

Glibc

This library provides the basic routines for the C programming language.

Let's unzip the package.

tar -xf glibc-2.41.tar.xz

And we will enter the directory.

cd glibc-2.41

First, create a symbolic link for LSB compliance. Additionally, for x86_64, create a compatibility symbolic link required for proper operation of the dynamic library loader:

case $(uname -m) in
    i?86)   ln -sfv ld-linux.so.2 $LFS/lib/ld-lsb.so.3
    ;;
    x86_64) ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64
            ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64/ld-lsb-x86-64.so.3
    ;;
esac

Apply the patch to the source code.

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

Now we will create a build directory and enter it.

mkdir -v build
cd build

Configure the build.

../configure                             \
      --prefix=/usr                      \
      --host=$LFS_TGT                    \
      --build=$(../scripts/config.guess) \
      --enable-kernel=5.4                \
      --with-headers=$LFS/usr/include    \
      --disable-nscd                     \
      libc_cv_slibdir=/usr/lib

Let's compile the package.

Top tip

There have been reports that this package may fail when building as a "parallel make." If that occurs, rerun the make command with the -j1 option.

make

Now we will install the package.

make DESTDIR=$LFS install

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

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

Once this is done we apply the following commands to validate the basic functions (compiler, linker, etc) are working.

echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux

We should see the following output:

GCC validation

if all is ok, remove the file a.out.

rm -v a.out

Libstdc++

This package is the standard C++ library. It is needed to compile c++ code.

For this process we must delete the folder we extracted earlier for gcc-14.2.0.

rm -rf gcc-14.2.0

And unzip again the tar file.

tar -xf gcc-14.2.0.tar.xz

And we will enter the directory.

cd gcc-14.2.0

Now we will create a build directory and enter it.

mkdir -v build
cd build

And configure the build with this parameters:

../libstdc++-v3/configure           \
    --host=$LFS_TGT                 \
    --build=$(../config.guess)      \
    --prefix=/usr                   \
    --disable-multilib              \
    --disable-nls                   \
    --disable-libstdcxx-pch         \
    --with-gxx-include-dir=/tools/$LFS_TGT/include/c++/14.2.0

Let's compile the package.

make

and install the package.

make DESTDIR=$LFS install

And we remove the libtool archive files.

rm -v $LFS/usr/lib/lib{stdc++{,exp,fs},supc++}.la

Cross-compiling Temporary Tools

M4

The M4 package contains a macro processor.

The process for the compilation is usually very similar so we will be less specific with the steps from now on.

Once unzipped the package, we will enter the directory, configure the build, compile and install.

tar -xf m4-1.4.19.tar.xz
cd m4-1.4.19
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

Ncurses

The Ncurses package contains libraries for terminal-independent handling of character screens.

First, build the "tic" program on the build host:

tar -xvf ncurses-6.5.tar.gz
cd ncurses-6.5
mkdir build
pushd build
  ../configure AWK=gawk
  make -C include
  make -C progs tic
popd

Now, prepare Ncurses.

./configure --prefix=/usr                \
            --host=$LFS_TGT              \
            --build=$(./config.guess)    \
            --mandir=/usr/share/man      \
            --with-manpage-format=normal \
            --with-shared                \
            --without-normal             \
            --with-cxx-shared            \
            --without-debug              \
            --without-ada                \
            --disable-stripping          \
            AWK=gawk

make
make DESTDIR=$LFS TIC_PATH=$(pwd)/build/progs/tic install
ln -sv libncursesw.so $LFS/usr/lib/libncurses.so
sed -e 's/^#if.*XOPEN.*$/#if 1/' \
    -i $LFS/usr/include/curses.h

Bash

The Bash package contains the Buourne-Again Shell.

Unzip the package, enter the directory, configure the build, compile and install.

tar -xvf bash-5.2.37.tar.gz
cd bash-5.2.37
./configure --prefix=/usr                      \
            --build=$(sh support/config.guess) \
            --host=$LFS_TGT                    \
            --without-bash-malloc
make
make DESTDIR=$LFS install
ln -sv bash $LFS/bin/sh

Coreutils

The Coreutils package contains the basic utility programs needed by every operating system.

tar -xvf coreutils-9.6.tar.xz
cd coreutils-9.6
./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess) \
            --enable-install-program=hostname \
            --enable-no-install-program=kill,uptime
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/chroot              $LFS/usr/sbin
mkdir -pv $LFS/usr/share/man/man8
mv -v $LFS/usr/share/man/man1/chroot.1 $LFS/usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/'                    $LFS/usr/share/man/man8/chroot.8

Diffutils

The Diffutils package contains programs that show the differences between files or directories.

tar -xvf diffutils-3.11.tar.xz
cd diffutils-3.11
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)
make
make DESTDIR=$LFS install

File

The File package contains a utility for determining the type of a given file or files.

tar -xvf file-5.46.tar.gz
cd file-5.46
mkdir build
pushd build
  ../configure --disable-bzlib      \
               --disable-libseccomp \
               --disable-xzlib      \
               --disable-zlib
  make
popd
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)
make FILE_COMPILE=$(pwd)/build/src/file
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/libmagic.la

Findutils

The findutils package contains programs to find files.

tar -xvf findutils-4.10.0.tar.xz
cd findutils-4.10.0
./configure --prefix=/usr                   \
            --localstatedir=/var/lib/locate \
            --host=$LFS_TGT                 \
            --build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install

Gawk

The Gawk package contains programs for manipulating text files.

tar -xvf gawk-5.3.1.tar.xz
cd gawk-5.3.1
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install

Grep

The Grep package contains programs for searching through the contents of files.

tar -xvf grep-3.11.tar.xz
cd grep-3.11
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)
make
make DESTDIR=$LFS install

Gzip

The Gzip package contains programs for compressing and decompressing files.

tar -xvf gzip-1.13.tar.xz
cd gzip-1.13
./configure --prefix=/usr --host=$LFS_TGT
make
make DESTDIR=$LFS install

Make

The Make package contains a program for controlling the generation of executables and other non-source files of a package from source files.

tar -xvf make-4.4.1.tar.gz
cd make-4.4.1
./configure --prefix=/usr   \
            --without-guile \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install

Patch

The Patch package contains a program for modifying or creating files by applying a "Patch" file typically created by the diff program.

tar -xvf patch-2.7.6.tar.xz
cd patch-2.7.6
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install

Sed

The Sed package contains a stream editor.

tar -xvf sed-4.9.tar.xz
cd sed-4.9
./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)
make
make DESTDIR=$LFS install

Tar

The Tar package provides the ability to create tar archives as well as perform various other kinds of archive manipulation. Tar can be used on previously created archives to extract files, to store additional files, or to update or list files which were already stored.

tar -xvf tar-1.35.tar.xz
cd tar-1.35
./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install

Xz

The Xz package contains programs for compressing and decompressing files.

tar -xvf xz-5.6.4.tar.xz
cd xz-5.6.4
./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess) \
            --disable-static                  \
            --docdir=/usr/share/doc/xz-5.6.4
make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/liblzma.la

Binutils phase 2

The Binutils package contains a linker, an assembler, and other tools for handling object files.

For second phase of the compilation we will eliminate the previous folder and extract again the source code.

rm -rf binutils-2.44/
tar -xvf binutils-2.44.tar.xz
cd binutils-2.44
sed '6031s/$add_dir//' -i ltmain.sh

Now, we will configure the build, compile and install.

mkdir -v build
cd       build
../configure                   \
    --prefix=/usr              \
    --build=$(../config.guess) \
    --host=$LFS_TGT            \
    --disable-nls              \
    --enable-shared            \
    --enable-gprofng=no        \
    --disable-werror           \
    --enable-64-bit-bfd        \
    --enable-new-dtags         \
    --enable-default-hash-style=gnu
make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes,sframe}.{a,la}

GCC phase 2

The GCC package contains the GNU compiler collection, which includes the C and C++ compilers.

So again, we will eliminate the previous folder and extract again the source code.

rm -rf gcc-14.2.0/
tar -xvf gcc-14.2.0.tar.xz
cd gcc-14.2.0

We bring the dependencies.

tar -xf ../mpfr-4.2.1.tar.xz
mv -v mpfr-4.2.1 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc

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

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

Override the building rule of libgcc and libstdc++ headers, to allow building these libraries with POSIX threads support:

sed '/thread_header =/s/@.*@/gthr-posix.h/' \
    -i libgcc/Makefile.in libstdc++-v3/include/Makefile.in

Now, we will configure the build, compile and install.

mkdir -v build
cd       build
../configure                                       \
    --build=$(../config.guess)                     \
    --host=$LFS_TGT                                \
    --target=$LFS_TGT                              \
    LDFLAGS_FOR_TARGET=-L$PWD/$LFS_TGT/libgcc      \
    --prefix=/usr                                  \
    --with-build-sysroot=$LFS                      \
    --enable-default-pie                           \
    --enable-default-ssp                           \
    --disable-nls                                  \
    --disable-multilib                             \
    --disable-libatomic                            \
    --disable-libgomp                              \
    --disable-libquadmath                          \
    --disable-libsanitizer                         \
    --disable-libssp                               \
    --disable-libvtv                               \
    --enable-languages=c,c++
make
make DESTDIR=$LFS install
ln -sv gcc $LFS/usr/bin/cc

This will take a while.

Entering Chroot and Building additional temporary tools

The chroot environment is completely insolated from the host operating system, except for the running kernel. From now on all the commands must be executed as root user and be sure to have the LFS variable set.

su root

Changing Ownership

As most of the commands in previous sections were executed as the user lfs, now we need to change the ownership to root user.

chown --from lfs -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
  x86_64) chown --from lfs -R root:root $LFS/lib64 ;;
esac

Preparing virtual Kernel File Systems

Let's create the directories where the file system will be mounted.

mkdir -pv $LFS/{dev,proc,sys,run}

During a normal boot of the LFS system, the kernel automatically mounts the devtmpfs file system on the /dev directory, so we need mount it manually.

mount -v --bind /dev $LFS/dev

Now, we mount the remaining virtual kernel file systems.

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

In some host systems, /dev/shm is a symbolic link to a directory, typically /run/shm, so we need to mount it.

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

Entering the Chroot Environment

It is time to enter the chroot environment and finish installing temporary tools.

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

And we should see something like this:

Chroot Environment

This would basically be the root console of our new distribution.

Creating Directories

Let's create root-level directories.

mkdir -pv /{boot,home,mnt,opt,srv}

And the required set of subdirectories.

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

In addition to this we must constantly make sure that the /usr/lib64 directory does not exist, this will probably break your system.

First, we need to satisfy the utilities that solve /etc/mtab.

ln -sv /proc/self/mounts /etc/mtab

Create a basic /etc/hosts file.

cat > /etc/hosts << EOF
127.0.0.1  localhost $(hostname)
::1        localhost
EOF

Create the /etc/passwd file.

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF

Create the /etc/group file.

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:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
input:x:24:
mail:x:34:
kvm:x:61:
uuidd:x:80:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF

Soon we will need to do some test with a regular user, so let's create it.

echo "tester:x:101:101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester

At this point we can start a new shell to remove I have no name! message.

exec /usr/bin/bash --login

And our shell should look like this now:

(lfs chroot) root:/# 

Now, let's initialize log files and give them proper permissions.

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

Additional temporary tools

Let's move to the sources directory to continue installing tools.

cd /sources

Gettext

The Gettext package contains utilities for internationalization and localization.

Unzip the package Gettext.

tar -xvf gettext-0.24.tar.xz 
cd gettext-0.24

Configure:

./configure --disable-shared

And compile:

make

Install msgfmt, msgmerge and xgettext programs:

cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin

Bison

The Bison package provides a parser generator.

Unzip the package Bison, enter the directory, configure, compile and install.

tar -xvf bison-3.8.2.tar.xz 
cd bison-3.8.2
./configure --prefix=/usr \
            --docdir=/usr/share/doc/bison-3.8.2
make 
make install

Perl

The Perl package contains the practical extraction and report language.

Unzip the package Perl, enter the directory, configure, compile and install.

tar -xvf perl-5.40.1.tar.xz
cd perl-5.40.1
sh Configure -des                                         \
             -D prefix=/usr                               \
             -D vendorprefix=/usr                         \
             -D useshrplib                                \
             -D privlib=/usr/lib/perl5/5.40/core_perl     \
             -D archlib=/usr/lib/perl5/5.40/core_perl     \
             -D sitelib=/usr/lib/perl5/5.40/site_perl     \
             -D sitearch=/usr/lib/perl5/5.40/site_perl    \
             -D vendorlib=/usr/lib/perl5/5.40/vendor_perl \
             -D vendorarch=/usr/lib/perl5/5.40/vendor_perl
make
make install

Python

The Python 3 package contains the Python development environment.

Unzip the package of Python, enter the directory, configure, compile and install.

Top tip

There are two package files whose name starts with the "python" prefix. The one to extract form is you notice the uppercase first letter. (Python-3.13.2.tar.xz)

tar -xvf Python-3.13.2.tar.xz
cd Python-3.13.2
./configure --prefix=/usr   \
            --enable-shared \
            --without-ensurepip
make
make install

Texinfo

The Textinfo package contains programs for reading, writing and converting info pages.

Unzip the package, enter the directory, configure, compile and install.

tar -xvf texinfo-7.2.tar.xz
cd texinfo-7.2
./configure --prefix=/usr
make
make install

Util-linux

The Util-linux package contains miscellaneous utility programs.

Unzip the package, enter the directory.

tar -xvf util-linux-2.40.4.tar.xz 
cd util-linux-2.40.4

It is recommended using the /var/lib/hwclock directory instead of the usual /etc directory as the location for the adjtime file. Create the directory.

mkdir -pv /var/lib/hwclock

Configure, compile and install.

./configure --libdir=/usr/lib     \
            --runstatedir=/run    \
            --disable-chfn-chsh   \
            --disable-login       \
            --disable-nologin     \
            --disable-su          \
            --disable-setpriv     \
            --disable-runuser     \
            --disable-pylibmount  \
            --disable-static      \
            --disable-liblastlog2 \
            --without-python      \
            ADJTIME_PATH=/var/lib/hwclock/adjtime \
            --docdir=/usr/share/doc/util-linux-2.40.4
make
make install

Cleaning up

First, remove the currently installed documentation files.

rm -rf /usr/share/{info,man,doc}/*

Now, remove the libtool .la files, are only useful for libltdl.

find /usr/{lib,libexec} -name \*.la -delete

And the directory /tools is no longer needed.

rm -rf /tools

Backup

At this point the current LFS system is in a good state, Creating a backup of the current system may prove useful.

The following steps are performed from outside the chroot environment.

Leave the chroot environment.

exit

Once outside the chroot environment, make sure you are root user and the content of the LFS variable be /mnt/lfs.

root@debian:~$ echo $LFS
/mnt/lfs

Now, unmount the virtual file systems.

mountpoint -q $LFS/dev/shm && umount $LFS/dev/shm
umount $LFS/dev/pts
umount $LFS/{sys,proc,run,dev}

Before creating the backup, we should delete the folder of each package we install in /sources directory.

cd $LFS/sources
rm -rf */

With this we are left with only .tar files.

Now, we can create a backup of the current system.

cd $LFS
tar -cJpf $HOME/lfs-temp-tools-12.3.tar.xz .

This take a while to complete, be patient.

Building the LFS System

Once here, we going to enter the chroot environment again, but we must be sure that the /dev directory, virtual kernel file system is mounted and link /dev/shm is created.

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

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

Now, enter the chroot environment.

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

Now inside the chroot environment, let's install the packages definitives.

For some packages I not add description, because I added he description in the previous chapters.

Man pages in LFS

The Man-pages package contains the manual pages.

Unzip the package.

tar -xf man-pages-6.12.tar.xz
cd man-pages-6.12

Remove two man pages for password hashing functions. Libxcrypt will provide a better version of these man pages:

rm -v man3/crypt*

And install the package.

make -R GIT=false prefix=/usr install

Iana-Etc in LFS

The Iana-Etc package provides data for network services and protocols.

Unzip the package.

tar -xvf iana-etc-20250123.tar.gz
cd iana-etc-20250123

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

cp services protocols /etc

Glibc in LFS

The Glibc package contains the main C library.

tar -xvf glibc-2.41.tar.xz
cd glibc-2.41
patch -Np1 -i ../glibc-2.41-fhs-1.patch
mkdir -v build
cd       build
echo "rootsbindir=/usr/sbin" > configparms
../configure --prefix=/usr                            \
             --disable-werror                         \
             --enable-kernel=5.4                      \
             --enable-stack-protector=strong          \
             --disable-nscd                           \
             libc_cv_slibdir=/usr/lib
make

This is the definitive installation of the Glibc package in our system, so we need check the package is correcly compiled.

make check

This can take a while to check all the tests, but some may fail.

Glibc check

if you want check which test failed due to timeout run:

grep "Time out" $(find -name \*.out)

Glibc will complain about the absence of /etc/ld.so.conf, so create that file.

touch /etc/ld.so.conf

Fix teh makefile to skip an outdated sanity check that fails:

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

And install the package.

make install

And fix a hardcoded path to the executable loader in the ldd script:

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

Install the locales that can make the system respond in a different language.

localedef -i C -f UTF-8 C.UTF-8
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i el_GR -f ISO-8859-7 el_GR
localedef -i en_GB -f ISO-8859-1 en_GB
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_ES -f ISO-8859-15 es_ES@euro
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i is_IS -f ISO-8859-1 is_IS
localedef -i is_IS -f UTF-8 is_IS.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f ISO-8859-15 it_IT@euro
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
localedef -i nl_NL@euro -f ISO-8859-15 nl_NL@euro
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i se_NO -f UTF-8 se_NO.UTF-8
localedef -i ta_IN -f UTF-8 ta_IN.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
localedef -i zh_HK -f BIG5-HKSCS zh_HK.BIG5-HKSCS
localedef -i zh_TW -f UTF-8 zh_TW.UTF-8

and make the locales available for the system.

make localedata/install-locales

Now, there are two locales that will be needed for testing in the near future.

localedef -i C -f UTF-8 C.UTF-8
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true

Now, we going to configure glibc.

Let's create /etc/nsswitch.conf file.

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

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

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

# End /etc/nsswitch.conf
EOF

To add timezone data:

tar -xf ../../tzdata2025a.tar.gz

ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}

for tz in etcetera southamerica northamerica europe africa antarctica  \
          asia australasia backward; do
    zic -L /dev/null   -d $ZONEINFO       ${tz}
    zic -L /dev/null   -d $ZONEINFO/posix ${tz}
    zic -L leapseconds -d $ZONEINFO/right ${tz}
done

cp -v zone.tab zone1970.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO tz

Now let's select local timezone.

tzselect
Tzselect

Select the option for your timezone.

Select country

And your country, after confirm.

Once confirmed you will pay attention to the timezone you have selected in the output.

export TZ='America/Bogota'

And create the /etc/localtime file as symlink.

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

Right, now to finish we need configure the Dynamic Loader.

Create /etc/ld.so.conf file.

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

EOF

And for dynamic loader also search a directory and include the contents of file found there.

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

EOF
mkdir -pv /etc/ld.so.conf.d

Zlib in LFS

To extract, prepare compilation, make, check and install zlib.

tar -xvf zlib-1.3.1.tar.gz
cd zlib-1.3.1
./configure --prefix=/usr
make
make check
make install

After that, remove a useless static library.

rm -fv /usr/lib/libz.a

Bzip2 in LFS

Unzip the package.

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

For bzip2, we need apply a patch to the source code.

patch -Np1 -i ../bzip2-1.0.8-install_docs-1.patch
sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile
sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile

Then prepare the compilation.

make -f Makefile-libbz2_so
make clean
make
make PREFIX=/usr install

And install shared library and bzip2 binary.

cp -av libbz2.so.* /usr/lib
ln -sv libbz2.so.1.0.8 /usr/lib/libbz2.so
cp -v bzip2-shared /usr/bin/bzip2
for i in /usr/bin/{bzcat,bunzip2}; do
  ln -sfv bzip2 $i
done

Finally, remove static libraries.

rm -fv /usr/lib/libbz2.a

Xz in LFS

Extract the package, configure compilation, make, check and install.

tar -xvf xz-5.6.4.tar.xz
cd xz-5.6.4
./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/xz-5.6.4
make
make check
make install

Lz4 in LFS

Lz4 is a lossless compression algorithm, providing compression speed greater than 500 MB/s per core.

Extract, compile, check and install.

tar -xvf lz4-1.10.0.tar.gz
cd lz4-1.10.0
make BUILD_STATIC=no PREFIX=/usr
make -j1 check
make BUILD_STATIC=no PREFIX=/usr install

Zstd in LFS

Zstandard is a real-time compression algorithm, providing high compression ratios.

To extract, compile, check and install.

tar -xvf zstd-1.5.7.tar.gz
cd zstd-1.5.7
make prefix=/usr
make check
make prefix=/usr install

Remove the static library.

rm -v /usr/lib/libzstd.a

File in LFS

Extract, configure, compile, check and install.

tar -xvf file-5.46.tar.gz
cd file-5.46
./configure --prefix=/usr
make
make check
make install

Readline in LFS

The Readline package is a set of libraries that offer command-line editing and history capabilities.

Extract the package.

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

To prevent errors with the old libraries of readline, we type the following sed command.

sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install
sed -i 's/-Wl,-rpath,[^ ]*//' support/shobj-conf

Configure, compile, check and install.

./configure --prefix=/usr    \
            --disable-static \
            --with-curses    \
            --docdir=/usr/share/doc/readline-8.2.13
make SHLIB_LIBS="-lncursesw"
make install

If you want install the documentation:

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

M4 in LFS

Extract, configure, compile, check and install.

tar -xvf m4-1.4.19.tar.xz
cd m4-1.4.19
./configure --prefix=/usr
make
make check
make install

Bc in LFS

Extract, configure, compile, check and install.

tar -xvf bc-7.0.3.tar.xz
cd bc-7.0.3
CC=gcc ./configure --prefix=/usr -G -O3 -r
make
make test
make install

Flex in LFS

The Flex package contains a utility for generating programs that recognize patterns in text.

Extract, configure, compile, check and install.

tar -xvf flex-2.6.4.tar.gz
cd flex-2.6.4
./configure --prefix=/usr \
            --docdir=/usr/share/doc/flex-2.6.4 \
            --disable-static
make
make check 
make install

Some programs try use lex instead of flex, so we need to create a symlink.

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

Tcl in LFS

The Tcl package contains the Tool Command Language, a robust general-purpose scripting language.

Extract, configure, compile, check and install.

tar -xvf tcl8.6.16-src.tar.gz
cd tcl8.6.16
SRCDIR=$(pwd)
cd unix
./configure --prefix=/usr           \
            --mandir=/usr/share/man \
            --disable-rpath
make
sed -e "s|$SRCDIR/unix|/usr/lib|" \
    -e "s|$SRCDIR|/usr/include|"  \
    -i tclConfig.sh
sed -e "s|$SRCDIR/unix/pkgs/tdbc1.1.10|/usr/lib/tdbc1.1.10|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.10/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/tdbc1.1.10/library|/usr/lib/tcl8.6|" \
    -e "s|$SRCDIR/pkgs/tdbc1.1.10|/usr/include|"            \
    -i pkgs/tdbc1.1.10/tdbcConfig.sh
sed -e "s|$SRCDIR/unix/pkgs/itcl4.3.2|/usr/lib/itcl4.3.2|" \
    -e "s|$SRCDIR/pkgs/itcl4.3.2/generic|/usr/include|"    \
    -e "s|$SRCDIR/pkgs/itcl4.3.2|/usr/include|"            \
    -i pkgs/itcl4.3.2/itclConfig.sh
unset SRCDIR
make test
make install

Make the installed library writable.

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

Install the headers, make necessary symlink and rename man pages.

make install-private-headers
ln -sfv tclsh8.6 /usr/bin/tclsh
mv /usr/share/man/man3/{Thread,Tcl_Thread}.3

If you want install the documentation:

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

Expect in LFS

The expect package contains tools for automating, via scripted dialogues, interactive applications.

Extract and enter the directory.

tar -xvf expect5.45.4.tar.gz
cd expect5.45.4

Expect needs PTY to work, Verify that.

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

So, let's apply a patch to the source code, prepare compilation, make, check and install.

patch -Np1 -i ../expect-5.45.4-gcc14-1.patch
./configure --prefix=/usr           \
            --with-tcl=/usr/lib     \
            --enable-shared         \
            --disable-rpath         \
            --mandir=/usr/share/man \
            --with-tclinclude=/usr/include
make 
make test
make install
ln -svf expect5.45.4/libexpect5.45.4.so /usr/lib

DejaGNU in LFS

The DejaGNU package contains a framework for running test suites on GNU tools.

Extract, prepare compilation, make, check and install.

tar -xvf dejagnu-1.6.3.tar.gz
cd dejagnu-1.6.3
mkdir -v build
cd       build
../configure --prefix=/usr
makeinfo --html --no-split -o doc/dejagnu.html ../doc/dejagnu.texi
makeinfo --plaintext       -o doc/dejagnu.txt  ../doc/dejagnu.texi
make check
make install
install -v -dm755  /usr/share/doc/dejagnu-1.6.3
install -v -m644   doc/dejagnu.{html,txt} /usr/share/doc/dejagnu-1.6.3

Pkgconf in LFS

The pkgconf package is a successor to pkg-config and contains a tool for passing the include path and library path to applications.

Extract, configure, compile and install.

tar -xvf pkgconf-2.3.0.tar.xz
cd pkgconf-2.3.0
./configure --prefix=/usr              \
            --disable-static           \
            --docdir=/usr/share/doc/pkgconf-2.3.0
make 
make install

For maintain compatibility with the original pkg-config, create two symlinks.

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

Binutils in LFS

Extract, configure, compile, check and install.

tar -xvf binutils-2.44.tar.xz
cd binutils-2.44
mkdir -v build
cd       build
../configure --prefix=/usr       \
             --sysconfdir=/etc   \
             --enable-ld=default \
             --enable-plugins    \
             --enable-shared     \
             --disable-werror    \
             --enable-64-bit-bfd \
             --enable-new-dtags  \
             --with-system-zlib  \
             --enable-default-hash-style=gnu
make tooldir=/usr
make -k check
make tooldir=/usr install

You can list failed tests with:

grep '^FAIL:' $(find -name '*.log')

Finally, remove useless static libraries.

rm -rfv /usr/lib/lib{bfd,ctf,ctf-nobfd,gprofng,opcodes,sframe}.a \
        /usr/share/doc/gprofng/

GMP in LFS

The GMP package contains math libraries. These have usefull functions for arbitrary precision arithmetic.

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

Top tip

If you are building for 32-bit, but have a processor that supports 64-bit instructions, add the ABI=32 parameter to the ./configure command.

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

Then, compile, generate html documentation and run tests.

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

You need ensure at least 199 test in the result test suite passed.

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

Install the package.

make install
make install-html

MPFR in LFS

The MPFR package contains functions for multiple precision math.

tar -xvf mpfr-4.2.1.tar.xz
cd mpfr-4.2.1
./configure --prefix=/usr        \
            --disable-static     \
            --enable-thread-safe \
            --docdir=/usr/share/doc/mpfr-4.2.1
make 
make html

The tests suite are considered critical, so you need to ensure that all tests passed.

make check 

Install the package.

make install
make install-html

MPC in LFS

The MPC package contains a library for the arithmetic of complex numbers with arbitrary high precision and correct rounding of the result.

Extract, configure, compile, check and install.

tar -xvf mpc-1.3.1.tar.gz
cd mpc-1.3.1
./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/mpc-1.3.1
make
make html
make check
make install
make install-html

Attr in LFS

The Attr package contains utilities to administrer the extended attributes of filesystem objects.

Extract, configure, compile, check and install.

tar -xvf attr-2.5.2.tar.gz
cd attr-2.5.2
./configure --prefix=/usr     \
            --disable-static  \
            --sysconfdir=/etc \
            --docdir=/usr/share/doc/attr-2.5.2
make
make check
make install

Acl in LFS

The Acl package contains utilities to administer Access Control Lists, which are used to define fine-grained discretionary access rights for files and directories.

Extract, configure, compile, check and install.

tar -xvf acl-2.3.2.tar.xz
cd acl-2.3.2
./configure --prefix=/usr         \
            --disable-static      \
            --docdir=/usr/share/doc/acl-2.3.2
make
make check 
make install

One test named test/cp.test is known to fail because Coreutils is not built with the Acl support yet.

Libcap in LFS

The Libcap package implements the userspace interface to the POSIX 10003.1e capabilities available in the Linux kernels.

Extract, prevent the static libraries, compile, check and install.

tar -xvf libcap-2.73.tar.xz
cd libcap-2.73
sed -i '/install -m.*STA/d' libcap/Makefile
make prefix=/usr lib=lib
make test
make prefix=/usr lib=lib install

Libxcrypt in LFS

The libxcrypt package contains a modern library for one-way hashing of passwords.

Extract, configure, compile, check and install.

tar -xvf libxcrypt-4.4.38.tar.xz
cd libxcrypt-4.4.38
./configure --prefix=/usr                \
            --enable-hashes=strong,glibc \
            --enable-obsolete-api=no     \
            --disable-static             \
            --disable-failure-tokens
make
make check
make install

Shadow in LFS

The Shadow package contains programs for handling passwords in a secure way.

tar -xvf shadow-4.17.3.tar.xz
cd shadow-4.17.3

Disable the installation of the groups program and its man pages.

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 YESCRYPT:' \
    -e 's:/var/spool/mail:/var/mail:'                   \
    -e '/PATH=/{s@/sbin:@@;s@/bin:@@}'                  \
    -i etc/login.defs

Configure, compile and install.

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

Enable shadowed passwords.

pwconv
grpconv

Change the default parameters of useradd shadow's configuration file.

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

And choose a password for user root.

passwd root

GCC in LFS

Extract the source code.

tar -xvf gcc-14.2.0.tar.xz
cd gcc-14.2.0

Change the default directory name for 64-bit libraries.

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

Now, prepare the build and compile.

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

Set a stack size hard limit to infinite and remove several known test failures.

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

change the to testter user and run.

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

Test can take a while to complete, be patient.

Install the package.

make install

Change the ownership to the root user and group.

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

Now, we need create this symlinks.

ln -svr /usr/bin/cpp /usr/lib
ln -sv gcc.1 /usr/share/man/man1/cc.1
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/14.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/

And finally, to check if all is working, run:

echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
grep -B4 '^ /usr/include' dummy.log
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
grep "/lib.*/libc.so.6 " dummy.log
grep found dummy.log

And the output should be something like this:

Check GCC

Once everything is working, we can remove the test files and move misplaced file.

rm -v dummy.c a.out dummy.log
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib

Ncurses in LFS

Extract, configure and compile.

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

Install the package.

make DESTDIR=$PWD/dest install
install -vm755 dest/usr/lib/libncursesw.so.6.5 /usr/lib
rm -v  dest/usr/lib/libncursesw.so.6.5
sed -e 's/^#if.*XOPEN.*$/#if 1/' \
    -i dest/usr/include/curses.h
cp -av dest/* /
for lib in ncurses form panel menu ; do
    ln -sfv lib${lib}w.so /usr/lib/lib${lib}.so
    ln -sfv ${lib}w.pc    /usr/lib/pkgconfig/${lib}.pc
done
ln -sfv libncursesw.so /usr/lib/libcurses.so

And install Ncurses documentation.

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

Sed in LFS

The Sed package contains a stream editor.

Extract, configure, compile, check and install.

tar -xvf sed-4.9.tar.xz
cd sed-4.9
./configure --prefix=/usr
make
make html
chown -R tester .
su tester -c "PATH=$PATH make check"
make install
install -d -m755           /usr/share/doc/sed-4.9
install -m644 doc/sed.html /usr/share/doc/sed-4.9

Psmisc in LFS

The Psmisc package contains programs for displaying information about running processes.

Extract, configure, compile, check and install.

tar -xvf psmisc-23.7.tar.xz
cd psmisc-23.7
./configure --prefix=/usr
make
make check
make install

Gettext in LFS

Extract, configure, compile, check and install.

tar -xvf gettext-0.24.tar.xz
cd gettext-0.24
./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/gettext-0.24
make
make check
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so

Bison in LFS

Extract, configure, compile, check and install.

tar -xvf bison-3.8.2.tar.xz
cd bison-3.8.2
./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.8.2
make  
make check
make install

Grep in LFS

Extract the package.

tar -xvf grep-3.11.tar.xz
cd grep-3.11

Some tests may fail if you not remove a warning about egrep and fgrep.

sed -i "s/echo/#echo/" src/egrep.sh

Configure, compile, check and install.

./configure --prefix=/usr
make 
make check
make install

Bash in LFS

Extract, configure, compile, check and install.

tar -xvf bash-5.2.37.tar.gz
cd bash-5.2.37
./configure --prefix=/usr             \
            --without-bash-malloc     \
            --with-installed-readline \
            --docdir=/usr/share/doc/bash-5.2.37
make

The test suite we should run as a non-root user.

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

Install the package and run the newly compiled bash program.

make install
exec /usr/bin/bash --login

Libtool in LFS

The Libtool package contains the GNU generic library support script.

Extract, configure, compile, check, install and remove the static library.

tar -xvf libtool-2.5.4.tar.xz
cd libtool-2.5.4
./configure --prefix=/usr
make 
make check
make install
rm -fv /usr/lib/libltdl.a

GDBM in LFS

The GDBM package contains the GNU Database Manager.

Extract, configure, compile, check and install.

tar -xvf gdbm-1.24.tar.gz
cd gdbm-1.24
./configure --prefix=/usr    \
            --disable-static \
            --enable-libgdbm-compat
make
make check
make install

Gperf in LFS

Gperf is a perfect hash function from a key set.

Extract, configure, compile, check and install.

tar -xvf gperf-3.1.tar.gz
cd gperf-3.1
./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1
make
make -j1 check
make install

Expat in LFS

The Expat package contains a stream oriented XML parser in C.

Extract, configure, compile, check and install.

tar -xvf expat-2.6.4.tar.xz
cd expat-2.6.4
./configure --prefix=/usr    \
            --disable-static \
            --docdir=/usr/share/doc/expat-2.6.4
make 
make check 
make install

If you want install the documentation, run:

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

Inetutils in LFS

the Inetutils package contains programs for basic networking.

Extract the source code.

tar -xvf inetutils-2.6.tar.xz
cd inetutils-2.6

Ensure the package build with gcc-14.1 or later.

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

Configure, compile, check, install and move to proper location.

./configure --prefix=/usr        \
            --bindir=/usr/bin    \
            --localstatedir=/var \
            --disable-logger     \
            --disable-whois      \
            --disable-rcp        \
            --disable-rexec      \
            --disable-rlogin     \
            --disable-rsh        \
            --disable-servers
make 
make check 
make install
mv -v /usr/{,s}bin/ifconfig

Less in LFS

The Less package contains a text file viewer.

Extract, configure, compile, check and install.

tar -xvf less-668.tar.gz
cd less-668
./configure --prefix=/usr --sysconfdir=/etc
make
make check
make install

Perl in LFS

Extract the source code.

tar -xvf perl-5.40.1.tar.xz
cd perl-5.40.1

First we need to say perl to use the compress libraries installed on the system.

export BUILD_ZLIB=False
export BUILD_BZIP2=0

Configure, compile, check and install.

sh Configure -des                                          \
             -D prefix=/usr                                \
             -D vendorprefix=/usr                          \
             -D privlib=/usr/lib/perl5/5.40/core_perl      \
             -D archlib=/usr/lib/perl5/5.40/core_perl      \
             -D sitelib=/usr/lib/perl5/5.40/site_perl      \
             -D sitearch=/usr/lib/perl5/5.40/site_perl     \
             -D vendorlib=/usr/lib/perl5/5.40/vendor_perl  \
             -D vendorarch=/usr/lib/perl5/5.40/vendor_perl \
             -D man1dir=/usr/share/man/man1                \
             -D man3dir=/usr/share/man/man3                \
             -D pager="/usr/bin/less -isR"                 \
             -D useshrplib                                 \
             -D usethreads
make
TEST_JOBS=$(nproc) make test_harness
make install
unset BUILD_ZLIB BUILD_BZIP2

XML::Parser in LFS

This module is a Perl interface to James Clark's XML parser, expat.

Extract, configure, compile, check and install.

tar -xvf XML-Parser-2.47.tar.gz
cd XML-Parser-2.47
perl Makefile.PL
make
make test
make install

Intltool in LFS

The Intltool is an internalization tool used for extracting translatable strings from source files.

Extract the source code, fix the warnings caused by perl-5.22, configure, check and install

tar -xvf intltool-0.51.0.tar.gz
cd intltool-0.51.0
sed -i 's:\\\${:\\\$\\{:' intltool-update.in
./configure --prefix=/usr
make
make check
make install

Autoconf in LFS

Extract, configure, compile, check and install.

tar -xvf autoconf-2.72.tar.xz
cd autoconf-2.72
./configure --prefix=/usr
make
make check
make install

Automake in LFS

The automake package contains programs for generating makefiles for use with Autoconf.

Extract, configure, compile, check and install.

tar -xvf automake-1.17.tar.xz
cd automake-1.17
./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.17
make 
make -j$(($(nproc)>4?$(nproc):4)) check
make install

OpenSSL in LFS

The OpenSSL package contains management tools and libraries relating to cryptography.

Extract, configure, compile, check and install.

tar -xvf openssl-3.4.1.tar.gz
cd openssl-3.4.1
./config --prefix=/usr         \
         --openssldir=/etc/ssl \
         --libdir=lib          \
         shared                \
         zlib-dynamic
make
HARNESS_JOBS=$(nproc) make test
sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile
make MANSUFFIX=ssl install
mv -v /usr/share/doc/openssl /usr/share/doc/openssl-3.4.1

If you want install the documentation, run:

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

Libelf in LFS

Libelf is a library for handling of handling ELF( Executable and Linkable Format) files.

Extract, configure, compile, check and install.

tar -xvf elfutils-0.192.tar.bz2
cd elfutils-0.192
./configure --prefix=/usr                \
            --disable-debuginfod         \
            --enable-libdebuginfod=dummy
make
make check
make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
rm /usr/lib/libelf.a

Libffi in LFS

The Libffi library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time.

Extract, configure, compile, check and install.

tar -xvf libffi-3.4.7.tar.gz
cd libffi-3.4.7
./configure --prefix=/usr          \
            --disable-static       \
            --with-gcc-arch=native.4.7
make
make check
make install

Python in LFS

Extract, configure, compile, check and install.

tar -xvf Python-3.13.2.tar.xz
cd Python-3.13.2
./configure --prefix=/usr       \
            --enable-shared     \
            --with-system-expat \
            --with-ensurepip=yes
make 
make test TESTOPTS="--timeout 120"
make install

For supress warning related to the new version of pip3, run:

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

And if you want install the documentation, run:

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

Flit-Core in LFS

Flit-core is the distribution-building parts of Flit( a packaging tool for simple Python modules).

Extract, build and install.

tar -xvf flit_core-3.11.0.tar.gz
cd flit_core-3.11.0
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist flit_core

Wheel in LFS

Wheel is a Python library that is the reference implementation of the Python wheel packaging standard.

Extract, build and install.

tar -xvf wheel-0.45.1.tar.gz
cd wheel-0.45.1
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist wheel

Setuptools in LFS

Setuptools is a tool used to download build, install, upgrade and uninstall Python packages.

Extract, build and install.

tar -xvf setuptools-75.8.1.tar.gz
cd setuptools-75.8.1
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist setuptools

Ninja in LFS

Ninja is a small build system with a focus on speed.

Extract, configure and install.

tar -xvf ninja-1.12.1.tar.gz
cd ninja-1.12.1
export NINJAJOBS=4
sed -i '/int Guess/a \
  int   j = 0;\
  char* jobs = getenv( "NINJAJOBS" );\
  if ( jobs != NULL ) j = atoi( jobs );\
  if ( j > 0 ) return j;\
' src/ninja.cc
python3 configure.py --bootstrap --verbose
install -vm755 ninja /usr/bin/
install -vDm644 misc/bash-completion /usr/share/bash-completion/completions/ninja
install -vDm644 misc/zsh-completion  /usr/share/zsh/site-functions/_ninja

Meson in LFS

Meson is an open source build system meant to be both extremely fast, and extremely user-friendly.

Extract, compile and install.

tar -xvf meson-1.7.0.tar.gz
cd meson-1.7.0
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist meson
install -vDm644 data/shell-completions/bash/meson /usr/share/bash-completion/completions/meson
install -vDm644 data/shell-completions/zsh/_meson /usr/share/zsh/site-functions/_meson

Kmod in LFS

The Kmod package contains libraries and utilities for loading kernel modules.

Extract, configure, compile and install.

tar -xvf kmod-34.tar.xz
cd kmod-34
mkdir -p build
cd       build
meson setup --prefix=/usr ..    \
            --sbindir=/usr/sbin \
            --buildtype=release \
            -D manpages=false
ninja
ninja install

Coreutils in LFS

Extract, apply a patch, configure, compile, check and install.

tar -xvf coreutils-9.6.tar.xz
cd coreutils-9.6
patch -Np1 -i ../coreutils-9.6-i18n-1.patch
autoreconf -fv
automake -af
FORCE_UNSAFE_CONFIGURE=1 ./configure \
            --prefix=/usr            \
            --enable-no-install-program=kill,uptime
make 
make NON_ROOT_USERNAME=tester check-root
groupadd -g 102 dummy -U tester
chown -R tester . 
su tester -c "PATH=$PATH make -k RUN_EXPENSIVE_TESTS=yes check" \
   < /dev/null
groupdel dummy
make install
mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' /usr/share/man/man8/chroot.8

Check in LFS

Check is a unit testing framework for C.

Extract, configure, compile, check and install.

tar -xvf check-0.15.2.tar.gz
cd check-0.15.2
./configure --prefix=/usr --disable-static
make
make check
make docdir=/usr/share/doc/check-0.15.2 install

Diffutils in LFS

Extract, configure, compile, check and install.

tar -xvf diffutils-3.11.tar.xz
cd diffutils-3.11
./configure --prefix=/usr
make
make check
make install

Gawk in LFS

The Gawk package contains programs for manipulating text files.

Extract, configure, compile, check and install.

tar -xvf gawk-5.3.1.tar.xz
cd gawk-5.3.1
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr
make
chown -R tester .
su tester -c "PATH=$PATH make check"
rm -f /usr/bin/gawk-5.3.1
make install

Findutils in LFS

Extract, configure, compile, check and install.

tar -xvf findutils-4.10.0.tar.xz
cd findutils-4.10.0
./configure --prefix=/usr --localstatedir=/var/lib/locate
make
chown -R tester .
su tester -c "PATH=$PATH make check"
make install

Groff in LFS

The Groff package contains programs for processing and formatting text and images.

Extract, configure, compile, check and install.

tar -xvf groff-1.23.0.tar.gz
cd groff-1.23.0
PAGE=A4 ./configure --prefix=/usr
make
make check
make install

GRUB in LFS

The GRUB package provides Grand Unified Bootloader. In this page it will be built with UEFI suppert, which is not enabled for GRUP build in LFS.

Extract the package, configure, compile and install.

tar -xvf grub-2.12.tar.xz
cd grub-2.12
unset {C,CPP,CXX,LD}FLAGS
./configure --prefix=/usr        \
            --sysconfdir=/etc    \
            --disable-efiemu     \
            --with-platform=efi  \
            --target=x86_64      \
            --disable-werror     &&
make
make install &&
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions

Gzip in LFS

Extract, configure, compile, check and install.

tar -xvf gzip-1.13.tar.xz
cd gzip-1.13
./configure --prefix=/usr
make
make check
make install

Iproute2 in LFS

The IPRoute2 package conatins programs for basic and advanced IPV4-based networking.

Extract, configure, compile and install.

tar -xvf iproute2-6.13.0.tar.xz
cd iproute2-6.13.0
sed -i /ARPD/d Makefile
rm -fv man/man8/arpd.8
make NETNS_RUN_DIR=/run/netns
make SBINDIR=/usr/sbin install

Install the documentation.

install -vDm644 COPYING README* -t /usr/share/doc/iproute2-6.13.0

Kbd in LFS

The Kdb package contains key-table files, console fonts, and keyboard utilities.

Extract, apply a patch, configure, compile and install.

tar -xvf kbd-2.7.1.tar.xz
cd kbd-2.7.1
patch -Np1 -i ../kbd-2.7.1-backspace-1.patch
sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in
./configure --prefix=/usr --disable-vlock
make
make check
make install

Libpipeline in LFS

The Libpipeline package contains a library for manipulating pipelines of subprocesses in a flexible and convenient way.

Extract, configure, compile and install.

tar -xvf libpipeline-1.5.8.tar.gz
cd libpipeline-1.5.8
./configure --prefix=/usr
make
make check
make install

Make in LFS

The Make package contains a program for controlling the generation of executables and other non-source files of a package from source files.

Extract, configure, compile and install.

tar -xvf make-4.4.1.tar.gz
cd make-4.4.1
./configure --prefix=/usr
make
chown -R tester .
su tester -c "PATH=$PATH make check"
make install

Patch in LFS

The Patch package contains a program for modifying or creating files.

Extract, configure, compile and install.

tar -xvf patch-2.7.6.tar.xz
cd patch-2.7.6
./configure --prefix=/usr
make
make check
make install

Tar in LFS

The Tar package provides a program for manipulating tar archives.

Extract, configure, compile, check and install.

tar -xvf tar-1.35.tar.xz
cd tar-1.35
FORCE_UNSAFE_CONFIGURE=1  \
./configure --prefix=/usr
make
make check
make install
make -C doc install-html docdir=/usr/share/doc/tar-1.35

Textinfo in LFS

Extract, configure, compile and install.

tar -xvf texinfo-7.2.tar.xz
cd texinfo-7.2
./configure --prefix=/usr
make
make install
make TEXMF=/usr/share/texmf install-tex

Vim in LFS

The Vim package contains a powerful text editor.

Extract, configure, compile and install.

tar -xvf vim-9.1.1166.tar.gz
cd vim-9.1.1166
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
./configure --prefix=/usr
make
chown -R tester .
sed '/test_plugin_glvs/d' -i src/testdir/Make_all.mak
su tester -c "TERM=xterm-256color LANG=en_US.UTF-8 make -j1 test" \
   &> vim-test.log
make install

Create this symbolic links.

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/vim91/doc /usr/share/doc/vim-9.1.1166

Markupsafe in LFS

Markupsafe is a library for parsing and compiling XML, HTML and XHTML.

Extract, compile and install.

tar -xvf markupsafe-3.0.2.tar.gz
cd markupsafe-3.0.2
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist Markupsafe

Jinja2 in LFS

Jinja2 is a Python module that implements a simple pythonic template lenguage.

Extract, compile and install.

tar -xvf jinja2-3.1.5.tar.gz
cd jinja2-3.1.5
pip3 wheel -w dist --no-cache-dir --no-build-isolation --no-deps $PWD
pip3 install --no-index --find-links dist Jinja2

Udev from Systemd in LFS

The Udev package contains programs for dynamic creation of device nodes.

tar -xvf systemd-257.3.tar.gz
cd systemd-257.3

Before building, remove some things.

sed -e 's/GROUP="render"/GROUP="video"/' \
    -e 's/GROUP="sgx", //'               \
    -i rules.d/50-udev-default.rules.in
sed -i '/systemd-sysctl/s/^/#/' rules.d/99-systemd.rules.in
sed -e '/NETWORK_DIRS/s/systemd/udev/' \
    -i src/libsystemd/sd-network/network-util.h

Configure, compile and install.

mkdir -p build
cd       build
meson setup ..                  \
      --prefix=/usr             \
      --buildtype=release       \
      -D mode=release           \
      -D dev-kvm-mode=0660      \
      -D link-udev-shared=false \
      -D logind=false           \
      -D vconsole=false
export udev_helpers=$(grep "'name' :" ../src/udev/meson.build | \
                      awk '{print $3}' | tr -d ",'" | grep -v 'udevadm')
ninja udevadm systemd-hwdb                                           \
      $(ninja -n | grep -Eo '(src/(lib)?udev|rules.d|hwdb.d)/[^ ]*') \
      $(realpath libudev.so --relative-to .)                         \
      $udev_helpers

And install the package.

install -vm755 -d {/usr/lib,/etc}/udev/{hwdb.d,rules.d,network}
install -vm755 -d /usr/{lib,share}/pkgconfig
install -vm755 udevadm                             /usr/bin/
install -vm755 systemd-hwdb                        /usr/bin/udev-hwdb
ln      -svfn  ../bin/udevadm                      /usr/sbin/udevd
cp      -av    libudev.so{,*[0-9]}                 /usr/lib/
install -vm644 ../src/libudev/libudev.h            /usr/include/
install -vm644 src/libudev/*.pc                    /usr/lib/pkgconfig/
install -vm644 src/udev/*.pc                       /usr/share/pkgconfig/
install -vm644 ../src/udev/udev.conf               /etc/udev/
install -vm644 rules.d/* ../rules.d/README         /usr/lib/udev/rules.d/
install -vm644 $(find ../rules.d/*.rules \
                      -not -name '*power-switch*') /usr/lib/udev/rules.d/
install -vm644 hwdb.d/*  ../hwdb.d/{*.hwdb,README} /usr/lib/udev/hwdb.d/
install -vm755 $udev_helpers                       /usr/lib/udev
install -vm644 ../network/99-default.link          /usr/lib/udev/network
tar -xvf ../../udev-lfs-20230818.tar.xz
make -f udev-lfs-20230818/Makefile.lfs install
tar -xf ../../systemd-man-pages-257.3.tar.xz                            \
    --no-same-owner --strip-components=1                              \
    -C /usr/share/man --wildcards '*/udev*' '*/libudev*'              \
                                  '*/systemd.link.5'                  \
                                  '*/systemd-'{hwdb,udevd.service}.8
sed 's|systemd/network|udev/network|'                                 \
    /usr/share/man/man5/systemd.link.5                                \
  > /usr/share/man/man5/udev.link.5
sed 's/systemd\(\\\?-\)/udev\1/' /usr/share/man/man8/systemd-hwdb.8   \
                               > /usr/share/man/man8/udev-hwdb.8
sed 's|lib.*udevd|sbin/udevd|'                                        \
    /usr/share/man/man8/systemd-udevd.service.8                       \
  > /usr/share/man/man8/udevd.8
rm /usr/share/man/man*/systemd*
unset udev_helpers

And configure.

udev-hwdb update

Man-DB in LFS

The Man-DB package contains a collection of man pages.

Extract, configure, compile and install.

tar -xvf man-db-2.13.0.tar.xz
cd man-db-2.13.0
./configure --prefix=/usr                         \
            --docdir=/usr/share/doc/man-db-2.13.0 \
            --sysconfdir=/etc                     \
            --disable-setuid                      \
            --enable-cache-owner=bin              \
            --with-browser=/usr/bin/lynx          \
            --with-vgrind=/usr/bin/vgrind         \
            --with-grap=/usr/bin/grap             \
            --with-systemdtmpfilesdir=            \
            --with-systemdsystemunitdir=
make
make check
make install

Procps-ng in LFS

The Procps-ng package contains programs for monitoring system processes.

Extract, configure, compile and install.

tar -xvf procps-ng-4.0.5.tar.xz
cd procps-ng-4.0.5
./configure --prefix=/usr                           \
            --docdir=/usr/share/doc/procps-ng-4.0.5 \
            --disable-static                        \
            --disable-kill                          \
            --enable-watch8bit
make
chown -R tester .
su tester -c "PATH=$PATH make check"
make install

Util-linux in LFS

The Util-linux package contains various programs for manipulating Linux filesystems.

Extract, configure, compile, check and install.

tar -xvf util-linux-2.40.4.tar.xz
cd util-linux-2.40.4
./configure --bindir=/usr/bin     \
            --libdir=/usr/lib     \
            --runstatedir=/run    \
            --sbindir=/usr/sbin   \
            --disable-chfn-chsh   \
            --disable-login       \
            --disable-nologin     \
            --disable-su          \
            --disable-setpriv     \
            --disable-runuser     \
            --disable-pylibmount  \
            --disable-liblastlog2 \
            --disable-static      \
            --without-python      \
            --without-systemd     \
            --without-systemdsystemunitdir        \
            ADJTIME_PATH=/var/lib/hwclock/adjtime \
            --docdir=/usr/share/doc/util-linux-2.40.4
make
bash tests/run.sh --srcdir=$PWD --builddir=$PWD
touch /etc/fstab
chown -R tester .
su tester -c "make -k check"
make install

E2fsprogs in LFS

The E2fsprogs package contains programs for creating and managing ext2/ext3/ext4 filesystems.

Extract, configure, compile and install.

tar -xvf e2fsprogs-1.47.2.tar.gz
cd e2fsprogs-1.47.2
mkdir -v build
cd       build
../configure --prefix=/usr           \
             --sysconfdir=/etc       \
             --enable-elf-shlibs     \
             --disable-libblkid      \
             --disable-libuuid       \
             --disable-uuidd         \
             --disable-fsck
make
make check
make install

Remove the static libraries and install additional documentation.

rm -fv /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a
gunzip -v /usr/share/info/libext2fs.info.gz
install-info --dir-file=/usr/share/info/dir /usr/share/info/libext2fs.info

And configure the program.

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

Sysklogd in LFS

The Sysklogd package contains programs for loggin system messages, such as those emitted by the kernel when unusual things happen.

Extract, configure, compile and install.

tar -xvf sysklogd-2.7.0.tar.gz
cd sysklogd-2.7.0
./configure --prefix=/usr      \
            --sysconfdir=/etc  \
            --runstatedir=/run \
            --without-logger   \
            --disable-static   \
            --docdir=/usr/share/doc/sysklogd-2.7.0
make
make install

And configure the program.

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

auth,authpriv.* -/var/log/auth.log
*.*;auth,authpriv.none -/var/log/sys.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
*.emerg *

# Do not open any internet ports.
secure_mode 2

# End /etc/syslog.conf
EOF

Sysvinit in LFS

The SysVinit package conatins a program fro controlling the startup, running, and shutdown of the system.

Extract, apply the patch and compile.

tar -xvf sysvinit-3.14.tar.xz
cd sysvinit-3.14
patch -Np1 -i ../sysvinit-3.14-consolidated-1.patch
make
make install

Stripping and Cleaning Up

This is a one of the final phases in the build of a LFS system, from now we will start mostly with the configuration, but first, we'll reduce the size of everything we carry a little bit.

Stripping

With this proccess, we will remove the debugging symbols from the libraries and binaries and some unnecessary symbol table entries.

Before execute the following commands, make sure that you have a backup of the files.

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.33
             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=zlib $LIB $LIB.dbg
    cp $LIB /tmp/$LIB
    strip --strip-unneeded /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.44.so
               libsframe.so.1.0.0
               libhistory.so.8.2
               libncursesw.so.6.5
               libm.so.6
               libreadline.so.8.2
               libz.so.1.3.1
               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-unneeded /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-unneeded /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-unneeded $i
            ;;
    esac
done

unset BIN LIB save_usrlib online_usrbin online_usrlib

A large number of files will be flagged as errors because their file format is not recognized. These warnings can be safely ignored. They indicate that those files are scripts, not binaries.

Cleaning Up

And finally, clean up some extra files.

rm -rf /tmp/{*,.*}
find /usr/lib /usr/libexec -name \*.la -delete
find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf
userdel -r tester

System configuration

Install LFS-Bootscripts

The LFS-Bootscripts package contains a set of script to start/stop the LFS system at bootup/shutdown.

Extract and install.

tar -xvf lfs-bootscripts-20240825.tar.xz
cd lfs-bootscripts-20240825
make install

General Network Configuration

First you should check what's your network interface name.

ip link show
Network Interface Name

In my case, is ens33.

So let's create a simple configuration with a static IP address.

cd /etc/sysconfig/
cat > ifconfig.ens33 << "EOF"
ONBOOT=yes
IFACE=ens33
SERVICE=ipv4-static
IP=192.168.1.2
GATEWAY=192.168.1.1
PREFIX=24
BROADCAST=192.168.1.255
EOF

Now, let's create the /etc/resolv.conf file.

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

nameserver 8.8.8.8
nameserver 8.8.4.4

# End /etc/resolv.conf
EOF

Configure the hostname.

echo "entr0phy4" > /etc/hostname

And /etc/hosts file.

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

127.0.0.1 localhost
127.0.1.1 entr0phy4 entr0phy4
192.168.1.2 entr0phy4 entr0phy4
::1       localhost ip6-localhost ip6-loopback
ff02::1   ip6-allnodes
ff02::2   ip6-allrouters

# End /etc/hosts
EOF

System V Bootscript configuration

The first program should run at kernel initialization is init. This reads the /etc/inittab, let's create it.

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

id:3:initdefault:

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

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

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

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

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

# End /etc/inittab
EOF

Configure the system clock

We need create a new file /etc/sysconfig/clock.

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

UTC=1

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

# End /etc/sysconfig/clock
EOF

Configure the rc.site

We going to set a variable SYSKLOGD_PARMS in file /etc/sysconfig/rc.site to a null value.

SYSKLOGD_PARMS=

and change the hostname.

HOSTNAME=entr0phy4

Configure system locale

If you need list all the locales can use:

locale -a

After find the locale you want, type:

LC_ALL=en_US.utf8 locale charmap
LC_ALL=en_US.utf8 locale language
LC_ALL=en_US.utf8 locale charmap
LC_ALL=en_US.utf8 locale int_curr_symbol
LC_ALL=en_US.utf8 locale int_prefix

And check not found errors.

cat > /etc/locale.conf << "EOF"
LANG=en_US.utf8
EOF

Creating the inputrc file

the file /etc/inputrc provides editing capabilities while the user is entering a line from the terminal. It works by translating keyboard inputs into specific actions. Readline is used by bash and most other shells as well as many other applications.

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

Creating the /etc/shells file

The shells file contains a list of login shells on the system.

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

/bin/sh
/bin/bash

# End /etc/shells
EOF

Making the LFS bootable

In progress...

More articles

Machine: CrossFit

CrossFit is an insane difficulty Linux box featuring an Apache server that hosts the website of a fictional

Read more

Teletype Treatment

Upgrade simple shell to fully interactive TTY.

Read more