8.6. Glibc-2.41

The Glibc package contains the main C library. This library provides the basic routines for allocating memory, searching directories, opening and closing files, reading and writing files, string handling, pattern matching, arithmetic, and so on.

Approximate build time: 12 SBU
Required disk space: 3.2 GB

8.6.1. Installation of Glibc

Unlike in LFS, we will need to be able to generate locales on install or upgrade for the target system. To do so, we've borrowed a script from Arch Linux. Create the locale-gen script with the following command:

mkdir /sources/glibc
cd /sources/glibc
cat > locale-gen << "REALEOF"
#!/usr/bin/sh

set -e

LOCALEGEN=/etc/locale.gen
LOCALES=/usr/share/i18n/locales
if [ -n "$POSIXLY_CORRECT" ]; then
  unset POSIXLY_CORRECT
fi


[ -f $LOCALEGEN -a -s $LOCALEGEN ] || exit 0;

# Remove all old locale dir and locale-archive before generating new
# locale data.
rm -rf /usr/lib/locale/* || true

umask 022

is_entry_ok() {
  if [ -n "$locale" -a -n "$charset" ] ; then
    true
  else
    echo "error: Bad entry '$locale $charset'"
    false
  fi
}

echo "Generating locales..."
while read locale charset; do \
        case $locale in \#*) continue;; "") continue;; esac; \
        is_entry_ok || continue
        echo -n "  `echo $locale | sed 's/\([^.\@]*\).*/\1/'`"; \
        echo -n ".$charset"; \
        echo -n `echo $locale | sed 's/\([^\@]*\)\(\@.*\)*/\2/'`; \
        echo -n '...'; \
        if [ -f $LOCALES/$locale ]; then input=$locale; else \
        input=`echo $locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; fi; \
        localedef -i $input -c -f $charset -A /usr/share/locale/locale.alias $locale; \
        echo ' done'; \
done < $LOCALEGEN
echo "Generation complete."
REALEOF

Additionally, create the template file for locale-gen configuration file:

cat > locale.gen.txt << "REALEOF"
# Configuration file for locale-gen
#
# lists of locales that are to be generated by the locale-gen command.
#
# Each line is of the form:
#
#     <locale> <charset>
#
#  where <locale> is one of the locales given in /usr/share/i18n/locales
#  and <charset> is one of the character sets listed in /usr/share/i18n/charmaps
#
#  Examples:
#  en_US ISO-8859-1
#  en_US.UTF-8 UTF-8
#  de_DE ISO-8859-1
#  de_DE@euro ISO-8859-15
#
#  The locale-gen command will generate all the locales,
#  placing them in /usr/lib/locale.
#
#  A list of supported locales is included in this file.
#  Uncomment the ones you need.
REALEOF

You need to regenrate the installed locales on isntallation of a new version of GLibC. Create an install file which runs locale-gen on both first installation and on upgrades:

cat > glibc.install << "REALEOF"
# glibc.install

post_install(){
  /usr/bin/locale-gen
}

post_upgrade(){
  /usr/bin/locale-gen
}
REALEOF

Finally, create the PKGBUILD file for GlibC:

cat > PKGBUILD << "REALEOF"
# Maintainer: Linux From Scratch <lfs-dev@lists.linuxfromscratch.org>

pkgname="glibc"
pkgver="2.41"
pkgrel="1"
pkgdesc="The Glibc package contains the main C library. This library provides the basic routines for allocating memory, searching directories, opening and closing files, reading and writing files, string handling, pattern matching, arithmetic, and so on."
arch=('x86'
      'x86_64')
url="https://www.gnu.org/software/libc/"
groups=('core')
options=('!emptydirs'
         'staticlibs'
         '!strip') 
license=('GPLv2'
         'LGPLv2.1'
         'PD')
install='glibc.install'
depends=('rootfs')
makedepends=('bash'
             'binutils'
             'bison'
             'coreutils'
             'diffutils'
             'gawk'
             'gcc'
             'gettext'
             'grep'
             'gzip'
             'linux-api-headers'
             'make'
             'perl'
             'python'
             'sed'
             'texinfo')
checkdepends=('file')
backup=('etc/nsswitch.conf'
        'etc/locale.gen')
source=("https://ftp.gnu.org/gnu/glibc/glibc-2.41.tar.xz"
        "https://www.linuxfromscratch.org/patches/lfs/development/glibc-2.41-fhs-1.patch"
        'locale.gen.txt'
        'locale-gen')
md5sums=('19862601af60f73ac69e067d3e9267d4'
         '9a5997c3452909b1769918c759eff8a2'
         ''
         '')

prepare(){
  cd "${srcdir}/${pkgname}-${pkgver}"
  patch -Np1 -i "${srcdir}/${pkgname}-${pkgver}-fhs-1.patch"
  mkdir build
}

build(){

  # D_FORTIFY_SOURCE=2 causes testsuite build failure and is unnecessary during
  # actual builds (support is built-in via --enable-fortify-source).
  CFLAGS=${CFLAGS/-Wp,-D_FORTIFY_SOURCE=3/}

  cd "${srcdir}/${pkgname}-${pkgver}/build"

  # Make sure everything is correclty installed in the /usr prefix
  echo "slibdir=/usr/lib"      >> configparms
  echo "rtlddir=/usr/lib"      >> configparms
  echo "sbindir=/usr/sbin"     >> configparms
  echo "rootsbindir=/usr/sbin" >> configparms

  ../configure                                        \
      --prefix=/usr                                   \
      --libdir=/usr/lib                               \
      --disable-werror                                \
      --enable-kernel=5.4                             \
      --enable-stack-protector=strong                 \
      --enable-fortify-source                         \
      --disable-nscd                                  \
      --enable-cet                                    \
      libc_cv_slibdir=/usr/lib
  make
}

check(){
  cd "${srcdir}/${pkgname}-${pkgver}/build"

  # adjust/remove buildflags that cause false-positive testsuite failures
  # failure to build testsuite:
  sed -i 's/-Werror=format-security/-Wformat-security/' config.make
  # 27 test failures:
  sed -i '/CFLAGS/s/-fno-plt//' config.make
  # 1 test failure
  sed -i '/CFLAGS/s/-fexceptions//' config.make

  make -k check || true

  # Get test rusults together into one file
  for file in `find . -name "*.sum"`
  do
    cat $file >> tests-summary
  done
  _FAILCOUNT=`grep -c "^FAIL" tests-summary`

  # Known test failures:
  # io/tst-lchmod
  # misc/tst-sched-affinity-inheritance
  # nptl/tst-default-attr
  # nptl/tst-pthread-affinity-inheritance
  # posix/tst-sysconf-empty-chroot

  # Possible arch specific failures:
  # nss/tst-nss-files-hosts-multi
  # nptl/tst-thread-affinity-pthread
  # nptl/tst-thread-affinity-pthread2
  # nptl/tst-thread-affinity-sched
  # elf/tst-cpu-features-cpuinfo
  # stdlib/tst-arc4random-thread

  # Just make sure number of failures is no more than the known 5
  # and 7 possible arch specific failures
  test x"${_FAILCOUNT}" != "x" || _FAILCOUNT="0"
  test "${_FAILCOUNT}" -lt "13" || exit 1
}

package(){

  # locale-gen taken from Arch Linux
  install -vdm755 "${pkgdir}/usr/bin"
  install -vm755 "${srcdir}/locale-gen" "${pkgdir}/usr/bin"
  install -vdm755 "${pkgdir}/etc"
  install -vm644 "${srcdir}/locale.gen.txt" "${pkgdir}/etc/locale.gen"

  # uncommet locales by default required for LFS testsuites
  echo "# These locales are requried for LFS testsuites, do not comment out" \
       >> "${pkgdir}/etc/locale.gen"
  echo "C.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "cs_CZ.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "de_DE ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "de_DE@euro ISO-8859-15" >> "${pkgdir}/etc/locale.gen"
  echo "de_DE.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "el_GR ISO-8859-7" >> "${pkgdir}/etc/locale.gen"
  echo "en_GB ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "en_GB.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "en_HK ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "en_PH ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "en_US ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "en_US.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "es_ES@euro ISO-8859-15" >> "${pkgdir}/etc/locale.gen"
  echo "es_MX ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "fa_IR UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "fr_FR ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "fr_FR@euro ISO-8859-15" >> "${pkgdir}/etc/locale.gen"
  echo "fr_FR.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "is_IS ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "is_IS.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "it_IT ISO-8859-1" >> "${pkgdir}/etc/locale.gen"
  echo "it_IT@euro ISO-8859-15" >> "${pkgdir}/etc/locale.gen"
  echo "it_IT.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "ja_JP EUC-JP" >> "${pkgdir}/etc/locale.gen"
  echo "ja_JP.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "nl_NL@euro ISO-8859-15" >> "${pkgdir}/etc/locale.gen"
  echo "ru_RU.KOI8-R KOI8-R" >> "${pkgdir}/etc/locale.gen"
  echo "ru_RU.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "se_NO.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "ta_IN.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "tr_TR.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "zh_CN.GB18030 GB18030" >> "${pkgdir}/etc/locale.gen"
  echo "zh_HK.BIG5-HKSCS BIG5-HKSCS"
  echo "zh_TW.UTF-8 UTF-8" >> "${pkgdir}/etc/locale.gen"
  echo "" >> "${pkgdir}/etc/locale.gen"

  # Supply a list of all available locales
  sed -e '1,3d' -e 's|/| |g' -e 's|\\| |g' -e 's|^|#|g' \
    ${srcdir}/${pkgname}-${pkgver}/localedata/SUPPORTED \
    >> "${pkgdir}/etc/locale.gen"

  # Create the locale directory
  install -vdm755 ${pkgdir}/usr/lib/locale

  # Finally do the installation
  cd "${srcdir}/${pkgname}-${pkgver}/build"
  make DESTDIR="${pkgdir}" install

  # Remove these as they are part of the tzdata package
  rm -f "${pkgdir}"/usr/bin/{tzselect,zdump,zic}

  # Don't install ld.so.c{onf,ache} files - included in rootfs package
  rm -f ${pkgdir}/etc/ld.so.c{onf,ache}

  # If not a debug build, then we need to specify !strip and do it manually
  if check_option 'debug' n; then
    options+=('!strip')

    # Executables
    find "${pkgdir}"/usr/bin -type f -executable -exec strip $STRIP_BINARIES {} + 2> /dev/null || true
    find "${pkgdir}"/usr/sbin -type f -executable -exec strip $STRIP_BINARIES {} + 2> /dev/null || true
    find "${pkgdir}"/bin -type f -executable -exec strip $STRIP_BINARIES {} + 2> /dev/null || true
    find "${pkgdir}"/sbin -type f -executable -exec strip $STRIP_BINARIES {} + 2> /dev/null || true

    # Libraries
    find "${pkgdir}"/usr/lib -name '*.a' -type f -exec strip $STRIP_STATIC {} + 2> /dev/null || true
    find "{$pkgdir}"/lib -name '*.a' -type f -exec strip $STRIP_STATIC {} + 2> /dev/null || true
    find "{$pkgdir}"/usr/lib \
      -name '*.so' -type f -exec strip $STRIP_SHARED {} + 2> /dev/null || true

    # Do not strip these four for gdb and valgrind useability, strip the rest
    find "${pkgdir}"/lib \
      -not -name 'ld-*.so' \
      -not -name 'libc-*.so' \
      -not -name 'libpthread-*.so' \
      -not -name 'libthread_db-*.so' \
      -name '*.so' -type f -exec strip $STRIP_SHARED {} + 2> /dev/null || true
  fi

  # Create /etc/nsswitch.conf
  cat > ${pkgdir}/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

  # Install compatibility and lsb symlinks for x86_64
  install -vdm755 "${pkgdir}/lib64"
  ln -s ../lib/ld-linux-x86-64.so.2 "${pkgdir}/lib64"
  ln -s ../lib/ld-linux-x86-64.so.2 "${pkgdir}/lib64/ld-lsb-x86-64.so.3"

}
REALEOF

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=5.4

This option tells the build system that this Glibc may be used with kernels as old as 5.4 . 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.

Prepare the build directory for the pacman user and build the package (unlike previous packages, note the use of the 'updpkgsums' command to populate the checksums for the newly created files):

chown -R root:pacman .
chmod 2775 .
chmod 664 PKGBUILD
su pacman -c 'updpkgsums'
su pacman -c 'makepkg -L --nodeps'

Add the package to the central repository:

cp glibc-2.41-1-$(uname -m).pkg.tar.xz \
   /srv/pacman/repos/LFS/
repo-add /srv/pacman/repos/LFS/LFS.db.tar.xz \
         /srv/pacman/repos/LFS/glibc-2.41-1-$(uname -m).pkg.tar.xz

Update the local cache and install the glibc package:

pacman -Syu
pacman -S glibc --overwrite \* -dd --noconfirm

Finally, copy the source files into the source repository and clean up the build directory:

mkdir /srv/pacman/source/LFS/glibc
cp locale-gen locale.gen.txt glibc.install PKGBUILD \
   /srv/pacman/source/LFS/glibc
cd /sources
rm -rf glibc

8.6.2. Contents of Glibc

Installed programs: gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, ld.so (symlink to ld-linux-x86-64.so.2 or ld-linux.so.2), locale, localedef, makedb, mtrace, pcprofiledump, pldd, sln, sotruss, sprof, and xtrace
Installed libraries: ld-linux-x86-64.so.2, ld-linux.so.2, libBrokenLocale.{a,so}, libanl.{a,so}, libc.{a,so}, libc_nonshared.a, libc_malloc_debug.so, libdl.{a,so.2}, libg.a, libm.{a,so}, libmcheck.a, libmemusage.so, libmvec.{a,so}, libnsl.so.1, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libpcprofile.so, libpthread.{a,so.0}, libresolv.{a,so}, librt.{a,so.1}, libthread_db.so, and libutil.{a,so.1}
Installed directories: /usr/include/arpa, /usr/include/bits, /usr/include/gnu, /usr/include/net, /usr/include/netash, /usr/include/netatalk, /usr/include/netax25, /usr/include/neteconet, /usr/include/netinet, /usr/include/netipx, /usr/include/netiucv, /usr/include/netpacket, /usr/include/netrom, /usr/include/netrose, /usr/include/nfs, /usr/include/protocols, /usr/include/rpc, /usr/include/sys, /usr/lib/audit, /usr/lib/gconv, /usr/lib/locale, /usr/libexec/getconf, /usr/share/i18n, and /var/lib/nss_db

Short Descriptions

gencat

Generates message catalogues

getconf

Displays the system configuration values for file system specific variables

getent

Gets entries from an administrative database

iconv

Performs character set conversion

iconvconfig

Creates fastloading iconv module configuration files

ldconfig

Configures the dynamic linker runtime bindings

ldd

Reports which shared libraries are required by each given program or shared library

lddlibc4

Assists ldd with object files. It does not exist on newer architectures like x86_64

locale

Prints various information about the current locale

localedef

Compiles locale specifications

makedb

Creates a simple database from textual input

mtrace

Reads and interprets a memory trace file and displays a summary in human-readable format

pcprofiledump

Dump information generated by PC profiling

pldd

Lists dynamic shared objects used by running processes

sln

A statically linked ln program

sotruss

Traces shared library procedure calls of a specified command

sprof

Reads and displays shared object profiling data

xtrace

Traces the execution of a program by printing the currently executed function

ld-*.so

The helper program for shared library executables

libBrokenLocale

Used internally by Glibc as a gross hack to get broken programs (e.g., some Motif applications) running. See comments in glibc-2.41/locale/broken_cur_max.c for more information

libanl

Dummy library containing no functions. Previously was the asynchronous name lookup library, whose functions are now in libc

libc

The main C library

libc_malloc_debug

Turns on memory allocation checking when preloaded

libdl

Dummy library containing no functions. Previously was the dynamic linking interface library, whose functions are now in libc

libg

Dummy library containing no functions. Previously was a runtime library for g++

libm

The mathematical library

libmvec

The vector math library, linked in as needed when libm is used

libmcheck

Turns on memory allocation checking when linked to

libmemusage

Used by memusage to help collect information about the memory usage of a program

libnsl

The network services library, now deprecated

libnss_*

The Name Service Switch modules, containing functions for resolving host names, user names, group names, aliases, services, protocols, etc. Loaded by libc according to the configuration in /etc/nsswitch.conf

libpcprofile

Can be preloaded to PC profile an executable

libpthread

Dummy library containing no functions. Previously contained functions providing most of the interfaces specified by the POSIX.1c Threads Extensions and the semaphore interfaces specified by the POSIX.1b Real-time Extensions, now the functions are in libc

libresolv

Contains functions for creating, sending, and interpreting packets to the Internet domain name servers

librt

Contains functions providing most of the interfaces specified by the POSIX.1b Real-time Extensions

libthread_db

Contains functions useful for building debuggers for multi-threaded programs

libutil

Dummy library containing no functions. Previously contained code for standard functions used in many different Unix utilities. These functions are now in libc