Vorige: Das Bootstrapping mit kleinerem Seed, Nach oben: Bootstrapping [Inhalt][Index]
Die Abbildung oben zeigt den Anfang des Abhängigkeitsgraphen der
Distribution und entspricht den Paketdefinitionen im (gnu package
bootstrap)
-Modul. Eine ähnliche Grafik kann mit guix graph
(siehe
guix graph
aufrufen) erzeugt werden:
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-gcc)' \ | dot -Tps > gcc.ps
oder für das Bootstrapping mit noch kleinerem Seed:
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-mes)' \ | dot -Tps > mes.ps
Bei diesem Detaillierungsgrad sind die Dinge recht komplex. Guile selbst
besteht aus einer ausführbaren ELF-Datei neben vielen Quelldateien und
kompilierten Scheme-Dateien, die dynamisch bei der Ausführung geladen
werden. Das wird in dem im Graph gezeigten guile-2.0.7.tar.xz-Archiv
gespeichert. Das Archiv ist Teil von Guix’ „Quelldistribution“ und wird in
den Store mit add-to-store
(siehe Der Store) eingefügt.
Doch wie schreibt man eine Ableitung, die dieses Tarball-Archiv entpackt und
in den Store einfügt? Um dieses Problem zu lösen, benutzt die
guile-bootstrap-2.0.drv
-Ableitung – die erste, die erstellt
wird – bash
als Ersteller, welche wiederum
build-bootstrap-guile.sh
ausführt, was über einen Aufruf von
tar
den Tarball entpackt. Deswegen sind bash, tar,
xz und mkdir als statisch gebundene Binärdateien auch Teil der
Guix-Quelldistribution, die nur dazu da sind, dass der Guile-Tarball
entpackt werden kann.
Sobald guile-bootstrap-2.0.drv
erstellt worden ist, haben wir ein
funktionierendes Guile zur Hand, mit dem nachfolgende Erstellungsprogramme
ausgeführt werden können. Sein erster Auftrag ist, Tarballs mit den anderen
vorerstellten Binärdateien herunterzuladen – das ist die Tätigkeit der
.tar.xz.drv-Ableitungen. Wir verwenden zu diesem Zweck Guix-Module
wie ftp-client.scm
. Die module-import.drv
-Ableitungen
importieren solche Module und schreiben sie in derselben Verzeichnisstruktur
in ein Verzeichnis im Store. Die
module-import-compiled.drv
-Ableitungen kompilieren die Module und
schreiben sie in der richtigen Struktur in ein Ausgabeverzeichnis. Dies
entspricht dem #:modules
-Argument von
build-expression->derivation
(siehe Ableitungen).
Schließlich werden die verschiedenen Tarballs durch die Ableitungen
gcc-bootstrap-0.drv
, glibc-bootstrap-0.drv
, oder
bootstrap-mes-0.drv
und bootstrap-mescc-tools-0.drv
,
entpackt. Zu diesem Zeitpunkt haben wir eine fertige Toolchain für C.
Das Bootstrapping ist abgeschlossen, sobald eine vollständige Toolchain
vorliegt, die von den oben erläuterten vorerstellten
Bootstrapping-Werkzeugen nicht abhängt. Diese Voraussetzung, keine
Abhängigkeiten zu haben, überprüft man, indem man schaut, ob die Dateien der
endgültigen Toolchain frei von Referenzen auf die
/gnu/store-Verzeichnisse der Bootstrapping-Eingaben sind. Der
Vorgang, diese „finale“ Toolchain zu bekommen, wird von den
Paketdefinitionen beschrieben, die Sie im Modul (gnu packages
commencement)
finden.
Mit dem Befehl guix graph
können wir gegenüber dem obigen Graphen
„herauszoomen“, indem wir alles auf der Ebene von Paketobjekten statt auf
der von einzelnen Ableitungen betrachten – denken Sie daran, dass ein
Paket zu mehreren Ableitungen führen kann; normalerweise einer, die seine
Quelldateien herunterlädt, einer, die die benötigten Guile-Module erstellt,
und einer, die das Paket dann tatsächlich aus seinem Quellcode heraus
erstellt. Der Befehl
guix graph -t bag \ -e '(@@ (gnu packages commencement) glibc-final-with-bootstrap-bash)' | xdot -
zeigt den Abhängigkeitsgraphen, der zur „finalen“ C-Bibliothek39 führt. Hier sehen Sie ihn:
Das erste Werkzeug, das mit den Bootstrapping-Binärdateien erstellt wird,
ist GNU Make – beachten Sie das oben sichtbare
make-boot0
–, das eine Voraussetzung aller folgenden Pakete
ist. Von da aus werden Findutils und Diffutils erstellt.
Es folgt die erste Stufe der Binutils und GCC, die pseudo-crosskompiliert werden – d.h. die --target-Befehlszeilenoption entspricht der --host-Option. Mit ihnen wird libc erstellt. Dank den Crosskompilierungstricks ist garantiert, dass diese libc keine Referenzen auf die anfängliche Toolchain enthält.
Damit werden die finalen Binutils und GCC erstellt (sie sind oben nicht zu
sehen). GCC benutzt den ld
aus den finalen Binutils und bindet
Programme an die gerade erstellte libc. Mit dieser Toolchain erstellen wir
die anderen Pakete, die Guix und das GNU-Erstellungssystem benutzen: Guile,
Bash, Coreutils, etc.
Und voilà! Wenn das geschafft ist, haben wir die vollständige Menge von
Erstellungswerkzeugen, die das GNU-Erstellungssystem erwartet. Sie sind in
der Variablen %final-inputs
des Moduls (gnu packages
commencement)
zu finden und werden von jedem Paket implizit benutzt, das
das gnu-build-system
verwendet (siehe gnu-build-system
).
Weil die finale Toolchain nicht von den Bootstrapping-Binärdateien abhängt,
müssen diese nur selten aktualisiert werden. Es ist dennoch sinnvoll, sie
automatisiert erzeugen zu können, wenn sie doch aktualisiert werden. Das
Modul (gnu packages make-bootstrap)
ermöglicht dies.
Mit dem folgenden Befehl werden die Tarball-Archive erstellt, die die Bootstrapping-Binärdateien enthalten (beim traditionellen Bootstrapping sind das Binutils, GCC und glibc; beim Bootstrapping mit kleinerem Seed sind es linux-libre-headers, bootstrap-mescc-tools, bootstrap-mes; dazu kommen Guile sowie ein Tarball mit einer Mischung aus Coreutils und anderen grundlegenden Befehlszeilenwerkzeugen):
guix build bootstrap-tarballs
Die erzeugten Tarballs sind es, auf die im Modul (gnu packages
bootstrap)
verwiesen werden sollte, das am Anfang dieses Abschnitts erwähnt
wurde.
Können Sie noch folgen? Dann haben Sie vielleicht schon angefangen, sich zu fragen, wann wir denn einen Fixpunkt erreichen. Das ist eine interessante Frage! Leider wissen wir es nicht, aber wenn Sie es herausfinden wollen (und Ihnen die nennenswerten Rechen- und Speicherkapazitäten dafür zur Verfügung stehen), dann lassen Sie es uns wissen.
Zu unserem traditionellen Bootstrapping gehören GCC, GNU Libc, Guile, etc. Das ist ganz schön viel binärer Code! Warum ist das ein Problem? Es ist deswegen ein Problem, weil es praktisch unmöglich ist, solch große Klumpen binären Codes einem Audit zu unterziehen. Dadurch wird es schwer, nachzuvollziehen, welcher Quellcode ihn erzeugt hat. Jede ausführbare Binärdatei, für die kein Audit möglich ist, macht uns verwundbar gegenüber Hintertüren in Compilern, wie Ken Thompson sie in seiner Arbeit von 1984, Reflections on Trusting Trust, beschrieben hat.
Wir senken das Risiko, indem wir unsere Bootstrapping-Binärdateien immer mit einer früheren Guix-Version erzeugen. Trotzdem fehlt uns das Niveau an Transparenz, das wir am übrigen Paketabhängigkeitsgraphen wertschätzen, wo Guix immer vom Quellcode eindeutig auf die Binärdateien abbildet. Unser Ziel ist also, die Menge an Bootstrapping-Binärdateien so weit wie möglich zu verkleinern.
Auf dem Webauftritt von Bootstrappable.org werden laufende Projekte mit diesem Zweck aufgeführt. Bei einem davon geht es darum, den Bootstrapping-GCC durch eine Folge von Assemblern, Interpretierern und Compilern zunehmender Komplexität zu ersetzen, die von Anfang an aus Quellcode heraus erstellt werden kann, angefangen bei einem einfachen, überprüfbaren Assembler.
Unsere erste große Leistung stellt die Ersetzung von GCC, der GNU-C-Bibliothek und der Binutils durch die MesCC-Tools (einem einfachen Binder für hexadezimal dargestellte Maschinenprogramme und einem Makro-Assembler) und Mes dar (siehe Referenzhandbuch zu GNU Mes in GNU Mes, einem Scheme-Interpretierer und in Scheme geschriebenen C-Compiler). Weder MesCC-Tools noch Mes können bereits von Grund auf gebootstrapt werden, daher schleusen wir sie als binäre Seeds ein. Wir nennen das unser Bootstrapping mit kleinerem Seed, weil es die Größe unserer Bootstrapping-Binärdateien halbiert hat! Außerdem haben wir damit keinerlei Binärdatei für einen C-Compiler; auf i686-linux und x86_64-linux werden Guix-Pakete ganz ohne binären C-Compiler gebootstrapt.
Wir arbeiten daran, MesCC-Tools und Mes vollständig bootstrappen zu können, und behalten auch andere Bootstrapping-Binärdateien im Blick. Ihre Unterstützung ist willkommen!
Ihnen könnte die glibc-intermediate
-Markierung
auffallen, die darauf hindeutet, dass sie noch nicht ganz final ist,
aber annäherungsweise betrachten wir sie als final.
Vorige: Das Bootstrapping mit kleinerem Seed, Nach oben: Bootstrapping [Inhalt][Index]