My LFS journey
Daily Driving Linux From Scratch
For about a month now, I’ve been using a fully custom version of Linux that I built using the instructions from LFS. I don’t feel it’s right to call it LFS, since it deviates quite heavily from the instructions provided by the LFS authors. However, the guidance of their writings is immensely valuable.
Motivation
My reason for setting out to create this system was born from the fact that the system I was looking for did not exist. This is surprising given the comically high number of different Linux distributions there are to choose from. For one reason or another, nothing seemed to fit the description of what I wanted.
The system I wanted could be described as a very minimal base for a GNU-oriented system that I could build on top of. Many very minimal Linux distributions deviate from this. They might use Musl as the systems’ C library, a BSD set of shell utilities or the LLVM toolchain. In many ways these systems can be very competent, but as a GNU enthusiast and libre software advocate, these systems deviate in exactly the kind of ways that I morally cannot get behind.
Building Blocks
The pillars of my system are:
The GNU C library (GLIBC)
The library, the myth, the legend: GLIBC is the undisputed king of Unix(-like) system C libraries. It’s incredibly mature, stable and like many GNU projects, has excellent internationalization support.
GNU Compiler Collection (GCC)
The main system C/C++ compiler, which also provides frontends to compile
Fortran, Ada, Go, Modula-2, Objective-C/C++, D, Rust and Cobol. Additionally,
it contains the GNU C++ library, libstdc++.
GNU Binutils
The complement to GCC, a package of binary tools such as the system linker, assembler and archiver among others.
GNU Shepherd
The service manager and init system of GNU Guix, which I am quite proud to have managed to set up on my system, as Guix is the only distribution that officially supports it. It is configured using Guile Scheme.
The GNU Coreutils
The classic, well-known command-line utilities we all know and love.
Bash
The main system shell; used extensively across many distributions of GNU/Linux as the default user shell. Tried and true.
Package Management
One of the things that systems like LFS do not provide is a package manager. However, I figured that if I want to use this system for any significant amount of time, I need something.
So I got to work on a set of shell scripts. The main process is:
- Build a package
- Use things like
DESTDIR=to do a fake staged install of the package - Use my shell scripts to generate a manifest of the contents of the package
into a file name
.manifest - Write the name of the package and its version to a file named
.data - If I know there are things I’d want to run upon install/uninstall,
write the commands to either
.post-inor.post-rm. - If the package contains directories that I know can be safely removed when I
uninstall it, add the paths of each directory to
.dirs - Invoke the
archivefunction of my shell scripts to create a.tar.gzof the package - Invoke the
installfunction to:
- Unpack the archive against my root directory
- Execute commands from
.post-inif present - Run a few “hooks”, such as updating the linker cache with
ldconfig - Write the contents of
.datato myworldfile
- If there is a problem, I run the
removefunction to:
- Remove all of the files from the manifest
- Remove the directories from
.dirs(only if they are empty) - Execute commands from
.post-rmif present
Despite being roughly 100 total lines of shell code, it’s surprising competent for managing software, and has saved me from at least two problematic package installations.
Is it usable?
Yes, very much so. With the methods of managing my system that I’ve described. I have been able to cleanly upgrade packages without worries, and things have just been very stable. I’ve gone through 3 Linux kernel and 1 GLIBC upgrades without destroying my system, as well as a full downgrade from LLVM 21.1.0 to 19.1.7, which would’ve been genuinely impossible without my package management scripts.
What is it running?
It’s currently running the Niri Wayland compositor, Kitty terminal, Mozilla Firefox, and the AppArmor Linux security module. All things considered I’d say it is a fully featured setup, especially given the fact that it was built entirely by myself.
Sometimes, you have to make your own path
I was frustrated; I tried many different Linux distributions in pursuit of one that fulfilled what this system does, but in the end it’s clear that making it myself was not only the only option, but a very rewarding one too.