LFS - Linux From Scratch
Linux selber bauen - Schritt für Schritt.
Einführung
Nicht zuletzt aufgrund des Rummels um die Abkündigung von Urgesteinen wie CentOS 8 auf Ende 2021 und daraus entstehenden Diskussionen um Alternativen wie Rocky Linux mag sich so mancher überlegt haben, ein eigenes Linux zu bauen. Dieser Artikel erklärt auf Basis von Linux from Scratch (LFS), wie das funktioniert.
Linux from Scratch (LFS) und Beyond Linux From Scratch (BLFS) sind online verfügbare Anleitungen bzw. Bücher, die das Compilieren und Zusammenstellen eines eigenen Linux-Systems direkt aus frei verfügbaren Quellen Schritt für Schritt beschreiben. Hier wird die Abkürzung LFS sowohl für die Dokumentation als auch für das daraus entstehende Linux-System verwendet. LFS und BLFS werden meist zweimal im Jahr im März und im September aktualisiert.
1998 begann Gerard Beekmans, der Autor von LFS, sich mit Linux zu beschäftigen. Nach Einsatz diverser Distributionen reifte die Erkenntnis, dass es für ihn kein „one size fits all“ gibt, und es vielleicht ein eigenes System sein sollte - Open Source bot ihm per Definition die Möglichkeit dazu. Er begann zu compilieren und sich mit Compile-Time-Errors sowie zirkulären Abhängigkeiten auseinanderzusetzen. Die gesammelten Erfahrungen, die er mit der Linux-Community teilte, stiessen auf so breites Interesse, dass daraus das Projekt „LFS“ entstand.
LFS versucht soweit wie möglich, dem POSIX.1-2008-Standard, der ein Betriebssystem-Interface mit Environment zu Portabilitätszwecken definiert, dem Filesystem Hierarchy Standard (FHS) Version 3.0 sowie der Linux Standard Base (LSB) Version 5.0 (2015) zu folgen. Die Linux Standard Base definiert vier - teils kontrovers diskutierte - Standards für Core, Desktop, Runtime Languages und Imaging, die LFS schon aufgrund seiner minimalen Software-Ausstattung nur in Teilen umsetzen kann. Aber man hat die Trümpfe ja in der Hand, dies zu ändern…
Wer der Anleitung folgt, erhält Stand LFS v10.1 von März 2021 ein minimales Linux-System mit
Ext4-Dateisystem
GRUB 2.04
Kernel 5.10.17
Bash 5.1
GCC 10.2
Perl 5.32.1
Python 3.9.2
Vim 8.2
Man hat die Wahl zwischen LFS mit SysVinit-basiertem Bootsystem und LFS mit Systemd und D-Bus . Dieser Artikel behandelt die letztere Variante. Die Vorteile: Mit Systemd erhält LFS nicht nur das modernere Boot-System, sondern auch einen DHCP- und NTP-Client sowie andere Kleinigkeiten, die in der SysVinit-Variante erst im BLFS behandelt werden.
Mit dem Herunterladen der Kernel-Quellen und dem Anwerfen des C-Compilers ist es nicht getan. LFS unterteilt das Erstellen eines Linux-Systems in drei relevante Teile: die Konfiguration eines Build-Hosts (Part II, Abschnitt 2 bis 4), das Bauen einer Cross-Toolchain und nur temporär benötigter Tools (Part III, Abschnitt 5 bis 7) und erst daran anschliessend die Erstellung des eigentlichen LFS-Systems (Part IV, Abschnitt 8 bis 11). Die Abschnitte 2 bis 11 werden hier zusammengefasst beschrieben und so auch in den Shell-Kommentaren am Ende des Artikels referenziert.
Im Gegensatz zum LFS-Buch folgt man der BLFS-Anleitung übrigens nicht linear, sondern sucht sich aus über 50 Abschnitten diejenigen aus, welche das eigene Linux in die gewünschte Richtung bringen. Da von Security über Virtualisierung bis hin zu Desktop-Umgebungen so ziemlich alle Bereiche und die gängigsten Software-Pakete abgehandelt werden, verwundert es nicht, dass BLFS ungefähr dreimal so umfangreich wie LFS ist.
Dieser Artikel fasst die LFS-Anleitung zusammen und erklärt zunächst die Prinzipien und die Vorgehensweise. Am Ende des Artikels finden sich die Kommandos, die - soweit wie möglich - per Copy & Paste auf einem CentOS 8 Build-Host auszuführen sind, um in einem Rutsch zum ersten, selbst gebauten Linux zu kommen. Die Anleitung hier verfrachtet /home
darüber hinaus auf eine eigene Partition und bereitet die LFS-Disk auf einen autarken Boot vor.
Das Bauen nimmt Zeit in Anspruch. Zur Orientierung: Mit der hier beschriebenen Test-VM unter KVM auf Basis eines Core i7 10th Gen mit NVMe dauert der Build auch mit abgeschalteten Tests mehrere Stunden.
Wer nach dem Build, dem Boot in LFS und den ersten Tests tiefer in die Materie eintauchen möchte, sei auf die vorbildliche Original-Dokumentation verwiesen.
- Links
Da linuxfromscratch.org so seine Mühen mit Geschwindigkeit und Erreichbarkeit hat, empfiehlt sich die Nutzung einer der Mirror-Server.
Selber bauen oder nicht?
Man kann sich natürlich fragen, ob der Bau eines eigenen Linux-Systems lohnt, wo man doch aus einer breiten Masse an Distributionen auswählen kann. Das Team um den LFS-Projektleiter Gerard Beekmans hat darauf mehrere Antworten:
Das Projekt möchte zeigen, wie Linux gebaut wird, aus welchen Komponenten Linux besteht, wie diese zusammenarbeiten und voneinander abhängen. Wer will kann LFS jedoch als Ausgangspunkt für eigene Weiterentwicklungen nutzen.
Mit LFS erhält man ein aktuelles, funktionierendes und sehr kompaktes Linux-System, was aus nicht viel mehr als dem Kernel und ein paar Tools besteht. Die Doku berichtet von einem auf LFS laufenden Apache mit einer Gesamtgrösse von 8 MB und weniger, was besonders für Embedded Systeme von Interesse sein kann.
Wer selber baut, ist extrem flexibel. Mit LFS erhält man den Rohbau eines Hauses, aus dem sich ganz nach Geschmack ein individuelles Zuhause vom 1-Zimmer-Apartment bis zum Luxus-Resort gestalten lässt.
Security: LFS lässt sich bei Bedarf komplett auditieren, und - vielleicht noch wichtiger - man hat das Management aller Sicherheitspatches selbst in der Hand. Mehr Kontrolle als bei LFS über das, was auf dem System läuft, kann man nicht haben.
Und zugegeben, es ist einfach cool. Man stelle sich die Situation vor:
Guy: BTW I use Arch.You: :-)
Um die Erwartungen etwas zu dämpfen: Im produktiven Betrieb lässt sich mit LFS nicht komfortabel arbeiten. Ein SSH-Daemon fehlt, Werkzeuge wie sudo
, wget
oder parted
sind nicht mit an Bord. Das Dateisystem wird beispielsweise nicht durch LVM verwaltet, und der Netzwerk-Stack ist alles andere als komplett. Das wird zwar im Rahmen von BLFS als Advanced Topic nachgeliefert, ein Paket-Manager kommt aber im ganzen Projekt nicht zum Einsatz. Man muss seine eigene Distribution daher per Download und Compile selbst aktuell halten und regelmässig mit Updates und Sicherheitspatches versorgen. Wer auf Slackware & Co. zu Hause ist, wird sich LFS jedoch auch in dieser Hinsicht erweitern können, indem ein Manager wie Pacman oder GNU Stow hinzugefügt oder eine Strategie wie der Package User-Ansatz verfolgt wird. Überhaupt gilt im Projekt: Linux-Kenntnisse werden nicht vermittelt, sie werden vorausgesetzt.
Bis zur echten Linux-Distribution ist es ohnehin noch ein weiter Weg, zeichnen sich diese doch durch Merkmale aus wie:
eine aktive User Community
QA-geprüfte Pakete inkl. Errata und Patch-Management
ein umfangreiches Mirror-Netzwerk
zuständige und kontaktierbare Entwickler
Umsysteme wie Wiki, IRC-Chat, Mailinglisten, Foren, Bug Tracker, FAQ, …
Ob sich neben dem Lerneffekt auch ein praktischer Nutzen findet, hängt also wie immer von den eigenen Anforderungen ab. Mit LFS bekommt man jedenfalls ansatzweise ein Gefühl dafür, welcher Invest an Zeit und Know-How im Linux-Kernel, in Open Source Software und in allen Linux-Distributionen steckt.
Bemerkung
Neben LFS gibt es eine Reihe an Linux-Distributionsbaukästen, von denen die meisten auf den Embedded-Bereich spezialisiert sind und deren bekanntester Verteter BitBake aus dem Yocto-Projekt ist. Andere sind Linux Target Image Builder, OpenWrt oder Scratchbox.
Aufbau der LFS-Doku
Der Aufbau der Dokumentation entspricht geichzeitig dem Ablauf, um LFS zu bauen.
┌─────────────────────────────────────────────┐
│ Part II │
│ Der Build-Host │
└──┬─┬────────────────────────────────────────┤
│ ├────────────────────────────────────────┤
│ │ 02. Build-Host aufsetzen │
│ ├────────────────────────────────────────┤
│ │ 03. Pakete und Patches laden │
│ ├────────────────────────────────────────┤
│ │ 04. Abschlussarbeiten vornehmen │
│ └────────────────────────────────────────┘
│
┌──▼──────────────────────────────────────────┐
│ Part III │
│ LFS Cross-Toolchain und temporäre │
│ Tools bauen │
└──┬─┬────────────────────────────────────────┤
│ ├────────────────────────────────────────┤
│ │ 05. Cross-Toolchain compilieren │
│ ├────────────────────────────────────────┤
│ │ 06. Nur temporär benötigte Tools bauen │
│ ├────────────────────────────────────────┤
│ │ 07. Zusätzliche temporäre Tools bauen │
│ └────────────────────────────────────────┘
│
┌──▼──────────────────────────────────────────┐
│ Part IV │
│ LFS bauen │
└────┬────────────────────────────────────────┤
├────────────────────────────────────────┤
│ 08. Basis-Software installieren │
├────────────────────────────────────────┤
│ 09. System konfigurieren │
├────────────────────────────────────────┤
│ 10. System bootfähig machen │
├────────────────────────────────────────┤
│ 11. Abschluss und Reboot │
└────────────────────────────────────────┘
Der Build-Host
Build-Host aufsetzen
Ohne einen perfekt funktionierenden Build-Host geht es nicht. Diese Anleitung setzt daher eine unbenutzte, virtuelle Maschine auf Basis eines aktuellen CentOS 8.3 „Minimal Install“ mit BIOS-Boot voraus, fully patched. Der C-Compiler GCC profitiert von einem schnellen Core. Ein auf mehrere Cores verteilter, multi-threaded Build wird in der Dokumentation diskutiert, ist aber wegen immer mal wieder auftretender Race-Conditions nicht zu empfehlen.
Für den Build-Server genügen daher tatsächlich
2 Cores
2 GB RAM
SSD-basierter Hypervisor
Disks: 1x 10 GB (VirtIO,
/dev/vda
) für das System, 1x 20 GB (SATA oder SCSI,/dev/sda
) für LFSNetzwerkkarte: Intel e1000
Unbedingt darauf achten, VirtIO für die LFS-Disk und die Netzwerkkarte zu vermeiden, da die Anleitung keinen VirtIO-Support in den Kernel eincompiliert. LFS freut sich über eine virtuelle SATA- oder SCSI-Disk, die als /dev/sda
erkannt wird, sowie eine klassische Intel e1000-Netzwerkkarte mit 1 Gbps. Die Disk-Bezeichnung wird wichtig, wenn es darum geht, LFS bootfähig zu machen. Der Name der Netzwerkkarte (beispielsweise enp1s0
) spielt eine Rolle, falls Predictable Network Interface Names verwendet werden sollen.
Nach der CentOS-Installation müssen die für die ersten Build-Prozesse notwendigen Pakete installiert werden. Das benötigte makeinfo
aus dem texinfo
-Paket erhält man ab CentOS 8.3 aus dem „PowerTools“-Repo.
dnf -y install yum-utils
yum config-manager --set-enabled powertools
dnf -y install bison byacc bzip2 gcc-c++ patch perl python3 tar texinfo wget
Die von CentOS installierten Versionen sollten anschliessend mit Hilfe eines kleinen Skriptes geprüft werden: LFS v10.0 verlangt einen GCC ab Version 6.2 sowie GNU Make ab Version 4.0, die beispielsweise durch ein CentOS 7 nicht bereitgestellt werden.
Ist hier alles in Ordnung, wird die zweite Disk des Build-Hosts in die Partitionen /
, swap
und /home
aufgeteilt, das Dateisystem mit ext4
erstellt und die für alle nachfolgenden Shell-Aufrufe essentielle Umgebungsvariable $LFS
definiert, die den root-Mountpoint auflöst. Die Variable muss daher unter allen Umständen funktionieren. Das Setzen der Locale in CentOS 8 sollte noch erledigt und die zweite Disk gemountet werden.
/dev/sda
wird per BIOS/MBR bootfähig gemacht und mit diversen Partitionen ausgestattet. Um der GRUB-eigenen core.img
genügend Platz einzuräumen, startet die erste Partition für /
mit 10 GB Grösse erst ab 1 MiB. Danach wird /swap
mit 2 GB Grösse angelegt, der Rest der Disk ist für /home
reserviert.
/boot
benötigt in diesem Setup keine eigene Partition, sondern enthält als gewöhnliches Verzeichnis den Kernel sowie die Bootloader-Konfiguration. Eine eigene Partition wird erst dann nötig, falls ein Multiboot mit anderen Distributionen unterstützt werden soll, oder der Bootloader nicht mehr auf das root-Dateisystem zugreifen kann, was an fehlenden Treibern, an Disk-Encryption, an einem Software-RAID oder LVM liegen kann.
Hier geht’s zum CodeChapter02.
Pakete und Patches laden
Kapitel 3 der Dokumentation ist der Abschnitt, der LFS in seiner späteren Ausstattung definiert: neben den Build-Tools lädt man die gewünschten Quellen ausgewählter Software-Pakete herunter, die das System charakterisieren. Die Macher von LSF haben sich die Mühe gemacht, eine Vorauswahl zu treffen, deren Versionsabhängigkeiten aufzulösen und als Liste in einer Textdatei zusammenzufassen, die man herunterladen und ganz bequem wget
übergeben kann. Damit nicht genug: das LFS-Team liefert sogar eine Reihe an Patches, mit denen Fehler gefixt oder die Pakete in ihrer Ausprägung an das zukünftige Zielsystem angepasst werden. Darüber hinaus erklären sie alle Optionen der jeweiligen configure
-Aufrufe.
wget http://lfs.linux-sysadmin.com/lfs/downloads/stable-systemd/wget-list
wget --input-file=wget-list --continue --directory-prefix=$LFS/sources
Um die Checksummen der am Ende knapp 90 heruntergeladenen Pakete zu prüfen, hilft eine ebenfalls bereitgestellte md5sum-Checksummen-Liste.
Hier geht’s zum CodeChapter03.
Abschlussarbeiten vornehmen
In Kapitel 4 erstellt der Benutzer root die für den Build notwendigen Verzeichnisstrukturen $LFS/{bin,etc,lib,lib64,sbin,tools,usr,var}
sowie den Benutzer lfs. Dieser wird Eigentümer der Build-Verzeichnisse. Anschliessend wird in den Benutzer lfs gewechselt und dessen Shell-Environment geleert und optimiert. Da das neue Environment eine non-login-Shell ist, muss mit einer .bashrc
-Datei gearbeitet werden, um die Shell-Umgebung zu erweitern und anzupassen, zum Beispiel um Umgebungsvariablen wie $LFS
, LC_ALL
oder PATH
.
Das Verzeichnis $LFS/tools
wird den Cross-Compiler enthalten.
Ist hier alles getan, ist ein Neustart des Build-Hosts anzuraten, um sicherzugehen, dass der Build-Host ohne Altlasten daherkommt und funktioniert. Spätestens jetzt empfiehlt es sich, einen VM-Snapshot anzulegen.
Hier geht’s zum CodeChapter04.
LFS Cross-Toolchain und temporäre Tools bauen
Cross-Toolchain compilieren
In Kapitel 5 bleibt man mit dem Benutzer lfs angemeldet, für den die eigentliche Arbeit beginnt: das Bauen des Cross-Compilers und seiner Tools. Der Cross-Compiler und seine Tools landen temporär in $LFS/tools
, die Bibliotheken werden bereits in ihren zukünftigen Orten installiert.
Der Ablauf zum Bau der Software-Pakete ist dann bis zum Schluss fast immer gleich:
Wechsel ins
sources
-VerzeichnisAuspacken der Quell-Dateien mit Hilfe von
tar xf
Wechsel ins erstellte Verzeichnis
bei Bedarf
build
-Verzeichnis erstellenPaket compilieren
Paket installieren
das Source-Code-Verzeichnis löschen
Angewendet wird dies auf:
Linker und Assembler (erster Durchlauf)
Cross-Compiler (erster Durchlauf)
Linux API Headers
glibc
libstdc++
, erster Durchlauf
echo 'int main(){}' > dummy.c
$LFS_TGT-gcc dummy.c
# Displays the information contained in the file's segment headers, if it has any:
readelf -l a.out | grep '/ld-linux'
# should return something like
# [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Hier geht’s zum CodeChapter05.
Nur temporär benötigte Tools bauen
Immer noch unter dem Benutzer lfs: Mit der vorher erzeugten Cross-Toolchain wird in Kapitel 6 unter anderem Bash, grep
und der native LFS-GCC compiliert. Die Applikationen werden im bereits rudimentär erstellten LFS-Dateisystem installiert, sind aber noch nicht einsatzbereit, für bestimmte Aufgaben wird also immer noch das Host-System benötigt. Immerhin werden die in LFS installierten Bibliotheken bereits zum Linken verwendet. Wirklich genutzt werden die Applikationen erst im kommenden Abschnitt in der Chroot-Umgebung.
Temporär benötigt und compiliert werden
ein Macro-Prozessor
Linker und Assembler (zweiter Durchlauf)
der native GCC-Compiler (zweiter Durchlauf)
eine TUI-Bibliothek
Bash
Tools, die das System ändern, wie
chmod
,cp
,dd
etc.file
awk
,grep
,sed
gzip
,tar
,xz
make
,diff
,patch
Hier geht’s zum CodeChapter06.
Zusätzliche temporäre Tools bauen
Bis hierhin ist der Benutzer lfs Eigentümer des LFS-Dateisystems, was in Abschnitt 7 der LFS-Doku auf root geändert wird. Anschliessend werden die Devices console
und null
auf der Platte erzeugt, die ein Kernel beim Boot-Vorgang erwartet.
Durch die aufgelösten zirkularen Abhängigkeiten kann der Benutzer root zum ersten Mal in eine Chroot-Umgebung wechseln, die das Betriebssystem des Build-Hosts für weitere Aufgaben beinahe komplett aussperrt. Eine Ausnahme bildet der laufende Kernel: Damit die Chroot-Umgebung funktioniert, wird die Kommunikation mit diesem über Virtual Kernel File Systeme (VFS) konfiguriert. VFS sind Dateisysteme wie beispielsweise tmpfs
, die keinen Plattenplatz beanspruchen und komplett im Hauptspeicher liegen. Normalerweise werden Geräte unterhalb von /dev
als virtuelles Dateisystem gemountet und bei Erkennung oder beim ersten Zugriff während des Boot-Vorgangs durch Udev erstellt. Zu diesem Zeitpunkt fehlt Udev noch, also werden die benötigten Geräte manuell angelegt und per Bind-Mount eingehängt. Stolperfalle: Wer den LFS Build-Host später neustartet, muss auch die Mount-Befehle für die virtuellen Devices vor den weiteren Arbeiten erneut ausführen.
(lfs chroot) I have no name!:/#
Die endgültige Verzeichnisstrukur inklusive korrekt gesetzter Berechtigungen plus einiger Log-Dateien wird angelegt. Die Verzeichnisstruktur verwendet den Filesystem Hierarchy Standard (FHS) und legt unter anderem die Verzeichnisse {boot,home,mnt,opt,srv}
an, lässt unnötiges wie /usr/local/games
aber weg.
Fehlen noch Standard-Benutzer und -Gruppen. Da es hier keine einheitlichen Vorgaben gibt, orientiert sich LFS an Udev und anderen Distributionen.
Compiliert und installiert werden anschliessend noch Programme, um andere Programme zu testen (diese werden unter einem temporär angelegten Benutzer tester ausgeführt), sowie fehlende Bausteine der Toolchain:
als erstes
libstdc++
(zweiter Durchlauf)ein Paket für Internationalisierungs- und Lokalisierungs-Support
ein Parser-Generator
Perl und Python
Tools für Info-Pages
kleinere Utilities wie
blkid
,dmesg
u.a.
Die Toolchain ist jetzt komplett und unabhängig vom Build-Host.
Am Ende des Abschnitts kümmert sich die LFS-Doku noch um Stripping, Backups und Restore, worauf hier im Code aber verzichtet wird.
Hier geht’s zum CodeChapter07.
LFS bauen
Basis-Software installieren
In diesem Abschnitt der LFS-Dokumentation wird zunächst ein Ausblick auf das Thema Paket-Management gegeben und begründet, warum das Projekt keinen dokumentiert - es würde schlicht den Rahmen sprengen und nicht zur Ausrichtung von LFS passen. Anschliessend ist hier Fleissarbeit angesagt. So kümmert man sich in Kapitel 8 per configure
/make
/make install
darum, dass neben wichtigen Bibliotheken eine ganze Reihe an Applikationen auf der Platte landen, unter anderem:
die Bash
Text-Prozessoren wie
awk
,grep
,sed
Packer und Archiv-Programme wie
bzip
,gzip
,tar
undxz
GCC
der Bootloader GRUB
Man und ManDB
OpenSSL
Perl und Python
der Text-Editor Vim
Udev, welches sich um Geräte kümmert
Die Übersetzung des GCC in diesem Abschnitt ist der mit Abstand zeitintensivste Task im gesamten Projekt - fast die Hälfte der gesamten Compile-Time wird für diesen Schritt benötigt, was an der Ausführung der Test-Suites liegt. Jede Menge FAILED-Meldungen sind hier normal, solange ein grep
auf die von der Testsuite erzeugten Log-Dateien die erwarteten Ergebnisse liefert.
Tipp
Die Unit-Tests werden durch verschiedene Variationen des Befehls make check
oder make test
ausgeführt, teils unter dem Benutzer „tester“ (per su tester -c
) - wer diese überspringt, spart (erheblich) Zeit, riskiert aber auch, das ein oder andere Problem im Build-Prozess zu übersehen.
Nach der ganzen Arbeit wird aufgeräumt: nicht mehr benötigte Bibliotheken und Tools werden genau so entfernt wie der temporäre Benutzer tester. Ist der Nutzer des kommenden LFS kein Programmierer und/oder wird keine Debugging-Funktionalität benötigt, kann 2 GB Platz durch Bereinigung von Debugging-Symbolen eingespart werden (was im Code-Abschnitt berücksichtigt wird). Die Chroot-Umgebung wird verlassen, um sie gleich danach mit eingeschaltetem Bash Path-Hashing (und von dort an immer mit dieser Konfiguration) zu betreten.
Während der Compile-Vorgänge auftretende Warnungen in Bezug auf C-Syntax können übrigens ignoriert werden.
Hier geht’s zum CodeChapter08.
System konfigurieren
In Kapitel 9 konfiguriert man den Netzwerk-Stack: Hier lässt sich auf Wunsch die Verwendung der sogenannten „Predictable Network Interface Device Names“ abschalten, was wir tun. Die erste Netzwerkkarte im System wird von LFS somit später immer klassisch als eth0
erkannt. Die IP-Adresse wird per DHCP bezogen. Anschliessend wird die Namensauflösung konfiguriert und ein Hostname vergeben. Kleinere Konfigurationsarbeiten an der Systemuhr, der Linux-Konsole und der System Locale runden das System ab (im Listing wird ein Schweizerdeutsches Tastaturlayout eingestellt). Wer sich unsicher ist, was passende Locales sein könnten, sucht sich in LFS aus /usr/share/keymaps
und /usr/share/consolefonts
das passende heraus.
ln -s /dev/null /etc/systemd/network/99-default.link
Hier geht’s zum CodeChapter09.
System bootfähig machen
Es wird Zeit, LFS bootfähig einzurichten. Abschnitt 10 startet mit dem Anlegen einer /etc/fstab
, die auf die LFS-Partitionen sda1
(System) und sda2
(Swap) verweist. Anschliessend (und erst jetzt) wird der Linux-Kernel gebaut und installiert. Da bei späteren Erweiterungen wie beispielsweise in BLFS immer mal wieder Umkonfigurationen am Kernel notwendig sind, wird dessen Source Code nach dem Build nicht gelöscht. Mit Hilfe von grub-install
findet der Boot-Loader seinen Weg auf die Platte, der anschliessend noch per grub-mkconfig
konfiguriert wird.
Der Kernel wird im Code-Abschnitt per make defconfig
ohne Interaktion mit sinnvollen Default-Werten konfiguriert.
Wer mag, ändert das und nutzt die TUI-Variante per make menuconfig
, um die unzähligen Parameter des Kernels manuell zu setzen. Wichtig: IPv6 wird von den Machern von Systemd unbedingt empfohlen. Dann sollten diese Kernel-Features ein- bzw. abgeschaltet sein:
General setup -->
[ ] Auditing Support [CONFIG_AUDIT]
[*] Control Group support [CONFIG_CGROUPS]
[ ] Enable deprecated sysfs features to support old userspace tools [CONFIG_SYSFS_DEPRECATED]
[*] Configure standard kernel features (expert users) [CONFIG_EXPERT] --->
[*] open by fhandle syscalls [CONFIG_FHANDLE]
Processor type and features --->
[*] Enable seccomp to safely compute untrusted bytecode [CONFIG_SECCOMP]
Firmware Drivers --->
[*] Export DMI identification via sysfs to userspace [CONFIG_DMIID]
Networking support --->
Networking options --->
<*> The IPv6 protocol [CONFIG_IPV6]
Device Drivers --->
Generic Driver Options --->
[ ] Support for uevent helper [CONFIG_UEVENT_HELPER]
[*] Maintain a devtmpfs filesystem to mount at /dev [CONFIG_DEVTMPFS]
Firmware Loader --->
[ ] Enable the firmware sysfs fallback mechanism [CONFIG_FW_LOADER_USER_HELPER]
File systems --->
[*] Inotify support for userspace [CONFIG_INOTIFY_USER]
Pseudo filesystems --->
[*] Tmpfs POSIX Access Control Lists [CONFIG_TMPFS_POSIX_ACL]
Die erhabensten Momente im Build-Prozess:
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-5.10.17-lfs-10.1-systemd
cp -iv System.map /boot/System.map-5.10.17
cp -iv .config /boot/config-5.10.17
# ...
grub-install /dev/sda
grub-mkconfig --output=/boot/grub/grub.cfg
Hier geht’s zum CodeChapter10.
Abschluss und Reboot
LFS ist nun vollständig installiert. Stolz darf man sich in den beiden Dateien /etc/lsb-release
und /etc/os-release
verewigen. Ein Logout aus der Chroot, Setzen eines Root-Passwortes, Unmounting von $LFS
- und einem Reboot steht nichts mehr im Weg. Ist die LFS-Disk als primäres Bootmedium in der Build-VM ausgewählt, meldet sich nach kurzer Zeit LFS.
Hier geht’s zum CodeChapter11.
Cross-Compiler erklärt
Um den Einfluss des Betriebssystems des Build-Hosts auf LFS zu minimieren und unabhängig von diesem zu werden, erstellen Abschnitt 5 und 6 einen eigenen Cross-Compiler plus Tools, mit deren Hilfe LFS gebaut wird. Deren Lebenszeit ist begrenzt, die Tools werden nur für diesen Zweck in einer isolierten Chroot eingesetzt und anschliessend entfernt.
Der Build-Prozess basiert auf dem Prinzip der Cross-Compilation: Ein Cross-Compiler produziert Code für andere Maschinentypen, wird also normalerweise dazu verwendet, Compiler für andere System-Architekturen zu übersetzen. Auf unserer Build-Maschine ist das theoretisch nicht nötig, da mit hoher Wahrscheinlichkeit auf x86_64 für x86_64 gebaut wird. LFS soll aber auf jeden Fall frei von hineingelinkter Software des Build-Hosts sein, was cross-compilierte Software garantiert - daher der Aufwand.
Um die Vorgehensweise zu verdeutlichen, nimmt die LFS-Dokumentation drei Hosts mit jeweils unterschiedlichen Architekturen an.
Host A besitzt einen Compiler
compilerA
für die eigene Architektur. Der Host ist langsam und seine Kapazitäten begrenzt.Host B besitzt keinen Compiler, ist aber schnell und gut ausgestattet. Dieser soll Software für Host C produzieren.
Host C mit nochmals anderer Architektur besitzt ebenfalls keinen Compiler und ist klein und langsam.
Es werden zwei Cross-Compiler cross-compilerA
und cross-compilerB
benötigt. Das Vorgehen ist wie folgt:
Auf Host A: compilerA baut cross-compilerA.
Auf Host A: cross-compilerA baut cross-compilerB.
Auf Host B: cross-compilerB baut compilerC plus alle Programme für Host C, kann diese aber nicht testen.
Auf Host C: compilerC rebuilded und testet sich selbst.
Damit für LFS auf dem gleichen Host Cross-Compilation funktioniert, muss das bekannte Vendor-Triplet x86_64-pc-linux-gnu
(was heutzutage immer vier Komponenten enthält) in LFS_TGT
behutsam angepasst werden, um verschiedene Architekturen vorzugaukeln. Der Ablauf sieht dann so aus:
Auf dem Build-Host: compilerBuildHost baut cross-compilerBuildHost
Auf dem Build-Host: cross-compilerBuildHost baut compilerLFS
in LFS Chroot: compilerLFS rebuilded und testet sich selbst.
Für LFS muss mit Hilfe des Cross-Compilers nicht nur der C-Compiler, sondern auch glibc
und libstdc++
gebaut werden. Das Problem dabei: der zu erstellende C-Compiler baut intern auf libgcc
, welche wiederum gegen glibc
gelinkt sein muss - die es noch nicht gibt.
Um diese zirkulären Abhängigkeiten - oder das Henne-Ei-Problem - zu umgehen, wird zunächst eine Minimalversion des cross-compilerBuildHost erstellt, die gerade gut genug ist, um eine vollwertige glibc
sowie eine minimal funktionsfähige libstdc++
zu bauen. libstdc++
wird später in Chroot nochmals gebaut, diesesmal komplett. Weitere Details bietet die Dokumentation.
Troubleshooting
- Der Build-Vorgang meldet „libtool: warning: remember to run ‚libtool –finish /usr/lib‘“ (File-5.39)
Liegt am
prefix
-Parameter. Man muss nichts tun, also nicht ausführen und einfach ignorieren.- The system has no more ptys. Ask your system administrator to create more.
Möglicherweise wurde der Build-Host nach Schritt 7.3 neu gestartet, und vergessen, die Device-Nodes vor dem Chroot erneut zu mounten (also Code-Abschnitt 7.3 und 7.4 nochmals auszuführen).
- LFS bleibt beim Boot einfach mit der Meldung „GRUB“ stehen
Die LFS-Disk wurde mit BIOS/GPT eingerichtet.
/boot
muss dann auf eine eigene Partition ausgelagert werden.- LFS zeigt den GRUB Boot Loader. Will man in LFS booten, erhält man die Meldung „error: hd1 cannot get C/H/S values. „
Tritt gern bei manuell erstellter
/boot/grub/grub.cfg
auf. Wird die LFS-Disk als zweite Disk im System als erstes Boot-Medium spezifiziert, muss die/boot/grub/grub.cfg
den Eintragset root=(hd0,1)
aufweisen. Ist sie das zweite Boot-Medium, aufset root=(hd1,1)
setzen, usw.- „Kernel Panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)“
Es fehlen ziemlich sicher Treiber für das verwendete Medium. Falls VirtIO-Disks verwendet wurden, auf SATA-Disks umsteigen, oder die Treiber hinzufügen.
Have fun :-)
Wer jetzt einfach mal Bauen möchte: Die nachfolgenden Code-Abschnitte sind 1:1 der LFS-Doku entnommen, enthalten aber keinen Fliesstext mehr und sind soweit wie möglich per Copy & Paste in ein Terminal auf einem CentOS 8 Minimal lauffähig. Auf das manuelle Prüfen mancher Ausgaben wird bewusst verzichtet.
Copy & Paste Shell-Commands
Systemd-Version von LFS v10.1 mit BIOS/MBR-Boot, SATA-Disk, Intel e1000-Netzwerkkarte, auf CentOS 8 Minimal.
Copyright © 1999-2021, Gerard Beekmans
# Chapter 2. Preparing the Host System
dnf -y install yum-utils
yum config-manager --set-enabled powertools
dnf -y install bison byacc bzip2 gcc-c++ patch perl python3 tar texinfo wget
cat > version-check.sh << "EOF"
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH
echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1
if [ -h /usr/bin/yacc ]; then
echo "/usr/bin/yacc -> $(readlink -f /usr/bin/yacc)";
elif [ -x /usr/bin/yacc ]; then
echo yacc is $(/usr/bin/yacc -V | head -n1)
else
echo "yacc not found"
fi
bzip2 --version 2>&1 < /dev/null | head -n1 | cut -d" " -f1,6-
echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1
if [ -h /usr/bin/awk ]; then
echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`";
elif [ -x /usr/bin/awk ]; then
echo awk is `/usr/bin/awk --version | head -n1`
else
echo "awk not found"
fi
gcc --version | head -n1
g++ --version | head -n1
ldd --version | head -n1 | cut -d" " -f2- # glibc version
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
python3 --version
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1 # texinfo version
xz --version | head -n1
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
then echo "g++ compilation OK";
else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF
bash version-check.sh
# init the SECOND disk (SATA / SCSI)
parted /dev/sda mklabel msdos
# becomes /, leaving space for the MBR
parted /dev/sda mkpart primary 1MiB 10G
# sda1 will be a bootable BIOS/MBR partition
parted /dev/sda set 1 boot on
# becomes swap
parted /dev/sda mkpart primary 10G 12G
# becomes /home
parted /dev/sda mkpart primary 12G 100%
partprobe
sync
mkfs --verbose --type ext4 /dev/sda1
mkswap --check /dev/sda2
swapon /dev/sda2
mkfs --verbose --type ext4 /dev/sda3
export LFS=/mnt/lfs
echo 'export LFS=/mnt/lfs' >> /root/.bash_profile
export LC_CTYPE=POSIX
echo 'export LC_CTYPE=POSIX' > /etc/profile.d/locale.sh
mkdir -pv $LFS
echo '/dev/sda1 /mnt/lfs ext4 defaults 0 0' >> /etc/fstab
echo '/dev/sda2 swap swap defaults 0 0' >> /etc/fstab
mount --all
mkdir -pv $LFS/home
echo '/dev/sda3 /mnt/lfs/home ext4 defaults 0 0' >> /etc/fstab
mount --all
# takes round about 10 minutes or more
# Chapter 3. Packages and Patches
# try to use a mirror like http://lfs.linux-sysadmin.com instead of http://www.linuxfromscratch.org
mkdir -v $LFS/sources
chmod -v a+wt $LFS/sources
wget http://lfs.linux-sysadmin.com/lfs/downloads/stable-systemd/wget-list
# sequential downloading
# might take some minutes
wget --input-file=wget-list --continue --directory-prefix=$LFS/sources
wget http://lfs.linux-sysadmin.com/lfs/downloads/stable-systemd/md5sums --directory-prefix=$LFS/sources
pushd $LFS/sources
md5sum -c md5sums 1> /dev/null
popd
# Chapter 4. Final Preparations
mkdir -pv $LFS/{bin,etc,lib,sbin,usr,var}
case $(uname -m) in
x86_64) mkdir -pv $LFS/lib64 ;;
esac
# this is for the cross-compiler
mkdir -pv $LFS/tools
groupadd lfs
useradd --shell /bin/bash --gid lfs --create-home --skel /dev/null lfs
chown -v lfs $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -v lfs $LFS/lib64 ;;
esac
chown -v lfs $LFS/sources
su - lfs
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
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
logout
su - lfs
# takes round about 35 minutes or more, without tests
# Chapter 5 Compiling a Cross-Toolchain
# 5.1 Introduction
# 5.2 Binutils-2.36.1 - Pass 1
# 5.2.1. Installation of Cross Binutils
cd $LFS/sources
tar xf binutils-2.36.1.tar.xz
cd binutils-2.36.1
mkdir -v build
cd build
../configure --prefix=$LFS/tools \
--with-sysroot=$LFS \
--target=$LFS_TGT \
--disable-nls \
--disable-werror
make
make install
cd $LFS/sources
rm -rf binutils-2.36.1
# 5.3 GCC-10.2.0 - Pass 1
# 5.3.1. Installation of Cross GCC
cd $LFS/sources
tar xf gcc-10.2.0.tar.xz
cd gcc-10.2.0
tar -xf ../mpfr-4.1.0.tar.xz
mv -v mpfr-4.1.0 mpfr
tar -xf ../gmp-6.2.1.tar.xz
mv -v gmp-6.2.1 gmp
tar -xf ../mpc-1.2.1.tar.gz
mv -v mpc-1.2.1 mpc
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
../configure \
--target=$LFS_TGT \
--prefix=$LFS/tools \
--with-glibc-version=2.11 \
--with-sysroot=$LFS \
--with-newlib \
--without-headers \
--enable-initfini-array \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-decimal-float \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
make
make install
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/install-tools/include/limits.h
cd $LFS/sources
rm -rf gcc-10.2.0
# 5.4 Linux-5.10.17 API Headers
# 5.4.1. Installation of Linux API Headers
cd $LFS/sources
tar xf linux-5.10.17.tar.xz
cd linux-5.10.17
make mrproper
make headers
find usr/include -name '.*' -delete
rm usr/include/Makefile
cp -rv usr/include $LFS/usr
cd $LFS/sources
rm -rf linux-5.10.17
# 5.5 Glibc-2.33
# 5.5.1. Installation of Glibc
cd $LFS/sources
tar xf glibc-2.33.tar.xz
cd glibc-2.33
case $(uname -m) in
i?86) ln -sfv ld-linux.so.2 $LFS/lib/ld-lsb.so.3
;;
x86_64) ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64
ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64/ld-lsb-x86-64.so.3
;;
esac
patch -Np1 -i ../glibc-2.33-fhs-1.patch
mkdir -v build
cd build
../configure \
--prefix=/usr \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=3.2 \
--with-headers=$LFS/usr/include \
libc_cv_slibdir=/lib
make
make DESTDIR=$LFS install
# NORMALLY STOP HERE AND DO THE TEST BELOW
echo 'int main(){}' > dummy.c
$LFS_TGT-gcc dummy.c
readelf -l a.out | grep '/ld-linux'
rm -v dummy.c a.out
# OUTPUT LIKE "[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]"?
# THEN GO ON
# ELSE STOP AND FIX
# takes round about 1 minute or more, without tests
$LFS/tools/libexec/gcc/$LFS_TGT/10.2.0/install-tools/mkheaders
cd $LFS/sources
rm -rf glibc-2.33
# 5.6 Libstdc++ from GCC-10.2.0, Pass 1
# 5.6.1. Installation of Target Libstdc++
cd $LFS/sources
tar xf gcc-10.2.0.tar.xz
cd gcc-10.2.0
mkdir -v build
cd build
../libstdc++-v3/configure \
--host=$LFS_TGT \
--build=$(../config.guess) \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/10.2.0
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf gcc-10.2.0
# takes round about 35 minutes or more, without tests
# Chapter 6 Cross Compiling Temporary Tools
# 6.1 Introduction
# 6.2 M4-1.4.18
# 6.2.1. Installation of M4
cd $LFS/sources
tar xf m4-1.4.18.tar.xz
cd m4-1.4.18
sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf m4-1.4.18
# 6.3 Ncurses-6.2
# 6.3.1. Installation of Ncurses
cd $LFS/sources
tar xf ncurses-6.2.tar.gz
cd ncurses-6.2
sed -i s/mawk// configure
mkdir build
pushd build
../configure
make -C include
make -C progs tic
popd
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(./config.guess) \
--mandir=/usr/share/man \
--with-manpage-format=normal \
--with-shared \
--without-debug \
--without-ada \
--without-normal \
--enable-widec
make
make DESTDIR=$LFS TIC_PATH=$(pwd)/build/progs/tic install
echo "INPUT(-lncursesw)" > $LFS/usr/lib/libncurses.so
mv -v $LFS/usr/lib/libncursesw.so.6* $LFS/lib
ln -sfv ../../lib/$(readlink $LFS/usr/lib/libncursesw.so) $LFS/usr/lib/libncursesw.so
cd $LFS/sources
rm -rf ncurses-6.2
# 6.4 Bash-5.1
# 6.4.1. Installation of Bash
cd $LFS/sources
tar xf bash-5.1.tar.gz
cd bash-5.1
./configure --prefix=/usr \
--build=$(support/config.guess) \
--host=$LFS_TGT \
--without-bash-malloc
make
make DESTDIR=$LFS install
mv $LFS/usr/bin/bash $LFS/bin/bash
ln -sv bash $LFS/bin/sh
cd $LFS/sources
rm -rf bash-5.1
# 6.5 Coreutils-8.32
# 6.5.1. Installation of Coreutils
cd $LFS/sources
tar xf coreutils-8.32.tar.xz
cd coreutils-8.32
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess) \
--enable-install-program=hostname \
--enable-no-install-program=kill,uptime
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} $LFS/bin
mv -v $LFS/usr/bin/{false,ln,ls,mkdir,mknod,mv,pwd,rm} $LFS/bin
mv -v $LFS/usr/bin/{rmdir,stty,sync,true,uname} $LFS/bin
mv -v $LFS/usr/bin/{head,nice,sleep,touch} $LFS/bin
mv -v $LFS/usr/bin/chroot $LFS/usr/sbin
mkdir -pv $LFS/usr/share/man/man8
mv -v $LFS/usr/share/man/man1/chroot.1 $LFS/usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' $LFS/usr/share/man/man8/chroot.8
cd $LFS/sources
rm -rf coreutils-8.32
# 6.6 Diffutils-3.7
# 6.6.1. Installation of Diffutils
cd $LFS/sources
tar xf diffutils-3.7.tar.xz
cd diffutils-3.7
./configure --prefix=/usr --host=$LFS_TGT
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf diffutils-3.7
# 6.7 File-5.39
# 6.7.1. Installation of File
cd $LFS/sources
tar xf file-5.39.tar.gz
cd file-5.39
mkdir build
pushd build
../configure --disable-bzlib \
--disable-libseccomp \
--disable-xzlib \
--disable-zlib
make
popd
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)
make FILE_COMPILE=$(pwd)/build/src/file
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf file-5.39
# 6.8 Findutils-4.8.0
# 6.8.1. Installation of Findutils
cd $LFS/sources
tar xf findutils-4.8.0.tar.xz
cd findutils-4.8.0
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/find $LFS/bin
sed -i 's|find:=${BINDIR}|find:=/bin|' $LFS/usr/bin/updatedb
cd $LFS/sources
rm -rf findutils-4.8.0
# 6.9 Gawk-5.1.0
# 6.9.1. Installation of Gawk
cd $LFS/sources
tar xf gawk-5.1.0.tar.xz
cd gawk-5.1.0
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(./config.guess)
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf gawk-5.1.0
# 6.10 Grep-3.6
# 6.10.1. Installation of Grep
cd $LFS/sources
tar xf grep-3.6.tar.xz
cd grep-3.6
./configure --prefix=/usr \
--host=$LFS_TGT \
--bindir=/bin
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf grep-3.6
# 6.11 Gzip-1.10
# 6.11.1. Installation of Gzip
cd $LFS/sources
tar xf gzip-1.10.tar.xz
cd gzip-1.10
./configure --prefix=/usr --host=$LFS_TGT
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/gzip $LFS/bin
cd $LFS/sources
rm -rf gzip-1.10
# 6.12 Make-4.3
# 6.12.1. Installation of Make
cd $LFS/sources
tar xf make-4.3.tar.gz
cd make-4.3
./configure --prefix=/usr \
--without-guile \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf make-4.3
# 6.13 Patch-2.7.6
# 6.13.1. Installation of Patch
cd $LFS/sources
tar xf patch-2.7.6.tar.xz
cd patch-2.7.6
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf patch-2.7.6
# 6.14 Sed-4.8
# 6.14.1. Installation of Sed
cd $LFS/sources
tar xf sed-4.8.tar.xz
cd sed-4.8
./configure --prefix=/usr \
--host=$LFS_TGT \
--bindir=/bin
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf sed-4.8
# 6.15 Tar-1.34
# 6.15.1. Installation of Tar
cd $LFS/sources
tar xf tar-1.34.tar.xz
cd tar-1.34
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess) \
--bindir=/bin
make
make DESTDIR=$LFS install
cd $LFS/sources
rm -rf tar-1.34
# 6.16 Xz-5.2.5
# 6.16.1. Installation of Xz
cd $LFS/sources
tar xf xz-5.2.5.tar.xz
cd xz-5.2.5
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess) \
--disable-static \
--docdir=/usr/share/doc/xz-5.2.5
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/{lzma,unlzma,lzcat,xz,unxz,xzcat} $LFS/bin
mv -v $LFS/usr/lib/liblzma.so.* $LFS/lib
ln -svf ../../lib/$(readlink $LFS/usr/lib/liblzma.so) $LFS/usr/lib/liblzma.so
cd $LFS/sources
rm -rf xz-5.2.5
# 6.17 Binutils-2.36.1 - Pass 2
# 6.17.1. Installation of Binutils
cd $LFS/sources
tar xf binutils-2.36.1.tar.xz
cd binutils-2.36.1
mkdir -v build
cd build
../configure \
--prefix=/usr \
--build=$(../config.guess) \
--host=$LFS_TGT \
--disable-nls \
--enable-shared \
--disable-werror \
--enable-64-bit-bfd
make
make DESTDIR=$LFS install
install -vm755 libctf/.libs/libctf.so.0.0.0 $LFS/usr/lib
cd $LFS/sources
rm -rf binutils-2.36.1
# 6.18 GCC-10.2.0 - Pass 2
# 6.18.1. Installation of GCC
cd $LFS/sources
tar xf gcc-10.2.0.tar.xz
cd gcc-10.2.0
tar -xf ../mpfr-4.1.0.tar.xz
mv -v mpfr-4.1.0 mpfr
tar -xf ../gmp-6.2.1.tar.xz
mv -v gmp-6.2.1 gmp
tar -xf ../mpc-1.2.1.tar.gz
mv -v mpc-1.2.1 mpc
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' -i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
mkdir -pv $LFS_TGT/libgcc
ln -s ../../../libgcc/gthr-posix.h $LFS_TGT/libgcc/gthr-default.h
../configure \
--build=$(../config.guess) \
--host=$LFS_TGT \
--prefix=/usr \
CC_FOR_TARGET=$LFS_TGT-gcc \
--with-build-sysroot=$LFS \
--enable-initfini-array \
--disable-nls \
--disable-multilib \
--disable-decimal-float \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
make
make DESTDIR=$LFS install
ln -sv gcc $LFS/usr/bin/cc
cd $LFS/sources
rm -rf gcc-10.2.0
# Chapter 7 Entering Chroot and Building Additional Temporary Tools
# 7.1 Introduction
# 7.2 Changing Ownership
# switch to user "root" again
exit
chown -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -R root:root $LFS/lib64 ;;
esac
# 7.3 Preparing Virtual Kernel File Systems
mkdir -pv $LFS/{dev,proc,sys,run}
# 7.3.1. Creating Initial Device Nodes
mknod -m 600 $LFS/dev/console c 5 1
mknod -m 666 $LFS/dev/null c 1 3
mount -v --bind /dev $LFS/dev
mount -v --bind /dev/pts $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
mkdir -pv $LFS/$(readlink $LFS/dev/shm)
fi
# 7.4 Entering the Chroot Environment
chroot "$LFS" /usr/bin/env -i \
HOME=/root \
TERM="$TERM" \
PS1='(lfs chroot) \u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/bin/bash --login +h
# 7.5 Creating Directories
mkdir -pv /{boot,home,mnt,opt,srv}
mkdir -pv /etc/{opt,sysconfig}
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}
ln -sfv /run /var/run
ln -sfv /run/lock /var/lock
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
# 7.6 Creating Essential Files and Symlinks
ln -sv /proc/self/mounts /etc/mtab
echo "127.0.0.1 localhost $(hostname)" > /etc/hosts
cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/bin/false
daemon:x:6:6:Daemon User:/dev/null:/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/bin/false
systemd-bus-proxy:x:72:72:systemd Bus Proxy:/:/bin/false
systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/bin/false
systemd-journal-remote:x:74:74:systemd Journal Remote:/:/bin/false
systemd-journal-upload:x:75:75:systemd Journal Upload:/:/bin/false
systemd-network:x:76:76:systemd Network Management:/:/bin/false
systemd-resolve:x:77:77:systemd Resolver:/:/bin/false
systemd-timesync:x:78:78:systemd Time Synchronization:/:/bin/false
systemd-coredump:x:79:79:systemd Core Dumper:/:/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF
cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
kvm:x:61:
systemd-bus-proxy:x:72:
systemd-journal-gateway:x:73:
systemd-journal-remote:x:74:
systemd-journal-upload:x:75:
systemd-network:x:76:
systemd-resolve:x:77:
systemd-timesync:x:78:
systemd-coredump:x:79:
uuidd:x:80:
wheel:x:97:
nogroup:x:99:
users:x:999:
EOF
echo "tester:x:$(ls -n $(tty) | cut -d" " -f3):101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester
exec /bin/bash --login +h
# takes round about 15 minutes or more, without tests
touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp
# 7.7 Libstdc++ from GCC-10.2.0, Pass 2
# 7.7.1. Installation of Target Libstdc++
cd $LFS/sources
tar xf gcc-10.2.0.tar.xz
cd gcc-10.2.0
ln -s gthr-posix.h libgcc/gthr-default.h
mkdir -v build
cd build
../libstdc++-v3/configure \
CXXFLAGS="-g -O2 -D_GNU_SOURCE" \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--host=$(uname -m)-lfs-linux-gnu \
--disable-libstdcxx-pch
make
make install
cd $LFS/sources
rm -rf gcc-10.2.0
# 7.8 Gettext-0.21
# 7.8.1. Installation of Gettext
cd /sources
tar xf gettext-0.21.tar.xz
cd gettext-0.21
./configure --disable-shared
make
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin
cd /sources
rm -rf gettext-0.21
# 7.9 Bison-3.7.5
# 7.9.1. Installation of Bison
cd /sources
tar xf bison-3.7.5.tar.xz
cd bison-3.7.5
./configure --prefix=/usr \
--docdir=/usr/share/doc/bison-3.7.5
make
make install
cd /sources
rm -rf bison-3.7.5
# 7.10 Perl-5.32.1
# 7.10.1. Installation of Perl
cd /sources/
tar xf perl-5.32.1.tar.xz
cd perl-5.32.1
sh Configure -des \
-Dprefix=/usr \
-Dvendorprefix=/usr \
-Dprivlib=/usr/lib/perl5/5.32/core_perl \
-Darchlib=/usr/lib/perl5/5.32/core_perl \
-Dsitelib=/usr/lib/perl5/5.32/site_perl \
-Dsitearch=/usr/lib/perl5/5.32/site_perl \
-Dvendorlib=/usr/lib/perl5/5.32/vendor_perl \
-Dvendorarch=/usr/lib/perl5/5.32/vendor_perl
make
make install
cd /sources/
rm -rf perl-5.32.1
# 7.11 Python-3.9.2
# 7.11.1. Installation of Python
cd /sources
tar xf Python-3.9.2.tar.xz
cd Python-3.9.2
./configure --prefix=/usr \
--enable-shared \
--without-ensurepip
make
make install
cd /sources
rm -rf Python-3.9.2
# 7.12 Texinfo-6.7
# 7.12.1. Installation of Texinfo
cd /sources
tar xf texinfo-6.7.tar.xz
cd texinfo-6.7
./configure --prefix=/usr
make
make install
cd /sources
rm -rf texinfo-6.7
# 7.13 Util-linux-2.36.2
# 7.13.1. Installation of Util-linux
cd /sources
tar xf util-linux-2.36.2.tar.xz
cd util-linux-2.36.2
mkdir -pv /var/lib/hwclock
./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
--docdir=/usr/share/doc/util-linux-2.36.2 \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--without-python \
runstatedir=/run
make
make install
cd /sources
rm -rf util-linux-2.36.2
# 7.14 Cleaning up and Saving the Temporary System
find /usr/{lib,libexec} -name \*.la -delete
rm -rf /usr/share/{info,man,doc}/*
# takes round about 25 minutes or more, without tests
# Chapter 8 Installing Basic System Software
# 8.3 Man-pages-5.10
# 8.3.1. Installation of Man-pages
cd /sources
tar xf man-pages-5.10.tar.xz
cd man-pages-5.10
make install
cd /sources
rm -rf man-pages-5.10
# 8.4 Iana-Etc-20210202
# 8.4.1. Installation of Iana-Etc
cd /sources
tar xf iana-etc-20210202.tar.gz
cd iana-etc-20210202
cp services protocols /etc
cd /sources
rm -rf iana-etc-20210202
# 8.5 Glibc-2.33
# 8.5.1. Installation of Glibc
cd /sources
tar xf glibc-2.33.tar.xz
cd glibc-2.33
patch -Np1 -i ../glibc-2.33-fhs-1.patch
sed -e '402a\ *result = local->data.services[database_index];' \
-i nss/nss_database.c
mkdir -v build
cd build
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=3.2 \
--enable-stack-protector=strong \
--with-headers=/usr/include \
libc_cv_slibdir=/lib
make
#make check
touch /etc/ld.so.conf
sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile
make install
cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd
install -v -Dm644 ../nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf
install -v -Dm644 ../nscd/nscd.service /lib/systemd/system/nscd.service
mkdir -pv /usr/lib/locale
localedef -i POSIX -f UTF-8 C.UTF-8 2> /dev/null || true
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 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_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 it_IT -f ISO-8859-1 it_IT
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.SIJS 2> /dev/null || true
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.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
make localedata/install-locales
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
tar -xf ../../tzdata2021a.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
#tzselect
ln -sfv /usr/share/zoneinfo/Europe/Zurich /etc/localtime
cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
EOF
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
cd /sources
rm -rf glibc-2.33
# 8.6 Zlib-1.2.11
# 8.6.1. Installation of Zlib
cd /sources
tar xf zlib-1.2.11.tar.xz
cd zlib-1.2.11
./configure --prefix=/usr
make
#make check
make install
mv -v /usr/lib/libz.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libz.so) /usr/lib/libz.so
rm -fv /usr/lib/libz.a
cd /sources
rm -rf zlib-1.2.11
# 8.7 Bzip2-1.0.8
# 8.7.1. Installation of Bzip2
cd /sources
tar xf bzip2-1.0.8.tar.gz
cd bzip2-1.0.8
patch -Np1 -i ../bzip2-1.0.8-install_docs-1.patch
sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile
sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile
make -f Makefile-libbz2_so
make clean
make
make PREFIX=/usr install
cp -v bzip2-shared /bin/bzip2
cp -av libbz2.so* /lib
ln -sv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.so
rm -v /usr/bin/{bunzip2,bzcat,bzip2}
ln -sv bzip2 /bin/bunzip2
ln -sv bzip2 /bin/bzcat
rm -fv /usr/lib/libbz2.a
cd /sources
rm -rf bzip2-1.0.8
# 8.8 Xz-5.2.5
# 8.8.1. Installation of Xz
cd /sources
tar xf xz-5.2.5.tar.xz
cd xz-5.2.5
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/xz-5.2.5
make
#make check
make install
mv -v /usr/bin/{lzma,unlzma,lzcat,xz,unxz,xzcat} /bin
mv -v /usr/lib/liblzma.so.* /lib
ln -svf ../../lib/$(readlink /usr/lib/liblzma.so) /usr/lib/liblzma.so
cd /sources
rm -rf xz-5.2.5
# 8.9 Zstd-1.4.8
# 8.9.1. Installation of Zstd
cd /sources/
tar xf zstd-1.4.8.tar.gz
cd zstd-1.4.8
make
#make check
make prefix=/usr install
rm -v /usr/lib/libzstd.a
mv -v /usr/lib/libzstd.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libzstd.so) /usr/lib/libzstd.so
cd /sources
rm -rf zstd-1.4.8
# 8.13 File-5.39
# 8.13.1. Installation of File
cd /sources
tar xf file-5.39.tar.gz
cd file-5.39
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf file-5.39
# 8.11 Readline-8.1
# 8.11.1. Installation of Readline
cd /sources
tar xf readline-8.1.tar.gz
cd readline-8.1
sed -i '/MV.*old/d' Makefile.in
sed -i '/{OLDSUFF}/c:' support/shlib-install
./configure --prefix=/usr \
--disable-static \
--with-curses \
--docdir=/usr/share/doc/readline-8.1
make SHLIB_LIBS="-lncursesw"
make SHLIB_LIBS="-lncursesw" install
mv -v /usr/lib/lib{readline,history}.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libreadline.so) /usr/lib/libreadline.so
ln -sfv ../../lib/$(readlink /usr/lib/libhistory.so ) /usr/lib/libhistory.so
install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-8.1
cd /sources
rm -rf readline-8.1
# 8.12 M4-1.4.18
# 8.12.1. Installation of M4
cd /sources
tar xf m4-1.4.18.tar.xz
cd m4-1.4.18
sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf m4-1.4.18
# 8.13 Bc-3.3.0
# 8.13.1. Installation of Bc
cd /sources
tar xf bc-3.3.0.tar.xz
cd bc-3.3.0
PREFIX=/usr CC=gcc ./configure.sh -G -O3
make
#make test
make install
cd /sources
rm -rf bc-3.3.0
# 8.14 Flex-2.6.4
# 8.14.1. Installation of Flex
cd /sources
tar xf flex-2.6.4.tar.gz
cd flex-2.6.4
./configure --prefix=/usr \
--docdir=/usr/share/doc/flex-2.6.4 \
--disable-static
make
#make check
make install
ln -sv flex /usr/bin/lex
cd /sources
rm -rf flex-2.6.4
# 8.15 Tcl-8.6.11
# 8.15.1. Installation of Tcl
cd /sources
tar xf tcl8.6.11-src.tar.gz
cd tcl8.6.11
tar -xf ../tcl8.6.11-html.tar.gz --strip-components=1
SRCDIR=$(pwd)
cd unix
./configure --prefix=/usr \
--mandir=/usr/share/man \
$([ "$(uname -m)" = x86_64 ] && echo --enable-64bit)
make
sed -e "s|$SRCDIR/unix|/usr/lib|" \
-e "s|$SRCDIR|/usr/include|" \
-i tclConfig.sh
sed -e "s|$SRCDIR/unix/pkgs/tdbc1.1.2|/usr/lib/tdbc1.1.2|" \
-e "s|$SRCDIR/pkgs/tdbc1.1.2/generic|/usr/include|" \
-e "s|$SRCDIR/pkgs/tdbc1.1.2/library|/usr/lib/tcl8.6|" \
-e "s|$SRCDIR/pkgs/tdbc1.1.2|/usr/include|" \
-i pkgs/tdbc1.1.2/tdbcConfig.sh
sed -e "s|$SRCDIR/unix/pkgs/itcl4.2.1|/usr/lib/itcl4.2.1|" \
-e "s|$SRCDIR/pkgs/itcl4.2.1/generic|/usr/include|" \
-e "s|$SRCDIR/pkgs/itcl4.2.1|/usr/include|" \
-i pkgs/itcl4.2.1/itclConfig.sh
unset SRCDIR
#make test
make install
chmod -v u+w /usr/lib/libtcl8.6.so
make install-private-headers
ln -sfv tclsh8.6 /usr/bin/tclsh
mv /usr/share/man/man3/{Thread,Tcl_Thread}.3
cd /sources
rm -rf tcl8.6.11
# 8.16 Expect-5.45.4
# 8.16.1. Installation of Expect
cd /sources
tar xf expect5.45.4.tar.gz
cd expect5.45.4
./configure --prefix=/usr \
--with-tcl=/usr/lib \
--enable-shared \
--mandir=/usr/share/man \
--with-tclinclude=/usr/include
make
#make test
make install
ln -svf expect5.45.4/libexpect5.45.4.so /usr/lib
cd /sources
rm -rf expect5.45.4
# 8.17 DejaGNU-1.6.2
# 8.17.1. Installation of DejaGNU
cd /sources
tar xf dejagnu-1.6.2.tar.gz
cd dejagnu-1.6.2
./configure --prefix=/usr
makeinfo --html --no-split -o doc/dejagnu.html doc/dejagnu.texi
makeinfo --plaintext -o doc/dejagnu.txt doc/dejagnu.texi
make install
install -v -dm755 /usr/share/doc/dejagnu-1.6.2
install -v -m644 doc/dejagnu.{html,txt} /usr/share/doc/dejagnu-1.6.2
#make check
cd /sources
rm -rf dejagnu-1.6.2
# 8.18 Binutils-2.36.1
# 8.18.1. Installation of Binutils
cd /sources
tar xf binutils-2.36.1.tar.xz
cd binutils-2.36.1
expect -c "spawn ls"
# This command should only output the following (and nothing more):
# spawn ls
# takes round about 40 minutes or more, without tests
sed -i '/@\tincremental_copy/d' gold/testsuite/Makefile.in
mkdir -v build
cd build
../configure --prefix=/usr \
--enable-gold \
--enable-ld=default \
--enable-plugins \
--enable-shared \
--disable-werror \
--enable-64-bit-bfd \
--with-system-zlib
make tooldir=/usr
#make -k check
make tooldir=/usr install
rm -fv /usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes}.a
cd /sources
rm -rf binutils-2.36.1
# 8.19 GMP-6.2.1
# 8.19.1. Installation of GMP
cd /sources
tar xf gmp-6.2.1.tar.xz
cd gmp-6.2.1
ABI=32
./configure ...
cp -v configfsf.guess config.guess
cp -v configfsf.sub config.sub
./configure --prefix=/usr \
--enable-cxx \
--disable-static \
--docdir=/usr/share/doc/gmp-6.2.1
make
make html
#make check 2>&1 | tee gmp-check-log
awk '/# PASS:/{total+=$3} ; END{print total}' gmp-check-log
make install
make install-html
cd /sources
rm -rf gmp-6.2.1
# 8.20 MPFR-4.1.0
# 8.20.1. Installation of MPFR
cd /sources/
tar xf mpfr-4.1.0.tar.xz
cd mpfr-4.1.0
./configure --prefix=/usr \
--disable-static \
--enable-thread-safe \
--docdir=/usr/share/doc/mpfr-4.1.0
make
make html
#make check
make install
make install-html
cd /sources
rm -rf mpfr-4.1.0
# 8.21 MPC-1.2.1
# 8.21.1. Installation of MPC
cd /sources
tar xf mpc-1.2.1.tar.gz
cd mpc-1.2.1
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/mpc-1.2.1
make
make html
#make check
make install
make install-html
cd /sources
rm -rf mpc-1.2.1
# 8.22 Attr-2.4.48
# 8.22.1. Installation of Attr
cd /sources
tar xf attr-2.4.48.tar.gz
cd attr-2.4.48
./configure --prefix=/usr \
--disable-static \
--sysconfdir=/etc \
--docdir=/usr/share/doc/attr-2.4.48
make
#make check
make install
mv -v /usr/lib/libattr.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libattr.so) /usr/lib/libattr.so
cd /sources
rm -rf attr-2.4.48
# 8.23 Acl-2.2.53
# 8.23.1. Installation of Acl
cd /sources
tar xf acl-2.2.53.tar.gz
cd acl-2.2.53
./configure --prefix=/usr \
--disable-static \
--libexecdir=/usr/lib \
--docdir=/usr/share/doc/acl-2.2.53
make
make install
mv -v /usr/lib/libacl.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libacl.so) /usr/lib/libacl.so
cd /sources
rm -rf acl-2.2.53
# 8.24 Libcap-2.48
# 8.24.1. Installation of Libcap
cd /sources
tar xf libcap-2.48.tar.xz
cd libcap-2.48
sed -i '/install -m.*STA/d' libcap/Makefile
make prefix=/usr lib=lib
#make test
make prefix=/usr lib=lib install
for libname in cap psx; do
mv -v /usr/lib/lib${libname}.so.* /lib
ln -sfv ../../lib/lib${libname}.so.2 /usr/lib/lib${libname}.so
chmod -v 755 /lib/lib${libname}.so.2.48
done
cd /sources/
rm -rf libcap-2.48
# 8.25 Shadow-4.8.1
# 8.25.1. Installation of Shadow
cd /sources
tar xf shadow-4.8.1.tar.xz
cd shadow-4.8.1
sed -i 's/groups$(EXEEXT) //' src/Makefile.in
find man -name Makefile.in -exec sed -i 's/groups\.1 / /' {} \;
find man -name Makefile.in -exec sed -i 's/getspnam\.3 / /' {} \;
find man -name Makefile.in -exec sed -i 's/passwd\.5 / /' {} \;
sed -e 's:#ENCRYPT_METHOD DES:ENCRYPT_METHOD SHA512:' \
-e 's:/var/spool/mail:/var/mail:' \
-i etc/login.defs
sed -i 's:DICTPATH.*:DICTPATH\t/lib/cracklib/pw_dict:' etc/login.defs
sed -i 's/1000/999/' etc/useradd
touch /usr/bin/passwd
./configure --sysconfdir=/etc \
--with-group-name-max-length=32
make
make install
pwconv
grpconv
sed -i 's/yes/no/' /etc/default/useradd
cd /sources
rm -rf shadow-4.8.1
# 8.25.3. Setting the root password
# I Would do that later
# passwd root
# 8.26 GCC-10.2.0
# 8.26.1. Installation of GCC
cd /sources
tar xf gcc-10.2.0.tar.xz
cd gcc-10.2.0
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
../configure --prefix=/usr \
LD=ld \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib
make
# takes minimum 120 minutes
# In this section, the test suite for GCC is considered critical. Do not skip it under any circumstance.
ulimit -s 32768
chown -Rv tester .
su tester -c "PATH=$PATH make -k check"
../contrib/test_summary | grep -A7 Summ
make install
rm -rf /usr/lib/gcc/$(gcc -dumpmachine)/10.2.0/include-fixed/bits/
chown -v -R root:root \
/usr/lib/gcc/*linux-gnu/10.2.0/include{,-fixed}
ln -sv ../usr/bin/cpp /lib
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/10.2.0/liblto_plugin.so \
/usr/lib/bfd-plugins/
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
# [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
#/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/crt1.o succeeded
#/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/crti.o succeeded
#/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/crtn.o succeeded
grep -B4 '^ /usr/include' dummy.log
##include <...> search starts here:
# /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include
# /usr/local/include
# /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include-fixed
# /usr/include
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
#SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
#SEARCH_DIR("/usr/local/lib64")
#SEARCH_DIR("/lib64")
#SEARCH_DIR("/usr/lib64")
#SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
#SEARCH_DIR("/usr/local/lib")
#SEARCH_DIR("/lib")
#SEARCH_DIR("/usr/lib");
grep "/lib.*/libc.so.6 " dummy.log
#attempt to open /lib/libc.so.6 succeeded
grep found dummy.log
#found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2
rm -v dummy.c a.out dummy.log
# takes round about 10 minutes or more, without tests
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib
cd /sources
rm -rf gcc-10.2.0
# 8.27 Pkg-config-0.29.2
# 8.27.1. Installation of Pkg-config
cd /sources
tar xf pkg-config-0.29.2.tar.gz
cd pkg-config-0.29.2
./configure --prefix=/usr \
--with-internal-glib \
--disable-host-tool \
--docdir=/usr/share/doc/pkg-config-0.29.2
make
#make check
make install
cd /sources
rm -rf pkg-config-0.29.2
# 8.28 Ncurses-6.2
# 8.28.1. Installation of Ncurses
cd /sources
tar xf ncurses-6.2.tar.gz
cd ncurses-6.2
./configure --prefix=/usr \
--mandir=/usr/share/man \
--with-shared \
--without-debug \
--without-normal \
--enable-pc-files \
--enable-widec
make
make install
mv -v /usr/lib/libncursesw.so.6* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libncursesw.so) /usr/lib/libncursesw.so
for lib in ncurses form panel menu ; do
rm -vf /usr/lib/lib${lib}.so
echo "INPUT(-l${lib}w)" > /usr/lib/lib${lib}.so
ln -sfv ${lib}w.pc /usr/lib/pkgconfig/${lib}.pc
done
rm -vf /usr/lib/libcursesw.so
echo "INPUT(-lncursesw)" > /usr/lib/libcursesw.so
ln -sfv libncurses.so /usr/lib/libcurses.so
rm -fv /usr/lib/libncurses++w.a
mkdir -v /usr/share/doc/ncurses-6.2
cp -v -R doc/* /usr/share/doc/ncurses-6.2
make distclean
./configure --prefix=/usr \
--with-shared \
--without-normal \
--without-debug \
--without-cxx-binding \
--with-abi-version=5
make sources libs
cp -av lib/lib*.so.5* /usr/lib
cd /sources
rm -rf ncurses-6.2
# 8.29 Sed-4.8
# 8.29.1. Installation of Sed
cd /sources
tar xf sed-4.8.tar.xz
cd sed-4.8
./configure --prefix=/usr --bindir=/bin
make
make html
chown -Rv tester .
#su tester -c "PATH=$PATH make check"
make install
install -d -m755 /usr/share/doc/sed-4.8
install -m644 doc/sed.html /usr/share/doc/sed-4.8
cd /sources
rm -rf sed-4.8
# 8.30 Psmisc-23.4
# 8.30.1. Installation of Psmisc
cd /sources
tar xf psmisc-23.4.tar.xz
cd psmisc-23.4
./configure --prefix=/usr
make
make install
mv -v /usr/bin/fuser /bin
mv -v /usr/bin/killall /bin
cd /sources
rm -rf psmisc-23.4
# 8.31 Gettext-0.21
# 8.31.1. Installation of Gettext
cd /sources
tar xf gettext-0.21.tar.xz
cd gettext-0.21
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-0.21
make
#make check
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so
cd /sources
rm -rf gettext-0.21
# 8.32 Bison-3.7.5
# 8.32.1. Installation of Bison
cd /sources
tar xf bison-3.7.5.tar.xz
cd bison-3.7.5
./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.7.5
make
#make check
make install
cd /sources
rm -rf bison-3.7.5
# 8.33 Grep-3.6
# 8.33.1. Installation of Grep
cd /sources
tar xf grep-3.6.tar.xz
cd grep-3.6
./configure --prefix=/usr --bindir=/bin
make
#make check
make install
cd /sources
rm -rf grep-3.6
# 8.34 Bash-5.1
# 8.34.1. Installation of Bash
cd /sources
tar xf bash-5.1.tar.gz
cd bash-5.1
sed -i '/^bashline.o:.*shmbchar.h/a bashline.o: ${DEFDIR}/builtext.h' Makefile.in
./configure --prefix=/usr \
--docdir=/usr/share/doc/bash-5.1 \
--without-bash-malloc \
--with-installed-readline
make
chown -Rv tester .
#su tester << EOF
#PATH=$PATH make tests < $(tty)
#EOF
make install
mv -vf /usr/bin/bash /bin
exec /bin/bash --login +h
# takes round about 30 minutes or more, without tests
cd /sources
rm -rf bash-5.1
# 8.35 Libtool-2.4.6
# 8.35.1. Installation of Libtool
cd /sources
tar xf libtool-2.4.6.tar.xz
cd libtool-2.4.6
./configure --prefix=/usr
make
#make check
make install
rm -fv /usr/lib/libltdl.a
cd /sources
rm -rf libtool-2.4.6
# 8.36 GDBM-1.19
# 8.36.1. Installation of GDBM
cd /sources
tar xf gdbm-1.19.tar.gz
cd gdbm-1.19
./configure --prefix=/usr \
--disable-static \
--enable-libgdbm-compat
make
#make check
make install
cd /sources
rm -rf gdbm-1.19
# 8.37 Gperf-3.1
# 8.37.1. Installation of Gperf
cd /sources/
tar xf gperf-3.1.tar.gz
cd gperf-3.1
./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.1
make
#make -j1 check
make install
cd /sources/
rm -rf gperf-3.1
# 8.38 Expat-2.2.10
# 8.38.1. Installation of Expat
cd /sources
tar xf expat-2.2.10.tar.xz
cd expat-2.2.10
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/expat-2.2.10
make
#make check
make install
install -v -m644 doc/*.{html,png,css} /usr/share/doc/expat-2.2.10
cd /sources
rm -rf expat-2.2.10
# 8.39 Inetutils-2.0
# 8.39.1. Installation of Inetutils
cd /sources
tar xf inetutils-2.0.tar.xz
cd inetutils-2.0
./configure --prefix=/usr \
--localstatedir=/var \
--disable-logger \
--disable-whois \
--disable-rcp \
--disable-rexec \
--disable-rlogin \
--disable-rsh \
--disable-servers
make
#make check
make install
mv -v /usr/bin/{hostname,ping,ping6,traceroute} /bin
mv -v /usr/bin/ifconfig /sbin
cd /sources
rm -rf inetutils-2.0
# 8.40 Perl-5.32.1
# 8.40.1. Installation of Perl
cd /sources
tar xf perl-5.32.1.tar.xz
cd perl-5.32.1
export BUILD_ZLIB=False
export BUILD_BZIP2=0
sh Configure -des \
-Dprefix=/usr \
-Dvendorprefix=/usr \
-Dprivlib=/usr/lib/perl5/5.32/core_perl \
-Darchlib=/usr/lib/perl5/5.32/core_perl \
-Dsitelib=/usr/lib/perl5/5.32/site_perl \
-Dsitearch=/usr/lib/perl5/5.32/site_perl \
-Dvendorlib=/usr/lib/perl5/5.32/vendor_perl \
-Dvendorarch=/usr/lib/perl5/5.32/vendor_perl \
-Dman1dir=/usr/share/man/man1 \
-Dman3dir=/usr/share/man/man3 \
-Dpager="/usr/bin/less -isR" \
-Duseshrplib \
-Dusethreads
make
#make test
make install
unset BUILD_ZLIB BUILD_BZIP2
cd /sources
rm -rf perl-5.32.1
# 8.41 XML::Parser-2.46
# 8.41.1. Installation of XML::Parser
cd /sources
tar xf XML-Parser-2.46.tar.gz
cd XML-Parser-2.46
perl Makefile.PL
make
#make test
make install
cd /sources
rm -rf XML-Parser-2.46
# 8.42 Intltool-0.51.0
# 8.42.1. Installation of Intltool
cd /sources
tar xf intltool-0.51.0.tar.gz
cd intltool-0.51.0
sed -i 's:\\\${:\\\$\\{:' intltool-update.in
./configure --prefix=/usr
make
#make check
make install
install -v -Dm644 doc/I18N-HOWTO /usr/share/doc/intltool-0.51.0/I18N-HOWTO
cd /sources
rm -rf intltool-0.51.0
# 8.43 Autoconf-2.71
# 8.43.1. Installation of Autoconf
cd /sources
tar xf autoconf-2.71.tar.xz
cd autoconf-2.71
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf autoconf-2.71
# 8.44 Automake-1.16.3
# 8.44.1. Installation of Automake
cd /sources
tar xf automake-1.16.3.tar.xz
cd automake-1.16.3
sed -i "s/''/etags/" t/tags-lisp-space.sh
./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.16.3
make
#make -j4 check
make install
cd /sources
rm -rf automake-1.16.3
# 8.45 Kmod-28
# 8.45.1. Installation of Kmod
cd /sources/
tar xf kmod-28.tar.xz
cd kmod-28
./configure --prefix=/usr \
--bindir=/bin \
--sysconfdir=/etc \
--with-rootlibdir=/lib \
--with-xz \
--with-zstd \
--with-zlib
make
make install
for target in depmod insmod lsmod modinfo modprobe rmmod; do
ln -sfv ../bin/kmod /sbin/$target
done
ln -sfv kmod /bin/lsmod
cd /sources/
rm -rf kmod-28
# 8.46 Libelf from Elfutils-0.183
# 8.46.1. Installation of Libelf
cd /sources
tar xf elfutils-0.183.tar.bz2
cd elfutils-0.183
./configure --prefix=/usr \
--disable-debuginfod \
--enable-libdebuginfod=dummy \
--libdir=/lib
make
#make check
make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
rm /lib/libelf.a
cd /sources
rm -rf elfutils-0.183
# 8.47 Libffi-3.3
# 8.47.1. Installation of Libffi
cd /sources
tar xf libffi-3.3.tar.gz
cd libffi-3.3
./configure --prefix=/usr --disable-static --with-gcc-arch=native
make
#make check
make install
cd /sources
rm -rf libffi-3.3
# 8.48 OpenSSL-1.1.1j
# 8.48.1. Installation of OpenSSL
cd /sources
tar xf openssl-1.1.1j.tar.gz
cd openssl-1.1.1j
./config --prefix=/usr \
--openssldir=/etc/ssl \
--libdir=lib \
shared \
zlib-dynamic
make
#make test
sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile
make MANSUFFIX=ssl install
mv -v /usr/share/doc/openssl /usr/share/doc/openssl-1.1.1j
cp -vfr doc/* /usr/share/doc/openssl-1.1.1j
cd /sources
rm -rf openssl-1.1.1j
# 8.49 Python-3.9.2
# 8.49.1. Installation of Python 3
cd /sources
tar xf Python-3.9.2.tar.xz
cd Python-3.9.2
./configure --prefix=/usr \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--with-ensurepip=yes
make
#make test
make install
install -v -dm755 /usr/share/doc/python-3.9.2/html
tar --strip-components=1 \
--no-same-owner \
--no-same-permissions \
-C /usr/share/doc/python-3.9.2/html \
-xvf ../python-3.9.2-docs-html.tar.bz2
cd /sources
rm -rf Python-3.9.2
# 8.50 Ninja-1.10.2
# 8.50.1. Installation of Ninja
cd /sources
tar xf ninja-1.10.2.tar.gz
cd ninja-1.10.2
sed -i '/int Guess/a \
int j = 0;\
char* jobs = getenv( "NINJAJOBS" );\
if ( jobs != NULL ) j = atoi( jobs );\
if ( j > 0 ) return j;\
' src/ninja.cc
python3 configure.py --bootstrap
#./ninja ninja_test
#./ninja_test --gtest_filter=-SubprocessTest.SetWithLots
install -vm755 ninja /usr/bin/
install -vDm644 misc/bash-completion /usr/share/bash-completion/completions/ninja
install -vDm644 misc/zsh-completion /usr/share/zsh/site-functions/_ninja
cd /sources
rm -rf ninja-1.10.2
# 8.51 Meson-0.57.1
# 8.51.1. Installation of Meson
cd /sources
tar xf meson-0.57.1.tar.gz
cd meson-0.57.1
python3 setup.py build
python3 setup.py install --root=dest
cp -rv dest/* /
cd /sources
rm -rf meson-0.57.1
# 8.52 Coreutils-8.32
# 8.52.1. Installation of Coreutils
cd /sources
tar xf coreutils-8.32.tar.xz
cd coreutils-8.32
patch -Np1 -i ../coreutils-8.32-i18n-1.patch
sed -i '/test.lock/s/^/#/' gnulib-tests/gnulib.mk
autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix=/usr \
--enable-no-install-program=kill,uptime
make
make NON_ROOT_USERNAME=tester check-root
echo "dummy:x:102:tester" >> /etc/group
chown -Rv tester .
#su tester -c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"
sed -i '/dummy/d' /etc/group
make install
mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /bin
mv -v /usr/bin/{false,ln,ls,mkdir,mknod,mv,pwd,rm} /bin
mv -v /usr/bin/{rmdir,stty,sync,true,uname} /bin
mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/' /usr/share/man/man8/chroot.8
mv -v /usr/bin/{head,nice,sleep,touch} /bin
cd /sources
rm -rf coreutils-8.32
# 8.53 Check-0.15.2
# 8.53.1. Installation of Check
cd /sources
tar xf check-0.15.2.tar.gz
cd check-0.15.2
./configure --prefix=/usr --disable-static
make
#make check
make docdir=/usr/share/doc/check-0.15.2 install
cd /sources
rm -rf check-0.15.2
# 8.54 Diffutils-3.7
# 8.54.1. Installation of Diffutils
cd /sources
tar xf diffutils-3.7.tar.xz
cd diffutils-3.7
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf diffutils-3.7
# 8.55 Gawk-5.1.0
# 8.55.1. Installation of Gawk
cd /sources
tar xf gawk-5.1.0.tar.xz
cd gawk-5.1.0
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr
make
#make check
make install
mkdir -v /usr/share/doc/gawk-5.1.0
cp -v doc/{awkforai.txt,*.{eps,pdf,jpg}} /usr/share/doc/gawk-5.1.0
cd /sources
rm -rf gawk-5.1.0
# 8.56 Findutils-4.8.0
# 8.56.1. Installation of Findutils
cd /sources
tar xf findutils-4.8.0.tar.xz
cd findutils-4.8.0
./configure --prefix=/usr --localstatedir=/var/lib/locate
make
chown -Rv tester .
#su tester -c "PATH=$PATH make check"
make install
mv -v /usr/bin/find /bin
sed -i 's|find:=${BINDIR}|find:=/bin|' /usr/bin/updatedb
cd /sources
rm -rf findutils-4.8.0
# 8.57 Groff-1.22.4
# 8.57.1. Installation of Groff
cd /sources
tar xf groff-1.22.4.tar.gz
cd groff-1.22.4
PAGE=A4
./configure --prefix=/usr
make -j1
make install
cd /sources
rm -rf groff-1.22.4
# 8.58 GRUB-2.04
# 8.58.1. Installation of GRUB
cd /sources
tar xf grub-2.04.tar.xz
cd grub-2.04
sed "s/gold-version/& -R .note.gnu.property/" \
-i Makefile.in grub-core/Makefile.in
./configure --prefix=/usr \
--sbindir=/sbin \
--sysconfdir=/etc \
--disable-efiemu \
--disable-werror
make
make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions
cd /sources
rm -rf grub-2.04
# 8.59 Less-563
# 8.59.1. Installation of Less
cd /sources/
tar xf less-563.tar.gz
cd less-563
./configure --prefix=/usr --sysconfdir=/etc
make
make install
cd /sources/
rm -rf less-563
# 8.60 Gzip-1.10
# 8.60.1. Installation of Gzip
cd /sources
tar xf gzip-1.10.tar.xz
cd gzip-1.10
./configure --prefix=/usr
make
#make check
make install
mv -v /usr/bin/gzip /bin
cd /sources
rm -rf gzip-1.10
# 8.61 IPRoute2-5.10.0
# 8.61.1. Installation of IPRoute2
cd /sources
tar xf iproute2-5.10.0.tar.xz
cd iproute2-5.10.0
sed -i /ARPD/d Makefile
rm -fv man/man8/arpd.8
sed -i 's/.m_ipt.o//' tc/Makefile
make
make DOCDIR=/usr/share/doc/iproute2-5.10.0 install
cd /sources
rm -rf iproute2-5.10.0
# 8.62 Kbd-2.4.0
# 8.62.1. Installation of Kbd
cd /sources
tar xf kbd-2.4.0.tar.xz
cd kbd-2.4.0
patch -Np1 -i ../kbd-2.4.0-backspace-1.patch
sed -i '/RESIZECONS_PROGS=/s/yes/no/' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in
./configure --prefix=/usr --disable-vlock
make
#make check
make install
mkdir -v /usr/share/doc/kbd-2.4.0
cp -R -v docs/doc/* /usr/share/doc/kbd-2.4.0
cd /sources
rm -rf kbd-2.4.0
# 8.63 Libpipeline-1.5.3
# 8.63.1. Installation of Libpipeline
cd /sources
tar xf libpipeline-1.5.3.tar.gz
cd libpipeline-1.5.3
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf libpipeline-1.5.3
# 8.64 Make-4.3
# 8.64.1. Installation of Make
cd /sources
tar xf make-4.3.tar.gz
cd make-4.3
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf make-4.3
# 8.65 Patch-2.7.6
# 8.65.1. Installation of Patch
cd /sources
tar xf patch-2.7.6.tar.xz
cd patch-2.7.6
./configure --prefix=/usr
make
#make check
make install
cd /sources
rm -rf patch-2.7.6
# 8.66 Man-DB-2.9.4
# 8.66.1. Installation of Man-DB
cd /sources
tar xf man-db-2.9.4.tar.xz
cd man-db-2.9.4
sed -i '/find/s@/usr@@' init/systemd/man-db.service.in
./configure --prefix=/usr \
--docdir=/usr/share/doc/man-db-2.9.4 \
--sysconfdir=/etc \
--disable-setuid \
--enable-cache-owner=bin \
--with-browser=/usr/bin/lynx \
--with-vgrind=/usr/bin/vgrind \
--with-grap=/usr/bin/grap
make
#make check
make install
cd /sources
rm -rf man-db-2.9.4
# 8.66.2. Non-English Manual Pages in LFS
# 8.67 Tar-1.34
# 8.67.1. Installation of Tar
cd /sources
tar xf tar-1.34.tar.xz
cd tar-1.34
FORCE_UNSAFE_CONFIGURE=1 \
./configure --prefix=/usr \
--bindir=/bin
make
#make check
make install
make -C doc install-html docdir=/usr/share/doc/tar-1.34
cd /sources
rm -rf tar-1.34
# 8.68 Texinfo-6.7
# 8.68.1. Installation of Texinfo
cd /sources
tar xf texinfo-6.7.tar.xz
cd texinfo-6.7
./configure --prefix=/usr
make
#make check
make install
make TEXMF=/usr/share/texmf install-tex
pushd /usr/share/info
rm -v dir
for f in *
do install-info $f dir 2>/dev/null
done
popd
cd /sources
rm -rf texinfo-6.7
# 8.69 Vim-8.2.2433
# 8.69.1. Installation of Vim
cd /sources
tar xf vim-8.2.2433.tar.gz
cd vim-8.2.2433
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
./configure --prefix=/usr
make
chown -Rv tester .
#su tester -c "LANG=en_US.UTF-8 make -j1 test" &> vim-test.log
make install
ln -sv vim /usr/bin/vi
for L in /usr/share/man/{,*/}man1/vim.1; do
ln -sv vim.1 $(dirname $L)/vi.1
done
ln -sv ../vim/vim82/doc /usr/share/doc/vim-8.2.2433
cat > /etc/vimrc << "EOF"
" Begin /etc/vimrc
" Ensure defaults are set before customizing settings, not after
source $VIMRUNTIME/defaults.vim
let skip_defaults_vim=1
set nocompatible
set backspace=2
set mouse=
syntax on
if (&term == "xterm") || (&term == "putty")
set background=dark
endif
" End /etc/vimrc
EOF
# vim -c ':options'
cd /sources
rm -rf vim-8.2.2433
# 8.70 Systemd-247
# 8.70.1. Installation of systemd
cd /sources
tar xf systemd-247.tar.gz
cd systemd-247
patch -Np1 -i ../systemd-247-upstream_fixes-1.patch
ln -sf /bin/true /usr/bin/xsltproc
tar -xf ../systemd-man-pages-247.tar.xz
sed '181,$ d' -i src/resolve/meson.build
sed -i 's/GROUP="render"/GROUP="video"/' rules.d/50-udev-default.rules.in
mkdir -p build
cd build
LANG=en_US.UTF-8 \
meson --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
-Dblkid=true \
-Dbuildtype=release \
-Ddefault-dnssec=no \
-Dfirstboot=false \
-Dinstall-tests=false \
-Dkmod-path=/bin/kmod \
-Dldconfig=false \
-Dmount-path=/bin/mount \
-Drootprefix= \
-Drootlibdir=/lib \
-Dsplit-usr=true \
-Dsulogin-path=/sbin/sulogin \
-Dsysusers=false \
-Dumount-path=/bin/umount \
-Db_lto=false \
-Drpmmacrosdir=no \
-Dhomed=false \
-Duserdb=false \
-Dman=true \
-Dmode=release \
-Ddocdir=/usr/share/doc/systemd-247 \
..
LANG=en_US.UTF-8 ninja
LANG=en_US.UTF-8 ninja install
rm -f /usr/bin/xsltproc
rm -rf /usr/lib/pam.d
systemd-machine-id-setup
systemctl preset-all
systemctl disable systemd-time-wait-sync.service
cd /sources
rm -rf systemd-247
# 8.71 D-Bus-1.12.20
# 8.71.1. Installation of D-Bus
cd /sources
tar xf dbus-1.12.20.tar.gz
cd dbus-1.12.20
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--disable-static \
--disable-doxygen-docs \
--disable-xml-docs \
--docdir=/usr/share/doc/dbus-1.12.20 \
--with-console-auth-dir=/run/console \
--with-system-pid-file=/run/dbus/pid \
--with-system-socket=/run/dbus/system_bus_socket
make
make install
mv -v /usr/lib/libdbus-1.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libdbus-1.so) /usr/lib/libdbus-1.so
ln -sfv /etc/machine-id /var/lib/dbus
cd /sources
rm -rf dbus-1.12.20
# 8.72 Procps-ng-3.3.17
# 8.72.1. Installation of Procps-ng
cd /sources
tar xf procps-ng-3.3.17.tar.xz
cd procps-ng-3.3.17
./configure --prefix=/usr \
--exec-prefix= \
--libdir=/usr/lib \
--docdir=/usr/share/doc/procps-ng-3.3.17 \
--disable-static \
--disable-kill \
--with-systemd
make
#make check
make install
mv -v /usr/lib/libprocps.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libprocps.so) /usr/lib/libprocps.so
cd /sources
rm -rf procps-ng-3.3.17
# 8.73 Util-linux-2.36.2
# 8.73.1. Installation of Util-linux
cd /sources
tar xf util-linux-2.36.2.tar.xz
cd util-linux-2.36.2
./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
--docdir=/usr/share/doc/util-linux-2.36.2 \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--without-python \
runstatedir=/run
make
bash tests/run.sh --srcdir=$PWD --builddir=$PWD
chown -Rv tester .
#su tester -c "make -k check"
make install
cd /sources
rm -rf util-linux-2.36.2
# 8.74 E2fsprogs-1.46.1
# 8.74.1. Installation of E2fsprogs
cd /sources
tar xf e2fsprogs-1.46.1.tar.gz
cd e2fsprogs-1.46.1
mkdir -v build
cd build
../configure --prefix=/usr \
--bindir=/bin \
--with-root-prefix="" \
--enable-elf-shlibs \
--disable-libblkid \
--disable-libuuid \
--disable-uuidd \
--disable-fsck
make
#make check
make install
rm -fv /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a
gunzip -v /usr/share/info/libext2fs.info.gz
install-info --dir-file=/usr/share/info/dir /usr/share/info/libext2fs.info
makeinfo -o doc/com_err.info ../lib/et/com_err.texinfo
install -v -m644 doc/com_err.info /usr/share/info
install-info --dir-file=/usr/share/info/dir /usr/share/info/com_err.info
cd /sources
rm -rf e2fsprogs-1.46.1
# 8.75 About Debugging Symbols
# 8.76 Stripping Again
save_lib="ld-2.33.so libc-2.33.so libpthread-2.33.so libthread_db-1.0.so"
cd /lib
for LIB in $save_lib; do
objcopy --only-keep-debug $LIB $LIB.dbg
strip --strip-unneeded $LIB
objcopy --add-gnu-debuglink=$LIB.dbg $LIB
done
save_usrlib="libquadmath.so.0.0.0 libstdc++.so.6.0.28
libitm.so.1.0.0 libatomic.so.1.2.0"
cd /usr/lib
for LIB in $save_usrlib; do
objcopy --only-keep-debug $LIB $LIB.dbg
strip --strip-unneeded $LIB
objcopy --add-gnu-debuglink=$LIB.dbg $LIB
done
unset LIB save_lib save_usrlib
find /usr/lib -type f -name \*.a \
-exec strip --strip-debug {} ';'
find /lib /usr/lib -type f -name \*.so* ! -name \*dbg \
-exec strip --strip-unneeded {} ';'
find /{bin,sbin} /usr/{bin,sbin,libexec} -type f \
-exec strip --strip-all {} ';'
# 8.77 Cleaning Up
rm -rf /tmp/*
logout
chroot "$LFS" /usr/bin/env -i \
HOME=/root TERM="$TERM" \
PS1='(lfs chroot) \u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/bin/bash --login
find /usr/lib /usr/libexec -name \*.la -delete
find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf
rm -rf /tools
userdel -r tester
Ab hier gibt es kein simples Copy & Paste mehr. Die Netzwerkkonfiguration sowie Angaben zu den Disks müssen auf die eigene Umgebung angepasst werden.
# Chapter 9 System Configuration
# 9.1 Introduction
# 9.2 General Network Configuration
# 9.2.1. Network Interface Configuration Files
ln -s /dev/null /etc/systemd/network/99-default.link
cat > /etc/systemd/network/10-eth-dhcp.network << "EOF"
[Match]
Name=eth0
[Network]
DHCP=ipv4
[DHCP]
UseDomains=true
EOF
cat > /etc/resolv.conf << "EOF"
# Begin /etc/resolv.conf
domain linuxfabrik.loc
nameserver 192.168.122.1
# End /etc/resolv.conf
EOF
echo "lfs.linuxfabrik.loc" > /etc/hostname
cat > /etc/hosts << "EOF"
# Begin /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 lfs.linuxfabrik.loc
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# End /etc/hosts
EOF
# 9.5. Configuring the system clock
cat > /etc/adjtime << "EOF"
0.0 0 0.0
0
LOCAL
EOF
timedatectl set-timezone Europe/Zurich
# 9.6. Configuring the Linux Console
cat > /etc/vconsole.conf << "EOF"
KEYMAP="de_CH-latin1"
FONT="eurlatgr"
EOF
# 9.7. Configuring the System Locale
localectl set-locale LANG="en_US.UTF-8"
# 9.8. Creating the /etc/inputrc File
cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>
# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off
# Enable 8bit input
set meta-flag On
set input-meta On
# Turns off 8th bit stripping
set convert-meta Off
# Keep the 8th bit for display
set output-meta On
# none, visible or audible
set bell-style none
# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word
# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line
# End /etc/inputrc
EOF
# 9.9. Creating the /etc/shells File
cat > /etc/shells << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF
# Chapter 10 Making the LFS System Bootable
# 10.1 Introduction
# 10.2 Creating the /etc/fstab File
blkid
cat > /etc/fstab << "EOF"
# Begin /etc/fstab
UUID=85c0c6dc-9eec-4f1e-b56e-0437d3a0aeac / ext4 defaults 0 0
UUID=cfcf2c48-405c-4411-beec-1e530af48a90 swap swap pri=1 0 0
UUID=c9c9a304-9a88-4278-8b68-61c7f182fa2b /home ext4 defaults 0 0
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs defaults 0 0
devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
# End /etc/fstab
EOF
# 10.3. Linux-5.10.17
# 10.3.1. Installation of the kernel
cd /sources
tar xf linux-5.10.17.tar.xz
cd linux-5.10.17
make mrproper
make defconfig
#make menuconfig
Diese Features sollten ein- bzw. abgeschaltet sein:
General setup -->
[ ] Auditing Support [CONFIG_AUDIT]
[*] Control Group support [CONFIG_CGROUPS]
[ ] Enable deprecated sysfs features to support old userspace tools [CONFIG_SYSFS_DEPRECATED]
[*] Configure standard kernel features (expert users) [CONFIG_EXPERT] --->
[*] open by fhandle syscalls [CONFIG_FHANDLE]
Processor type and features --->
[*] Enable seccomp to safely compute untrusted bytecode [CONFIG_SECCOMP]
Firmware Drivers --->
[*] Export DMI identification via sysfs to userspace [CONFIG_DMIID]
Networking support --->
Networking options --->
<*> The IPv6 protocol [CONFIG_IPV6]
Device Drivers --->
Generic Driver Options --->
[ ] Support for uevent helper [CONFIG_UEVENT_HELPER]
[*] Maintain a devtmpfs filesystem to mount at /dev [CONFIG_DEVTMPFS]
Firmware Loader --->
[ ] Enable the firmware sysfs fallback mechanism [CONFIG_FW_LOADER_USER_HELPER]
File systems --->
[*] Inotify support for userspace [CONFIG_INOTIFY_USER]
Pseudo filesystems --->
[*] Tmpfs POSIX Access Control Lists [CONFIG_TMPFS_POSIX_ACL]
# takes round about 20 minutes or more
make
make modules_install
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-5.10.17-lfs-10.1-systemd
cp -iv System.map /boot/System.map-5.10.17
cp -iv .config /boot/config-5.10.17
install -d /usr/share/doc/linux-5.10.17
cp -r Documentation/* /usr/share/doc/linux-5.10.17
# 10.3.2. Configuring Linux Module Load Order
install -v -m755 -d /etc/modprobe.d
cat > /etc/modprobe.d/usb.conf << "EOF"
# Begin /etc/modprobe.d/usb.conf
install ohci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i ohci_hcd ; true
install uhci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i uhci_hcd ; true
# End /etc/modprobe.d/usb.conf
EOF
# 10.4 Using GRUB to Set Up the Boot Process
# 10.4.1. Introduction
# 10.4.2. GRUB Naming Conventions
# 10.4.3. Setting Up the Configuration
grub-install /dev/sda
grub-mkconfig --output=/boot/grub/grub.cfg
# Chapter 11 The End
# 11.1 The End
echo 10.1-systemd > /etc/lfs-release
cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="10.1-systemd"
DISTRIB_CODENAME="built with love by Linuxfabrik"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF
cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="10.1-systemd"
ID=lfs
PRETTY_NAME="Linux From Scratch 10.1-systemd"
VERSION_CODENAME="built with love by Linuxfabrik"
EOF
passwd root
# 11.2 Get Counted
# 11.3 Rebooting the System
logout
umount -Rv $LFS
shutdown now
Built on 2024-11-18