Was macht man, wenn das Auto einen neuen Zahnriemen und neue Stoßdämpfer braucht, deshalb in der Werkstatt hockt und man sich extra frei genommen hat, weil man keine Lust hat, 90 Minuten mit den Öffentlichen zu fahren, obwohl man mit dem Auto gerade mal 17 bis 20 Minuten braucht?
Richtig.
Man startet ein kleines Nebenprojekt.
Also kein vernünftiges Nebenprojekt.
Nicht sowas wie:
„Ich räume mal meinen Schreibtisch auf.“
Oder:
„Ich sortiere meine Unterlagen.“
Nein.
Mein Gehirn macht natürlich direkt:
„Weißt du, was jetzt entspannend wäre? Void Linux, Hyprland aus den Quellen bauen und Noctalia noch oben draufwerfen.“
Völlig normal.
Für Menschen mit innerem Paketmanager und sehr zweifelhaften Prioritäten.
Der ursprüngliche Plan war eigentlich harmlos
Ich habe hier noch einen alten Laptop von 2011 herumliegen. So ein Gerät, bei dem man nicht mehr fragt, ob es schnell ist, sondern ob es noch Würde besitzt.
Auf dem lief bisher Debian. Das war okay. Debian ist solide, ruhig, zuverlässig. So ein bisschen wie ein älterer Hausmeister, der seit 30 Jahren denselben Schlüsselbund trägt und genau weiß, welche Tür klemmt.
Aber irgendwie kam mir der Gedanke:
Vielleicht wäre Void auf so einem alten Gerät sogar sinnvoller.
Nicht, weil Void einfacher wäre. Ganz sicher nicht. Void ist nicht der freundliche Empfangstresen mit Kaffee und Infobroschüre.
Void ist eher:
„Hier ist ein Werkzeugkasten. Viel Glück.“
Aber der Gedanke dahinter war gar nicht so dumm: Lieber ein langsam rollendes System, das regelmäßig kleine Updates bekommt, als alle paar Jahre einen größeren Versionssprung auf einem alten Laptop durchprügeln. Gerade bei so einer kleinen alten Kiste kann das durchaus Sinn ergeben.
Also wollte ich das erstmal testen.
Nicht direkt auf dem Laptop.
Ich bin ja nicht komplett wahnsinnig.
Nur so ungefähr 73 Prozent.
Also habe ich Void erstmal auf dem Main-Rechner auf eine externe Platte installiert. Ganz klassisch mit der offiziellen Void-ISO mit XFCE.
Void aktualisieren war überraschend langweilig
Die erste Überraschung war tatsächlich positiv.
Die Void-ISO ist gefühlt fast anderthalb Jahre alt. Ich habe sogar erstmal die lokale Version installiert und danach aktualisiert.
Und was passiert?
Nichts Dramatisches.
Kein Feuer.
Kein Paketmanager, der sich heulend in die Ecke legt.
Kein „du hast 1842 Pakete, aber 17 davon haben jetzt spirituelle Differenzen“.
Einfach:
System installiert.
Update gestartet.
Update läuft durch.
Ich saß davor wie ein misstrauischer NPC und dachte:
„Das war’s? Wirklich?“
Void hat also an dieser Stelle erstmal sehr souverän geliefert. Das muss man fairerweise sagen. Für ein System, das gerne etwas kantig wirkt, war dieser Teil erstaunlich entspannt.
Und genau das war gefährlich.
Denn dadurch war ich motiviert.
Motivation ist bei Linux-Bastelprojekten ungefähr wie Benzin neben einem Lagerfeuer.
Das alte Hyprland-Problem auf Void
Mein eigentliches Problem mit Void war nie Void selbst.
Mein Problem war Hyprland.
Oder genauer gesagt: Hyprland ist nicht offiziell in den Void-Repos.
Das ist nicht automatisch schlimm, aber es verschiebt die Verantwortung sehr deutlich in Richtung „du wolltest das doch so“.
Bei früheren Void-Ausflügen hatte ich mit Fremdrepos gearbeitet. Das kann funktionieren. Aber sobald man bei einem so empfindlichen Stack wie Hyprland anfängt, Pakete aus verschiedenen Quellen zu mischen, merkt man schnell:
Wayland-Komponenten sind keine Legosteine.
Die sind eher wie Zahnräder aus einem alten Uhrwerk. Sie sehen alle irgendwie passend aus, aber wenn eins minimal falsch greift, macht das ganze Ding plötzlich Geräusche wie ein alter Drucker im Todeskampf.
Hyprland hängt nicht einfach nur an „Hyprland“.
Da gibt es einen ganzen kleinen Hypr-Zoo:
Hyprutils.
Hyprlang.
Hyprgraphics.
Hyprcursor.
Hyprwayland-scanner.
Hyprland-protocols.
Aquamarine.
Hyprwire.
xdg-desktop-portal-hyprland.
hyprpolkitagent.
Und wahrscheinlich noch drei Dinge, die irgendwo im Hintergrund sitzen und nur dann auftauchen, wenn man schon leicht müde ist.
Wenn diese Teile nicht zusammenpassen, wird es schnell eklig. Dann will Paket A Version X, Paket B ist aber schon bei Y, Paket C wurde gegen eine andere Bibliothek gebaut und Paket D schaut einfach nur aus dem Fenster.
Kurz gesagt:
Ich hatte keine Lust mehr auf diesen Fremdrepo-Mischmasch.
Also kam die glorreiche Idee:
Bauste dir den Scheiß halt selber.
Wie gesagt: Ich war noch motiviert.
Hyprland aus den Quellen: IKEA mit CMake-Fehlern
Also Repository geklont, Abhängigkeiten geprüft, erste Builds gestartet.
Und dann kam die Realität mit einem Klappstuhl.
Hyprland auf Ubuntu zu bauen war bei mir vorher vergleichsweise entspannt. Da war es eher so:
„Installier diese Pakete, starte den Build, warte ein bisschen, fluch zweimal, fertig.“
Void war anders.
Void sagte:
„Schön, dass du da bist. Hier ist dein erstes fehlendes Puzzleteil.“
Und danach:
„Hier ist dein zweites.“
Und danach:
„Übrigens, dieses Puzzleteil passt nicht ganz, weil dein Compiler andere Laune hat.“
Es ging nicht nur darum, Abhängigkeiten zu installieren. Es ging darum, den kompletten Stack in der richtigen Reihenfolge, mit passenden Versionen und passenden kleinen Korrekturen zusammenzubauen.
Ein bisschen wie IKEA, nur dass die Anleitung aus CMake-Fehlern besteht und der Inbusschlüssel „pkg-config“ heißt.
Die kleinen Schmerzen: GCC, libstdc++ und moderne C++-Freude
Ein Teil der Probleme kam durch Dinge, die in der Theorie modern und schön sind, in der Praxis aber erstmal sagen:
„Haha, dein System macht das anders.“
Ein Beispiel waren moderne C++-Funktionen wie „append_range“ oder „insert_range“. Auf dem Papier nett. In der konkreten Void-/GCC-/libstdc++-Kombination aber nicht einfach so nutzbar.
Also musste gepatcht werden.
Nicht „ich ändere mal eben eine Farbe“-Patch.
Sondern eher:
„Diese moderne Methode ersetzen wir durch eine klassische Schleife, damit der Compiler nicht anfängt, existentialistische Fehlermeldungen zu schreiben.“
Dann gab es String-/“string_view“-Kleinkram. Auch so eine Sorte Fehler, bei der man erstmal denkt:
„Das kann doch nicht der Grund sein.“
Doch.
Kann es.
Und dann war da noch „#embed“.
Das ist so ein moderner C/C++-Mechanismus, bei dem mein System sinngemäß gesagt hat:
„Nette Idee. Mach ich nicht.“
Also musste auch das ersetzt werden. Am Ende wurde daraus eine generierte Byte-Array-Lösung, damit die Standardkonfiguration trotzdem eingebettet werden kann, ohne dass der Build am Feature-Wunschzettel moderner Compilerlandschaften scheitert.
Das klingt jetzt trocken, aber emotional war es ungefähr so:
Ich:
„Bitte bau.“
Compiler:
„Nein.“
Ich:
„Warum?“
Compiler:
„Aus Gründen.“
Ich:
„Welche Gründe?“
Compiler:
„Zeile 800.“
Lua durfte natürlich auch nicht fehlen
Hyprland 0.55 bringt Lua-Konfiguration mit. Und wenn man schon dabei ist, sich freiwillig in den Baukeller zu sperren, baut man natürlich auch Lua passend dazu.
Also kam Lua 5.5 mit ins Spiel.
Das war nicht der schlimmste Teil, aber es musste sauber in den lokalen Prefix integriert werden. Also nicht wild irgendwo ins System schieben, sondern in den Projektbereich:
~/.local/hyprland-void-repro
Das war mir wichtig.
Ich wollte kein „Ich habe mein System mit selbstgebautem Zeug paniert und hoffe, dass es morgen noch bootet“.
Ich wollte einen lokalen, reproduzierbaren Stack. Also alles möglichst sauber unter einem eigenen Prefix.
Das ist weniger spektakulär, aber deutlich weniger dumm.
Und ich bin bemüht, bei Linux wenigstens gelegentlich unter 80 Prozent Dummheit zu bleiben.
Irgendwann lief Hyprland tatsächlich
Nach mehreren Stunden Build-Reihenfolge, Patcherei, Abhängigkeiten, „warum findet er das jetzt nicht?“, „warum heißt das Paket auf Void anders?“ und „ich geh kurz innerlich in den Wald schreien“ stand Hyprland dann tatsächlich.
Nicht als Paket.
Nicht als hübscher Installer.
Aber als lokaler Build.
Und das war schon mal ein kleiner Bosskill.
Dann kam der nächste Punkt:
Eine brauchbare „hyprland.lua“.
Zum Glück habe ich von Hyprland-Konfigurationen gefühlt eine Massentierhaltung. Irgendwo liegt immer noch eine alte Variante herum, die mal auf irgendeinem System funktioniert hat, bevor ich wieder meinte, mein Desktop müsse jetzt ganz anders werden.
Also habe ich eine passende Konfig genommen, angepasst und in „~/.config/hypr/“ geworfen.
Und plötzlich:
Hyprland startete.
Fenster gingen auf.
Keybinds funktionierten.
Das System tat so, als wäre das alles geplant gewesen.
War es nicht.
Aber wenn Linux so tut, als wäre mein Chaos Absicht gewesen, widerspreche ich nicht.
Dann kam Noctalia
Natürlich hätte ich an dieser Stelle aufhören können.
Hyprland lief.
Void lief.
Der Verstand hätte gesagt:
„Gut. Mach morgen weiter.“
Mein Kopf sagte:
„Noctalia fehlt noch.“
Und weil ich offenbar aus meinen eigenen Entscheidungen nicht lerne, dachte ich:
Wenn quälen, dann richtig.
Also Noctalia auch noch selbst bauen.
Im Vergleich zu Hyprland war Noctalia gar nicht mal so schlimm. Aber das ist ungefähr so, als würde man sagen:
„Der zweite Zahnarzttermin war entspannter als der erste.“
Schön ist trotzdem anders.
Noctalia hängt an Noctalia-QS beziehungsweise Quickshell. Und dafür braucht man wieder Qt-Kram. Nicht nur normales Qt, sondern auch private/development-Komponenten, Shader-Tools und sonstige kleine Dinge, die sich erst dann melden, wenn man dachte, man hätte die Abhängigkeiten jetzt endlich zusammen.
Da kamen dann so Sachen wie:
fehlende Qt-Private-Header.
fehlende Shader-Tools.
CLI11.
jemalloc.
PAM.
Und natürlich der Klassiker:
Das gebaute Binary heißt nicht so, wie man es erwartet.
Ich erwartete „qs“.
Das System hatte „quickshell“.
Also brauchte es Wrapper- und Symlink-Logik, damit Noctalia später sauber gestartet werden kann.
Das ist genau diese Sorte Linux-Arbeit, die von außen aussieht wie:
„Warum dauert das so lange?“
Und innen ist es:
„Weil ein Programm anders heißt, drei Umgebungsvariablen beleidigt sind und Qt irgendwo hinten im Bus sitzt.“
Runtime ist nicht Build
Der nächste wichtige Punkt war eine Erkenntnis, die man eigentlich kennt, aber trotzdem jedes Mal neu lernt:
Nur weil etwas gebaut wurde, heißt das nicht, dass es im Desktop-Alltag sauber läuft.
Hyprland und Noctalia zu bauen ist eine Sache.
Sie in einer echten Session mit Portalen, Polkit, Audio, Shell, Autostart und Display-Manager sauber zum Laufen zu bekommen, ist eine andere.
Also kamen Runtime-Wrapper dazu.
Kleine Startskripte, die dafür sorgen, dass die richtigen Komponenten aus dem lokalen Prefix gestartet werden:
Hyprland.
Noctalia.
Quickshell.
Portal-Komponenten.
hyprpolkitagent.
PipeWire und WirePlumber.
Nicht alles davon war sofort perfekt. Natürlich nicht. Wir reden hier nicht von einem magischen Einhorn-Installer, sondern von Void plus selbstgebautem Wayland-Stack. Da geht nichts ohne ein bisschen Prozess-Gemurmel im Hintergrund.
Aber Schritt für Schritt wurde daraus etwas, das nicht mehr nur „gerade eben zufällig läuft“ war, sondern tatsächlich wiederholbar.
Und das war der Punkt, an dem aus Basteln langsam ein Projekt wurde.
LightDM und die Geister von XFCE
Besonders lustig wurde es beim Wechsel von XFCE zu Hyprland.
Void mit XFCE war die Basis. Hyprland sollte über LightDM als eigene Session auswählbar sein.
Klingt einfach.
Ist es natürlich nicht.
Denn manchmal bleiben beim Wechsel von XFCE/Xorg zu Hyprland alte Prozesse hängen. XFCE-Komponenten, Portale, vielleicht ein Polkit-Agent, kleine Sitzungsreste, die irgendwo weiterlaufen und dann in der neuen Wayland-Session so tun, als hätten sie Hausrecht.
Das Ergebnis war nicht schön.
Maus und Tastatur können sich dann anfühlen, als hätten sie spontan gekündigt.
Also musste eine LightDM-Integration her, inklusive Cleanup-Hook.
Der räumt vor dem Start der Hyprland-Session bestimmte alte XFCE-/Portal-/Polkit-Prozesse weg, aber natürlich nicht wild mit der Axt durchs System. Nur für den betroffenen Nutzer, nur definierte Prozesse, keine root-Ziele, keine LightDM-Zerstörung.
Kurz gesagt:
Ein kleiner Exorzismus für Sitzungsreste.
Linux ist manchmal sehr spirituell.
Nur mit mehr PIDs.
Dotfiles: Der Unterschied zwischen „läuft“ und „fühlt sich richtig an“
Irgendwann lief der Stack.
Aber „läuft“ reicht bei Desktop-Projekten nicht.
Ein Desktop kann technisch funktionieren und sich trotzdem anfühlen wie ein Möbelhaus nach Ladenschluss.
Also mussten Dotfiles mit ins Projekt.
Hyprland-Konfiguration.
Noctalia-Einstellungen.
Fastfetch.
Farben.
Autostart.
Keybinds.
Aber hier gab es einen wichtigen Punkt: Meine aktuelle Hyprland-Konfiguration ist auf meine Maschine zugeschnitten. NVIDIA, Monitor, bestimmte Eigenheiten. Das darf man nicht einfach als allgemeines Standardprofil verkaufen.
Also entstanden zwei Profile:
Ein generisches Profil.
Und ein Kiru-NVIDIA-Profil.
Das generische Profil nutzt automatisch die bevorzugte Monitorauflösung und verzichtet auf NVIDIA-spezifische Annahmen. Das ist die Variante, die man auf fremden Systemen zuerst nehmen sollte.
Das Kiru-NVIDIA-Profil ist meine getestete Referenzkonfiguration. Also mein Setup, meine Maschine, mein Wahnsinn.
Dazu kam ein Dotfile-Installer mit Backups. Denn nichts schreit mehr „schlechter Installer“ als:
„Ich habe deine Konfiguration überschrieben. Viel Spaß.“
Also werden vorhandene Dateien vorher gesichert. Nicht perfekt wie ein fertiges Produkt, aber ordentlich genug, dass man nicht direkt den nächsten Nervenzusammenbruch bucht.
Aus Bastelordner wurde Codeberg-Projekt
Der nächste Schritt war dann: Das Ganze ordentlich auf Codeberg bringen.
Und auch da wollte ich nicht einfach alles reinwerfen.
Keine „sources/“.
Keine „build/“.
Keine Logs.
Keine temporären Metadaten.
Keine lokalen Codex-/Arbeitsdateien.
Nur das, was wirklich zum Projekt gehört:
Skripte.
Patches.
Dokumentation.
Runtime-Vorlagen.
Dotfiles.
Version-Locks.
Lizenz.
Installationsanleitung.
Das klingt selbstverständlich, aber jeder, der schon mal „mal eben schnell“ ein Projekt veröffentlicht hat, weiß:
Der Unterschied zwischen Repo und digitaler Müllhalde ist manchmal nur eine gute „.gitignore“.
Am Ende entstand daraus „hynalia-void“.
Ein reproduzierbarer Void-Linux-Baukasten für Hyprland und Noctalia.
Noch kein fertiges XBPS-Paket.
Noch kein Endnutzer-Installer.
Aber ein echtes Projekt.
Mit „README.md“.
Mit „INSTALL.md“.
Mit Abhängigkeitsdoku.
Mit Build-Doku.
Mit Runtime-Doku.
Mit Self-Check.
Mit Runtime-Integration-Check.
Also nicht mehr:
„Auf meiner Maschine geht’s.“
Sondern eher:
„Hier ist der Versuch, es nachvollziehbar zu machen.“
Und das ist für meine Verhältnisse schon erschreckend erwachsen.
Noctalia läuft, aber Void versteckt den Komfort im Keller
Natürlich ist damit nicht alles fertig.
Noctalia läuft, aber einige Module erkennen noch nicht alles sauber.
Bluetooth? BlueZ fehlt beziehungsweise „bluetoothd“ läuft nicht.
WLAN? NetworkManager läuft, LAN ist verbunden, WLAN-Hardware wird erkannt, aber ich nutze gerade ohnehin Kabel.
Audio? Da wird es spannender. PipeWire und WirePlumber sind vorhanden, aber aktuell sieht es nach einem Session-/Mehrfachinstanzproblem aus. Mehrere Prozesse, aber kein sauberer „pipewire-0“-Socket. Das ist so ein Fehlerbild, bei dem man weiß:
Das wird morgen wieder ein kleiner Boss.
Brightness? Auf dem Desktop normal nicht vorhanden. Kein echtes „/sys/class/backlight“, also kann Noctalia da auch nicht zaubern. Auf dem alten Laptop wird das später interessanter.
Portale und Polkit laufen dagegen sauber.
Das ist eigentlich eine gute Nachricht: Der Desktop ist nicht kaputt. Es fehlen nur noch Runtime-Integrationen und ein bisschen Void-Komfort-Unterbau.
Oder anders gesagt:
Das Haus steht.
Ein paar Lichtschalter führen noch in den Keller.
Was am Ende entstanden ist
Nach ungefähr acht Stunden Arbeit stand am Ende also kein fertiges Produkt, aber ein erstaunlich brauchbarer Baukasten:
Hyprland 0.55.4 aus den Quellen gebaut.
Der passende Hyprland-Stack lokal zusammengeführt.
Patches für Void-/Compiler-Eigenheiten.
Lua 5.5 lokal integriert.
Noctalia-QS gebaut.
Noctalia Shell installiert.
Runtime-Wrapper geschrieben.
LightDM-Session vorbereitet.
XFCE-Cleanup gelöst.
Dotfiles profiliert.
Installationsanleitung geschrieben.
Runtime-Diagnose ergänzt.
Codeberg-Repo erstellt und gepflegt.
Und das alles nur, weil mein Auto in der Werkstatt war.
Manche Menschen nutzen freie Tage zur Erholung.
Ich baue mir aus Versehen ein reproduzierbares Void-Hyprland-Noctalia-Projekt.
Jeder hat halt andere Entspannungsstörungen.
Warum das Ganze?
Gute Frage.
Vielleicht, weil ich wissen wollte, ob es geht.
Vielleicht, weil mich Void immer noch reizt.
Vielleicht, weil ich Hyprland und Noctalia mag und wissen wollte, wie weit man kommt, wenn man den Stack nicht aus irgendeinem Fremdrepo zieht.
Vielleicht auch einfach, weil mein Kopf manchmal ein Paketmanager mit zu vielen offenen Transaktionen ist.
Aber es fühlt sich trotzdem gut an.
Nicht, weil alles perfekt ist.
Sondern weil aus einem chaotischen Basteltag etwas entstanden ist, das strukturierter ist als erwartet.
Ein Projekt.
Ein Repo.
Eine Anleitung.
Ein Stand, auf dem man morgen weiterbauen kann.
Und irgendwann landet das Ganze vielleicht wirklich auf dem alten Laptop von 2011.
Der Kleine weiß noch nichts von seinem Glück.
Oder seinem Leid.
Je nachdem, wie man Void fragt.
Fazit
Void hasst mich vermutlich nicht wirklich.
Void ist nur ehrlich.
Void sagt nicht:
„Komm rein, ich mache dir alles schön.“
Void sagt:
„Hier sind die Teile. Wenn du es zusammensteckst, gehört es dir.“
Und genau das ist gleichzeitig nervig und faszinierend.
Hyprland auf Void selbst zu bauen war kein entspannter Spaziergang. Es war eher ein Waldweg mit CMake-Schlaglöchern, Compiler-Brombeeren und einem Noctalia-Schild, das leicht schief am Baum hängt.
Aber am Ende läuft es.
Nicht perfekt.
Nicht fertig.
Aber reproduzierbar genug, um daraus weiterzumachen.
Und das ist für einen freien Tag, der eigentlich nur wegen eines Autos in der Werkstatt entstanden ist, gar nicht mal so schlecht.
Danke fürs Lesen.
Und falls ihr euch fragt, ob ich morgen wirklich direkt weitermache:
Natürlich.
Ich habe ja offensichtlich nichts dazu gelernt.