Linux From Scratch - 3
Linux From Scratch - 3
22
Linux From Scratch - Version 11.3
24
Linux From Scratch - Version 11.3
26
Linux From Scratch - Version 11.3
27
Linux From Scratch - Version 11.3
29
Linux From Scratch - Version 11.3
30
Linux From Scratch - Version 11.3
The new instance of the shell is a non-login shell, which does not read, and execute, the contents of the /etc/profile
or .bash_profile files, but rather reads, and executes, the .bashrc file instead. Create the .bashrc file now:
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
33
Linux From Scratch - Version 11.3
CONFIG_SITE=$LFS/usr/share/config.site
In Chapter 5 and Chapter 6, if this variable is not set, configure scripts may attempt to load configuration items
specific to some distributions from /usr/share/config.site on the host system. Override it to prevent potential
contamination from the host.
export ...
While the preceding commands have set some variables, in order to make them visible within any sub-shells, we
export them.
Important
Several commercial distributions add an undocumented instantiation of /etc/bash.bashrc to the initialization
of bash. This file has the potential to modify the lfs user's environment in ways that can affect the building
of critical LFS packages. To make sure the lfs user's environment is clean, check for the presence of /etc/
bash.bashrc and, if present, move it out of the way. As the root user, run:
When the lfs user is no longer needed (at the beginning of Chapter 7), you may safely restore /etc/bash.
bashrc (if desired).
Note that the LFS Bash package we will build in Section 8.34, “Bash-5.2.15” is not configured to load or
execute /etc/bash.bashrc, so this file is useless on a completed LFS system.
Finally, to ensure the environment is fully prepared for building the temporary tools, force the bash shell to read the
new user profile:
source ~/.bash_profile
SBUs are not entirely accurate because they depend on many factors, including the host system's version of GCC. They
are provided here to give an estimate of how long it might take to install a package, but the numbers can vary by as
much as dozens of minutes in some cases.
34
Linux From Scratch - Version 11.3
The build
is the machine where we build programs. Note that this machine is also referred to as the “host”.
The host
is the machine/system where the built programs will run. Note that this use of “host” is not the same as in other
sections.
The target
is only used for compilers. It is the machine the compiler produces code for. It may be different from both the
build and the host.
As an example, let us imagine the following scenario (sometimes referred to as “Canadian Cross”). We have a compiler
on a slow machine only, let's call it machine A, and the compiler ccA. We also have a fast machine (B), but no compiler
for (B), and we want to produce code for a third, slow machine (C). We will build a compiler for machine C in three
stages.
Then, all the programs needed by machine C can be compiled using cc2 on the fast machine B. Note that unless B can
run programs produced for C, there is no way to test the newly built programs until machine C itself is running. For
example, to run a test suite on ccC, we may want to add a fourth stage:
xxxviii
Linux From Scratch - Version 11.3
In the preceding table, “on pc” means the commands are run on a machine using the already installed distribution. “On
lfs” means the commands are run in a chrooted environment.
This is not yet the end of the story. The C language is not merely a compiler; it also defines a standard library. In this
book, the GNU C library, named glibc, is used (there is an alternative, "musl"). This library must be compiled for the
LFS machine; that is, using the cross-compiler cc1. But the compiler itself uses an internal library providing complex
subroutines for functions not available in the assembler instruction set. This internal library is named libgcc, and it must
be linked to the glibc library to be fully functional. Furthermore, the standard library for C++ (libstdc++) must also be
linked with glibc. The solution to this chicken and egg problem is first to build a degraded cc1-based libgcc, lacking
some functionalities such as threads and exception handling, and then to build glibc using this degraded compiler (glibc
itself is not degraded), and also to build libstdc++. This last library will lack some of the functionality of libgcc.
The upshot of the preceding paragraph is that cc1 is unable to build a fully functional libstdc++ with the degraded
libgcc, but cc1 is the only compiler available for building the C/C++ libraries during stage 2. There are two reasons we
don't immediately use the compiler built in stage 2, cc-lfs, to build those libraries.
• Generally speaking, cc-lfs cannot run on pc (the host system). Even though the triplets for pc and lfs are
compatible with each other, an executable for lfs must depend on glibc-2.37; the host distro may utilize either a
different implementation of libc (for example, musl), or a previous release of glibc (for example, glibc-2.13).
• Even if cc-lfs can run on pc, using it on pc would create a risk of linking to the pc libraries, since cc-lfs is a native
compiler.
So when we build gcc stage 2, we instruct the building system to rebuild libgcc and libstdc++ with cc1, but we link
libstdc++ to the newly rebuilt libgcc instead of the old, degraded build. This makes the rebuilt libstdc++ fully functional.
In Chapter 8 (or “stage 3”), all the packages needed for the LFS system are built. Even if a package has already been
installed into the LFS system in a previous chapter, we still rebuild the package. The main reason for rebuilding these
packages is to make them stable: if we reinstall an LFS package on a completed LFS system, the reinstalled content of
the package should be the same as the content of the same package when first installed in Chapter 8. The temporary
packages installed in Chapter 6 or Chapter 7 cannot satisfy this requirement, because some of them are built without
optional dependencies, and autoconf cannot perform some feature checks in Chapter 6 because of cross-compilation,
causing the temporary packages to lack optional features, or use suboptimal code routines. Additionally, a minor reason
for rebuilding the packages is to run the test suites.
xl
Linux From Scratch - Version 11.3
Binutils is installed first because the configure runs of both gcc and glibc perform various feature tests on the assembler
and linker to determine which software features to enable or disable. This is more important than one might realize at
first. An incorrectly configured gcc or glibc can result in a subtly broken toolchain, where the impact of such breakage
might not show up until near the end of the build of an entire distribution. A test suite failure will usually highlight this
error before too much additional work is performed.
Binutils installs its assembler and linker in two locations, $LFS/tools/bin and $LFS/tools/$LFS_TGT/bin. The tools in
one location are hard linked to the other. An important facet of the linker is its library search order. Detailed information
can be obtained from ld by passing it the --verbose flag. For example, $LFS_TGT-ld --verbose | grep SEARCH will
illustrate the current search paths and their order. (Note that this example can be run as shown only while logged in as
user lfs. If you come back to this page later, replace $LFS_TGT-ld with ld).
The next package installed is gcc. An example of what can be seen during its run of configure is:
checking what assembler to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/as
checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ld
This is important for the reasons mentioned above. It also demonstrates that gcc's configure script does not search the
PATH directories to find which tools to use. However, during the actual operation of gcc itself, the same search paths
are not necessarily used. To find out which standard linker gcc will use, run: $LFS_TGT-gcc -print-prog-name=ld.
(Again, remove the $LFS_TGT- prefix if coming back to this later.)
Detailed information can be obtained from gcc by passing it the -v command line option while compiling a program. For
example, $LFS_TGT-gcc -v example.c (or without $LFS_TGT- if coming back later) will show detailed information
about the preprocessor, compilation, and assembly stages, including gcc's search paths for included headers and their
order.
Next up: sanitized Linux API headers. These allow the standard C library (glibc) to interface with features that the
Linux kernel will provide.
Next comes glibc. The most important considerations for building glibc are the compiler, binary tools, and kernel
headers. The compiler is generally not an issue since glibc will always use the compiler relating to the --host parameter
passed to its configure script; e.g., in our case, the compiler will be $LFS_TGT-gcc. The binary tools and kernel headers
can be a bit more complicated. Therefore, we take no risks and use the available configure switches to enforce the
correct selections. After the run of configure, check the contents of the config.make file in the build directory for all
important details. Note the use of CC="$LFS_TGT-gcc" (with $LFS_TGT expanded) to control which binary tools are used
and the use of the -nostdinc and -isystem flags to control the compiler's include search path. These items highlight
an important aspect of the glibc package—it is very self-sufficient in terms of its build machinery, and generally does
not rely on toolchain defaults.
As mentioned above, the standard C++ library is compiled next, followed in Chapter 6 by other programs that must
be cross-compiled to break circular dependencies at build time. The install step of all those packages uses the DESTDIR
variable to force installation in the LFS filesystem.
At the end of Chapter 6 the native LFS compiler is installed. First binutils-pass2 is built, in the same DESTDIR directory as
the other programs, then the second pass of gcc is constructed, omitting some non-critical libraries. Due to some weird
logic in gcc's configure script, CC_FOR_TARGET ends up as cc when the host is the same as the target, but different from
the build system. This is why CC_FOR_TARGET=$LFS_TGT-gcc is declared explicitly as one of the configuration options.
Upon entering the chroot environment in Chapter 7, the temporary installations of programs needed for the proper
operation of the toolchain are performed. From this point onwards, the core toolchain is self-contained and self-hosted.
In Chapter 8, final versions of all the packages needed for a fully functional system are built, tested, and installed.
xli