- Passend zu Zigs Ablauf, bei dem
build.zigund das Build-System in separate Prozesse aufgeteilt wurden, wurde die Paketverwaltungslogik aus der ausführbaren Compiler-Datei in den maker-Prozess verschoben - Mit der Verlagerung von
zig build,zig fetch,zig initundzig libcauf die maker-Seite werden HTTP, TLS, Git, Kompression und der Code zur Verarbeitung vonbuild.zig.zonals Quellcode ausgeliefert - In dieser Struktur lassen sich Paketverwaltungsfunktionen ohne Neu-Build des Compilers korrigieren, und da der maker mit
ReleaseSafekompiliert wird, sind auch Sicherheitsprüfungen für Netzwerkoperationen aktiviert - Ursprüngliches Ziel war es, durch Offenlegung des build server protocol ein Problem mit
--build-runner-Änderungen zu lösen, das ZLS blockierte; im neuen Prozessbaum bleibt der maker Elternprozess des configurer und kann erneutes Ausführen der Konfiguration stabiler handhaben - Für Nutzer ändert sich wenig, aber die Zig-Executable schrumpft um 4 % von 14,1 MiB auf 13,5 MiB, und
--maker-optsowie--zig-lib-dirwerden durch die UmgebungsvariablenZIG_DEBUG_MAKERbzw.ZIG_LIB_DIRersetzt
Verlagerung der Paketverwaltungslogik
- Nachdem Zigs Nutzer-Skript
build.zigund das Build-System selbst in separate Prozesse aufgeteilt wurden, wurde die Struktur so geändert, dass auch die Paketverwaltungslogik auf der Seite des Build-Systems liegt - Die in den maker-Prozess verschobenen Unterbefehle sind:
zig buildzig fetchzig initzig libc
Code, der aus der Compiler-Executable entfernt wurde
- Große Codebereiche, die zuvor in der Compiler-Executable enthalten waren, werden nun als Quellcode ausgeliefert
- Logik zum Abrufen von Paketen
- HTTP-Client und Networking
- TLS und zugehörige Kryptografie
- Git-Protokoll
xz,gzip,zstd,flate,zip- Parsing, Validierung und sonstige Verarbeitung von
build.zig.zon-Dateien
- Diese Funktionen können ohne Neu-Build des Compilers gepatcht werden, wodurch Nutzer und Beitragende leichter experimentieren können
- Die maker-Executable wird im Modus
ReleaseSafekompiliert, daher sind bei Netzwerkoperationen der Paketverwaltung Sicherheitsprüfungen aktiviert - Der für Networking und Datei-Hashing verwendete kryptografische Code kann auf dem Host verfügbare spezielle CPU-Instruktionen nutzen
Prozessstruktur und build server
- Die ursprüngliche Motivation war, das build server protocol offenzulegen und damit ein Problem zu beseitigen, das ZLS blockierte
- In der früheren Struktur war
zig buildzugleich für Compiler und Paketmanager zuständig, darunter enthielt der builder die Logik des Nutzer-build.zigund die Implementierung des Build-Systems - Nach der Trennung von maker/configurer sah die Struktur wie folgt aus:
zig build: Compiler + Paketmanagerconfigurer: Nutzer-build.zig-Logikmaker: Build-System
- In dieser Struktur musste ein lange laufendes
zig build --watchden configurer erneut ausführen, wenn Änderungen anbuild.zigoder zugehörigen Dateien erkannt wurden; dafür musste der maker beendet werden, damitzig builddie Paketverwaltungslogik erneut ausführen konnte - In der neuen Struktur übernimmt
zig buildnur den Compiler, während darunter der maker Build-System und Paketmanager verwaltet; der configurer wird ein Kindprozess des maker - Auch wenn die Konfiguration erneut ausgeführt werden muss, kann der maker als Elternprozess weiterlaufen
- Beim geplanten build server wird dadurch eine Struktur möglich, bei der der Client über Konfigurationsänderungen informiert wird, statt dass er sich nach dem Beenden des Servers erneut verbindet
Sichtbare Änderungen
- Die meisten Änderungen sind nicht inkompatibel, es gibt aber für Nutzer sichtbare Unterschiede
- Binärgröße der Zig-Executable: auf Basis von
ReleaseSmallohne LLVM von 14,1 MiB auf 13,5 MiB reduziert, also 4 % kleiner - Das Flag
--maker-optwird durch die UmgebungsvariableZIG_DEBUG_MAKERersetzt - Das Flag
--zig-lib-dirwird durch die UmgebungsvariableZIG_LIB_DIRersetzt
- Binärgröße der Zig-Executable: auf Basis von
Verbleibende blockierende Issues vor Zig 0.17.0
- Die nach diesem Änderungspaket verbleibenden wichtigen blockierenden Issues sind die Kernarbeiten bis zum Tag für Zig 0.17.0
- Da im Juli zwei Konferenzen und Vorbereitungen für Vorträge anstehen, wird realistisch erwartet, diese Arbeiten Anfang August abzuschließen
- Techatrix aus dem ZLS-Team hat sich wegen der Arbeit am build server protocol gemeldet und daran mitgewirkt; Sponsoring wird gesucht
1 Kommentare
Hacker-News-Kommentare
Zig-, Go- und Python-Entwickler verkünden gelegentlich, sie hätten Kühlmittel aus dem Kraftstofftank entfernt, und ihre Anhänger jubeln, das sei gut für die Sprache und werde die Performance deutlich verbessern.
Dabei frage ich mich eher, warum das Kühlmittel überhaupt im Kraftstofftank war.
Paketverwaltung in den Compiler zu packen war bequem, aber sobald Sprache und Werkzeuge breiter genutzt werden, wird eine Funktion, die für Einzelne vorteilhaft war, zu technischer Schuld, die Adoption verhindert.
In vielen Projekten wählen Entwickler den bequemen Weg, um „die schwierige Arbeit, die für eine saubere Lösung nötig wäre“ zu vermeiden; und weil andere diese schwierige Arbeit ebenfalls nicht machen wollen, wird daraus eine Konvention.
Wenn man einen Paketmanager im Build-System implementiert und ihn gleichzeitig im Compiler belassen will, muss man zuerst festlegen, welche Abstraktion zwischen Compiler und Build-System liegen soll.
Das wirkt sich auch auf das Import-System und grundlegende Teile der Sprache aus; solche Dinge müssen sauber entworfen werden und lassen sich später nur schwer ändern.
Anfangs Paketverwaltung und Compiler eng zu koppeln und ausgehend von der gewünschten Programmiererfahrung rückwärts zu entwerfen, um später die Implementierung zu ändern, kann für Nutzer weniger Auswirkungen haben.
Besonders Pythons Import-System halte ich für sehr komplex und fehlerbehaftet, weil es viele Arten der Paketverwaltung aufnehmen musste.
Go dagegen wurde von Anfang an mit Paketverwaltung im Hinterkopf entworfen, weshalb die importbezogene Syntax vergleichsweise klein und sauber ist. Natürlich stimme ich nicht jeder Designentscheidung zu.
Selbst bei kleinen Produkten ist schwer vorherzusagen, wie die einzelnen Komponenten interagieren werden, und man muss ständig nachbessern.
Jetzt stell dir vor, du baust eine selbsthostende C-Ersatzsprache.
Je größer die Beschleunigung, desto mehr Jubel, aber die meisten Optimierungen sind keine cleveren Tricks, sondern bestehen darin, mit dem Profiler festzustellen: „Oh, Kühlmittel gehört nicht in den Kraftstofftank.“
Die meisten Performance-Engpässe sind keine inhärenten Grenzen der Hardware oder des Problems selbst.
Es gibt ein Mindestmaß an Arbeit, das nötig ist, um ein Ergebnis zu bekommen, aber der Grund, warum Anwendungen langsam sind, liegt fast immer in dem Gerümpel, das man obendrauf gepackt hat.
Die Entwicklung von Zig wirkt wirklich wie eine gesunde Atmosphäre.
Ich nutze LLMs täglich und räume ein, dass sie bei vielen Problemtypen erstaunlich gut sind, aber ich will keine Programmiersprache, die von einem LLM geschaffen wurde.
Jede Codezeile, jede Entscheidung und jeder Kompromiss in einer Programmiersprache ist wichtig.
Eine Sprache, die nur nach Gefühl designt und codiert wurde, wäre eine Katastrophe.
Kein Modell hat mir je Code gezeigt, der mich vom Gegenteil überzeugt hätte. Selbst Fable, das klar besser ist als die bisherigen besten Modelle, ändert daran nichts.
Modelle haben keine eigenen Wünsche, keine sinnvollen Ansichten und wissen nicht, was sich in einer Sprache angenehm oder unangenehm anfühlt. Dasselbe gilt für ausreichend komplexe GUI- oder CLI-Interfaces.
Eine Sprache wie Zig kann aus einem LLM nicht hervorgehen, solange es Zig nicht einfach kopiert; und selbst dann wäre es eine schlechtere Kopie.
Mit „per LLM kopieren“ meine ich hier nicht, den Source-Tree buchstäblich mit
cpzu kopieren, sondern dass ein LLM eine Spezifikation schreibt und ein anderes LLM die Sprache nach dieser Spezifikation implementiert.Ich habe einen Bootloader gebaut und mit UEFI gearbeitet, und persönlich fand ich es deutlich einfacher als mit C.
Allerdings ist sicher auch ein Bias dabei, weil es Spaß macht, etwas Neues und Glänzendes zu lernen.
Ich frage mich, ob diese Änderung diejenige ist, die dazu geführt hat, dass
@cImportaus Zig entfernt und ins Build-System verlagert wurde.Es ist rein eine Frage der User Experience, und ich verstehe, dass die Trennung von Build-System und Compiler für die Maintainer wichtig ist, aber trotzdem ist es ein wenig schade, dass Entwicklungsstabilität vor User Experience kommt.
Es ist die richtige Entscheidung, aber traurig;
@cImportwar meiner Meinung nach ein starkes Killer-Feature der Sprache.Diese Änderung betrifft den Code zum Herunterladen und Entpacken von Third-Party-Paketen.
Die Änderung an
@cImportwar Teil der Arbeit daran, Zigs LLVM/libclang-Abhängigkeit irgendwann optional zu machen und später in ein Third-Party-Paket auslagern zu können, scheint aber nicht direkt damit zusammenzuhängen.Ich habe irgendwo gelesen, dass das langfristige Ziel darin besteht, das Build-System in eine WebAssembly-VM zu verlagern.
Wenn das stimmt, wäre das eine große Sache.
Eine gute Änderung für Zig.
Ich bin ziemlich versucht, von Go zu Zig zu wechseln, aber vorerst genieße ich es auch, von der Seitenlinie zuzusehen.
Jedes Mal, wenn eine Sprache ihr eigenes Paketsystem baut, habe ich nur das Gefühl, dass wir eine große Chance verpasst haben.
Die einzige Ausnahme ist C/C++, wo sich, im Guten wie im Schlechten, nichts ausreichend etabliert hat.
Solche Entscheidungen können später sehr komplexe Abläufe erzeugen, wenn man mehrere Sprachen mischen muss.
Packaging-Systeme machen Dinge einfacher, aber sobald man eine andere Sprache verwenden muss, machen sie den weiteren Prozess komplizierter.
Willst du ein einziges Build-System für alle Sprachen? Systeme wie Bazel gibt es, und sie werden oft für mehrsprachige Projekte genutzt, aber in der Praxis scheint sich gezeigt zu haben, dass ein Build-System mit sprachspezifischem Wissen deutlich leichter zu handhaben ist.
Es zwingt einen nämlich, sorgfältig nachzudenken, bevor man eine Abhängigkeit hinzufügt.
Solche Abhängigkeiten haben oft versteckte Kosten, etwa Sicherheitslücken.
Da ein erheblicher Teil wichtiger Systeme in C++ geschrieben ist, wäre es viel zu riskant, sich auf Dutzende leicht zugängliche Third-Party-Pakete zu verlassen, ohne jedes davon ordentlich zu auditieren.
Zig füllt diese Lücke.
Praktisch gibt es dafür nur Buck und Bazel, aber beide bringen zu viel Ballast der großen Organisationen mit, aus denen sie stammen.
Das ist schade.
Die Trennung der Zuständigkeiten wurde sehr nachvollziehbar umgesetzt.