Part of the Fathom-OS Project Log.
This is Part 4 of Chapter 8, the core system build. Part 3 finished the system libraries and the final permanent GCC. This part builds the run of terminal and text tooling that the rest of the userland depends on, Ncurses for terminal handling, then Sed, Psmisc, Gettext, Bison, and Grep, closing with the final permanent Bash. Seven packages, ending on the shell itself.
References:
Resuming the Build
Every Chapter 8 session starts the same way, since the snapshot is taken outside the chroot with the virtual filesystems unmounted. Become root on the host, confirm $LFS, check the mount state, remount, and re-enter the chroot. This session it all went clean, no stacked mounts and no surprises, so it is just the standard sequence.
sudo -i
echo $LFS
findmnt | grep /lfs
$LFS came back /lfs and findmnt showed only the /lfs root partition, clean. The remount block and chroot entry then ran first try:
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
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
The reminder from earlier parts still stands: use sudo -i, not su -, since the Ubuntu host keeps the root account locked.
8.31 Ncurses
Terminal-independent handling of character screens, the library that draws menus and text interfaces. This build is different from most in one important way: the test suite cannot run during the build, it only runs after install and is optional, so there is no test summary to capture here. What matters instead is the install method.
The configure builds wide-character shared libraries and the pkg-config files:
./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
The install is the careful part. Overwriting the live libncursesw.so.6.6 in place can crash the shell that is using it, so the book installs to a staging directory first, edits curses.h there to force the wide-character ABI, then copies into place with --remove-destination:
make DESTDIR=$PWD/dest install
sed -e 's/^#if.*XOPEN.*$/#if 1/' -i dest/usr/include/curses.h
cp --remove-destination -av dest/* /
Then a set of symlinks so applications expecting the non-wide-character libraries link against the wide-character ones instead, and one more so old applications looking for -lcurses still build:
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
The big Note block on the page about building version 5 non-wide libraries does not apply here. That is only for binary-only applications needing Ncurses 5 or LSB compliance, which a from-source system does not.
The Text Tools
A run of routine but essential text-processing tools, each built, tested, and installed.
8.32 Sed
The stream editor. Plain build with the HTML docs generated, then the test suite runs as the tester user.
./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
Result: TOTAL 192, PASS 171, SKIP 21, no failures. The skips are environment-dependent tests that do not apply in the chroot.
8.33 Psmisc
Tools for displaying information about running processes (fuser, killall, pstree, and others). A short package, plain configure, make, check, install.
./configure --prefix=/usr
make
make check
make install
The test suite passed clean across its three groups, killall 66, pslog 2, and fuser 9 expected passes. The “Couldn’t find tool init file” notices in the output are a harmless DejaGNU message, not failures.
8.34 Gettext
Internationalization and localization utilities. Note the version here is genuinely 1.0, not a typo, this release of the book uses Gettext 1.0. A larger build at 2.1 SBU. Plain configure, make, check, install, with a permission fix on the preloadable library at the end.
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-1.0
make
make check
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so
Result: TOTAL 479, PASS 436, SKIP 43, no failures. A large suite passing clean.
8.35 Bison
The parser generator. Plain build, then a long test suite of parser tests.
./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.8.2
make
make check
make install
Result: 712 tests successful, 64 skipped, no failures. Bison reports its results as a plain count rather than the PASS/SKIP/FAIL table the other packages use.
8.36 Grep
Searching through file contents. One sed first to silence an egrep/fgrep warning that otherwise makes some other packages’ tests fail later, then a plain build.
sed -i "s/echo/#echo/" src/egrep.sh
./configure --prefix=/usr
make
make check
make install
Result: TOTAL 315, PASS 280, SKIP 35, no failures. The “Included lib/regex.c not used” warning during configure is normal, it just means Grep is using the system regex from the libraries already built.
8.37 Bash
The Bourne-Again Shell, and the closing package for this part. Built against the readline already on the system rather than its bundled copy.
./configure --prefix=/usr \
--without-bash-malloc \
--with-installed-readline \
--docdir=/usr/share/doc/bash-5.3
make
The mktemp is dangerous linker warning during the build is a long-standing harmless Bash notice, not an error.
The Test Suite Runs in a Pseudo Terminal
Bash’s test suite is the most involved in this part. It has to run as a non-root user who owns the terminal connected to standard input, so the book hands the source tree to the tester user and spawns a pseudo terminal through Expect to run the tests inside it:
chown -R tester .
LC_ALL=C.UTF-8 su -s /usr/bin/expect tester << "EOF"
set timeout -1
spawn make tests
expect eof
lassign [wait] _ _ _ value
exit $value
EOF
Unlike the clean PASS/SKIP/FAIL tables from the text tools, Bash reports failures as diff output prefixed with < and >, and several are expected. The book names them up front: run-builtins fails on a diff at lines 479 and 480 (a ulimit core file size difference, which in the chroot shows as “cannot modify limit”), and tests needing the zh_TW.BIG5 and ja_JP.SJIS locales fail because those locales are not installed. The run also prints a stream of “do not consider this a test failure” warnings for signal numbering, error message text, and whitespace differences.
Every diff in this run mapped to either a book-named known failure or a warning the book told you in advance to disregard. No unexpected failures.
Install, then replace the running shell with the newly built Bash:
make install
exec /usr/bin/bash --login
That last command is the package replacing the very shell you are working in. The prompt comes back looking identical, but you are now running the Bash you just built.
Snapshot
With Bash done, the terminal libraries and the shell are all in place. This is the checkpoint before the next run of packages. Exit the chroot, unmount the virtual filesystems one at a time with children before parents, verify clean with findmnt (only the /lfs root partition should remain), then snapshot.
exit
umount $LFS/dev/shm
umount $LFS/dev/pts
umount $LFS/{sys,proc,run,dev}
findmnt | grep /lfs
Only the /lfs root partition remained, clean. Snapshot taken.
What Is Next
Part 5 continues the run of system tooling. Libtool comes next, then GDBM, Gperf, Expat, Inetutils, Less, Perl, and onward through the rest of the chapter’s utilities. That run is large, so it will span more than one post as the earlier parts did.
More updates to follow as each build phase completes.
Previous: Chapter 8 Part 3: System Libraries and the Final GCC | Next: Chapter 8 Part 5: Build Tools and Perl
All session notes and build logs are committed to the private repository at github.com/QuietWireDev/fathom-os.




