8.5.1. Installation of Glibc
Some of the Glibc programs use the non-FHS compliant /var/db
directory to store their runtime data.
Apply the following patch to make such programs store their runtime
data in the FHS-compliant locations:
patch -Np1 -i ../glibc-2.40-fhs-1.patch
The Glibc documentation recommends building Glibc in a dedicated
build directory:
mkdir -v build
cd build
Ensure that the ldconfig and sln utilities will be installed
into /usr/sbin
:
echo "rootsbindir=/usr/sbin" > configparms
Prepare Glibc for compilation:
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=4.19 \
--enable-stack-protector=strong \
--disable-nscd \
libc_cv_slibdir=/usr/lib
The meaning of the configure options:
-
--disable-werror
-
This option disables the -Werror option passed to GCC. This
is necessary for running the test suite.
-
--enable-kernel=4.19
-
This option tells the build system that this Glibc may be
used with kernels as old as 4.19. This means generating
workarounds in case a system call introduced in a later
version cannot be used.
-
--enable-stack-protector=strong
-
This option increases system security by adding extra code to
check for buffer overflows, such as stack smashing attacks.
Note that Glibc always explicitly overrides the default of
GCC, so this option is still needed even though we've already
specified --enable-default-ssp
for GCC.
-
--disable-nscd
-
Do not build the name service cache daemon which is no longer
used.
-
libc_cv_slibdir=/usr/lib
-
This variable sets the correct library for all systems. We do
not want lib64 to be used.
Compile the package:
make
Important
In this section, the test suite for Glibc is considered critical.
Do not skip it under any circumstance.
Generally a few tests do not pass. The test failures listed below
are usually safe to ignore.
make check
You may see some test failures. The Glibc test suite is somewhat
dependent on the host system. A few failures out of over 5000 tests
can generally be ignored. This is a list of the most common issues
seen for recent versions of LFS:
-
io/tst-lchmod is known
to fail in the LFS chroot environment.
-
Some tests, for example nss/tst-nss-files-hosts-multi and
nptl/tst-thread-affinity* are
known to fail due to a timeout (especially when the system is
relatively slow and/or running the test suite with multiple
parallel make jobs). These tests can be identified with:
grep "Timed out" $(find -name \*.out)
It's possible to re-run a single test with enlarged timeout
with TIMEOUTFACTOR=<factor>
make test
t=<test
name>
. For example,
TIMEOUTFACTOR=10 make test
t=nss/tst-nss-files-hosts-multi will re-run
nss/tst-nss-files-hosts-multi with
ten times the original timeout.
-
Additionally, some tests may fail with a relatively old CPU
model (for example elf/tst-cpu-features-cpuinfo) or
host kernel version (for example stdlib/tst-arc4random-thread).
Though it is a harmless message, the install stage of Glibc will
complain about the absence of /etc/ld.so.conf
. Prevent this warning with:
touch /etc/ld.so.conf
Fix the Makefile to skip an outdated sanity check that fails with a
modern Glibc configuration:
sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile
Important
If upgrading Glibc to a new minor version (for example, from
Glibc-2.36 to Glibc-2.40) on a running LFS system, you need to
take some extra precautions to avoid breaking the system:
-
Upgrading Glibc on a LFS system prior to 11.0 (exclusive)
is not supported. Rebuild LFS if you are running such an
old LFS system but you need a newer Glibc.
-
If upgrading on a LFS system prior to 12.0 (exclusive),
install Libxcrypt
following Section 8.28,
“Libxcrypt-4.4.36.” In addition to a normal
Libxcrypt installation,
you MUST follow the note in
Libxcrypt section to install libcrypt.so.1*
(replacing libcrypt.so.1
from the prior Glibc
installation).
-
If upgrading on a LFS system prior to 12.1 (exclusive),
remove the nscd program:
rm -f /usr/sbin/nscd
-
Upgrade the kernel and reboot if it's older than 4.19
(check the current version with uname -r) or if you want
to upgrade it anyway, following Section 10.3,
“Linux-6.11.1.”
-
Upgrade the kernel API headers if it's older than 4.19
(check the current version with cat
/usr/include/linux/version.h) or if you
want to upgrade it anyway, following Section 5.4,
“Linux-6.11.1 API Headers” (but removing $LFS
from the cp command).
-
Perform a DESTDIR
installation
and upgrade the Glibc shared libraries on the system using
one single install command:
make DESTDIR=$PWD/dest install
install -vm755 dest/usr/lib/*.so.* /usr/lib
It's imperative to strictly follow these steps above unless you
completely understand what you are doing. Any unexpected deviation may render the system
completely unusable. YOU ARE WARNED.
Then continue to run the make
install command, the sed command against
/usr/bin/ldd
, and the commands to
install the locales. Once they are finished, reboot the system
immediately.
Install the package:
make install
Fix a hardcoded path to the executable loader in the ldd script:
sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/ldd
Next, install the locales that can make the system respond in a
different language. None of these locales are required, but if some
of them are missing, the test suites of some packages will skip
important test cases.
Individual locales can be installed using the localedef program. E.g., the
second localedef
command below combines the /usr/share/i18n/locales/cs_CZ
charset-independent
locale definition with the /usr/share/i18n/charmaps/UTF-8.gz
charmap
definition and appends the result to the /usr/lib/locale/locale-archive
file. The
following instructions will install the minimum set of locales
necessary for the optimal coverage of tests:
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
In addition, install the locale for your own country, language and
character set.
Alternatively, install all the locales listed in the glibc-2.40/localedata/SUPPORTED
file (it includes
every locale listed above and many more) at once with the following
time-consuming command:
make localedata/install-locales
Then use the localedef command to create and
install locales not listed in the glibc-2.40/localedata/SUPPORTED
file when you
need them. For instance, the following two locales are needed for
some tests later in this chapter:
localedef -i C -f UTF-8 C.UTF-8
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true
Note
Glibc now uses libidn2 when resolving internationalized domain
names. This is a run time dependency. If this capability is
needed, the instructions for installing libidn2 are in the
BLFS libidn2 page.
8.5.2. Configuring Glibc
8.5.2.1. Adding nsswitch.conf
The /etc/nsswitch.conf
file needs
to be created because the Glibc defaults do not work well in a
networked environment.
Create a new file /etc/nsswitch.conf
by running the following:
cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF
8.5.2.2. Adding Time Zone Data
Install and set up the time zone data with the following:
tar -xf ../../tzdata2024b.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
The meaning of the zic commands:
-
zic -L
/dev/null ...
-
This creates posix time zones without any leap seconds. It
is conventional to put these in both zoneinfo
and zoneinfo/posix
. It is necessary to put
the POSIX time zones in zoneinfo
, otherwise various test suites
will report errors. On an embedded system, where space is
tight and you do not intend to ever update the time zones,
you could save 1.9 MB by not using the posix
directory, but some applications or
test suites might produce some failures.
-
zic -L
leapseconds ...
-
This creates right time zones, including leap seconds. On
an embedded system, where space is tight and you do not
intend to ever update the time zones, or care about the
correct time, you could save 1.9MB by omitting the
right
directory.
-
zic ... -p
...
-
This creates the posixrules
file. We use New York because POSIX requires the daylight
saving time rules to be in accordance with US rules.
One way to determine the local time zone is to run the following
script:
tzselect
After answering a few questions about the location, the script
will output the name of the time zone (e.g., America/Edmonton). There are also some
other possible time zones listed in /usr/share/zoneinfo
such as Canada/Eastern or EST5EDT that are not identified by the
script but can be used.
Then create the /etc/localtime
file
by running:
ln -sfv /usr/share/zoneinfo/<xxx>
/etc/localtime
Replace <xxx>
with the name of the time zone selected (e.g., Canada/Eastern).
8.5.2.3. Configuring the
Dynamic Loader
By default, the dynamic loader (/lib/ld-linux.so.2
) searches through
/usr/lib
for dynamic libraries that
are needed by programs as they are run. However, if there are
libraries in directories other than /usr/lib
, these need to be added to the
/etc/ld.so.conf
file in order for
the dynamic loader to find them. Two directories that are
commonly known to contain additional libraries are /usr/local/lib
and /opt/lib
, so add those directories to the
dynamic loader's search path.
Create a new file /etc/ld.so.conf
by running the following:
cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
EOF
If desired, the dynamic loader can also search a directory and
include the contents of files found there. Generally the files in
this include directory are one line specifying the desired
library path. To add this capability run the following commands:
cat >> /etc/ld.so.conf << "EOF"
# Add an include directory
include /etc/ld.so.conf.d/*.conf
EOF
mkdir -pv /etc/ld.so.conf.d
8.5.3. Building Glibc - 32bit
Now recompile for m32. The extracted source can be reused but needs
to be cleaned before installing the m32 version of Glibc.
Clear the build directory and remove artefacts from previous build:
rm -rf ./*
find .. -name "*.a" -delete
Configure Glibc for m32 with the following commands:
CC="gcc -m32" CXX="g++ -m32" \
../configure \
--prefix=/usr \
--host=i686-pc-linux-gnu \
--build=$(../scripts/config.guess) \
--enable-kernel=4.19 \
--disable-nscd \
--libdir=/usr/lib32 \
--libexecdir=/usr/lib32 \
libc_cv_slibdir=/usr/lib32
Compile the package:
make
Install the package:
make DESTDIR=$PWD/DESTDIR install
cp -a DESTDIR/usr/lib32/* /usr/lib32/
install -vm644 DESTDIR/usr/include/gnu/{lib-names,stubs}-32.h \
/usr/include/gnu/
Add the library name to the dynamic loader config:
echo "/usr/lib32" >> /etc/ld.so.conf
Caution
At this point, it is imperative to stop and ensure that the basic
functions (compiling and linking) of the new toolchain are
working as expected. To perform a sanity check, run the following
commands:
echo 'int main(){}' > dummy.c
gcc -m32 dummy.c
readelf -l a.out | grep '/ld-linux'
If everything is working correctly, there should be no errors,
and the output of the last command will be of the form:
[Requesting program interpreter: /lib/ld-linux.so.2]
If the output is not shown as above or there was no output at
all, then something is wrong. Investigate and retrace the steps
to find out where the problem is and correct it. This issue must
be resolved before continuing on.
Once all is well, clean up the test files:
rm -v dummy.c a.out
8.5.4. Building Glibc - x32bit
Now recompile for mx32. The extracted source can be reused but
needs to be cleaned before installing the mx32 version of Glibc.
Clear the build directory and remove artefacts from previous build:
rm -rf ./*
find .. -name "*.a" -delete
Configure Glibc for mx32 with the following commands:
CC="gcc -mx32" CXX="g++ -mx32" \
../configure \
--prefix=/usr \
--host=x86_64-pc-linux-gnux32 \
--build=$(../scripts/config.guess) \
--enable-kernel=4.19 \
--disable-nscd \
--libdir=/usr/libx32 \
--libexecdir=/usr/libx32 \
libc_cv_slibdir=/usr/libx32
Compile the package:
make
Install the package:
make DESTDIR=$PWD/DESTDIR install
cp -a DESTDIR/usr/libx32/* /usr/libx32/
install -vm644 DESTDIR/usr/include/gnu/{lib-names,stubs}-x32.h \
/usr/include/gnu/
Add the library name to the dynamic loader config:
echo "/usr/libx32" >> /etc/ld.so.conf
Caution
At this point, it is imperative to stop and ensure that the basic
functions (compiling and linking) of the new toolchain are
working as expected. To perform a sanity check, run the following
commands:
echo 'int main(){}' > dummy.c
gcc -mx32 dummy.c
readelf -l a.out | grep '/ld-linux-x32'
If everything is working correctly, there should be no errors,
and the output of the last command will be of the form:
[Requesting program interpreter: /libx32/ld-linux-x32.so.2]
If the output is not shown as above or there was no output at
all, then something is wrong. Investigate and retrace the steps
to find out where the problem is and correct it. This issue must
be resolved before continuing on.
Once all is well, clean up the test files:
rm -v dummy.c a.out