Wie Dune zum besseren Build-System für OCaml wurde
(blog.janestreet.com)- Aus Unzufriedenheit mit OMake entwickelte Jane Street Jenga, doch die externe Akzeptanz blieb gering; das als Kompatibilitätslösung gebaute Jbuilder wuchs unerwartet zu einem grundlegenden Werkzeug der OCaml-Community heran
- Der anfängliche Reiz von Jbuilder lag weniger in den Funktionen als in Geschwindigkeit und Portabilität; in Jane-Street-Projekten führte eine etwa 5-mal schnellere Kompilierung gegenüber OCamlbuild zur Akzeptanz
- In Zusammenarbeit mit OCaml Labs entwickelte sich Jbuilder zu einem vollständigen Build-System weiter und wurde nach Community-Diskussionen wegen eines Namenskonflikts mit der alten Borland-Java-IDE zu Dune
- Jane Street pflegte Jenga und Dune eine Zeit lang parallel, doch als die Codebasis auf 65 Mio. Zeilen OCaml und 5 Mio. Zeilen Python anwuchs, stieg die Schwierigkeit einer internen Migration stark an
- Nach mehr als einem Jahr konzentrierter Arbeit wird die Codebasis von Jane Street nun mit Dune gebaut; bei Builds mit weitgehend gefülltem Cache sind sie 2- bis 3-mal schneller
Jenga entstand aus Unzufriedenheit mit OMake
- Ein Build-System ist ein alltägliches Werkzeug für Entwickler: Es erstellt aus mehreren Quelldateien ein ausführbares Programm und übernimmt auch Compiler-Aufrufe sowie Testausführungen
- Um 2012 war Jane Street mit OMake, einem der damaligen Standard-Build-Systeme für OCaml, unzufrieden und entwickelte deshalb das eigene Build-System Jenga
- Intern funktionierte Jenga gut, daher entschied Jane Street, es zu veröffentlichen, in der Erwartung, dass auch die Community es nützlich finden würde
- Man hoffte, dass externe Nutzer Jenga verwenden und Beiträge leisten würden
- Auch die Open-Source-Veröffentlichung von Jane-Street-Code sollte dadurch einfacher werden
- Tatsächlich blieb die externe Akzeptanz hinter den Erwartungen zurück
- Es lief nicht unter Windows
- Wer Jenga einführen wollte, musste praktisch den gesamten Jane-Street-Ansatz zum Bauen von OCaml übernehmen
- Als die externe Nutzung nicht zunahm, machte Jane Street Jenga wieder proprietär; das Problem des Buildens von Open-Source-Code blieb jedoch bestehen
Jbuilder als Kompatibilitätsschicht
- 2016 entschied Jane Street, mit Jbuilder ein einfaches plattformübergreifendes Tool zu bauen, mit dem externe Nutzer den eigenen Code bauen konnten, ohne das gesamte Jenga-Modell übernehmen zu müssen
- Das Tool sollte auch den Aufwand verringern, Builds an OCamlbuild anzupassen, das damals zum neuen Standard für das Bauen von OCaml-Projekten wurde
- Jbuilder verstand die von Jenga für Build-Konfigurationen verwendeten Dateien
jbuildund führte die nötigen Kompilierungsbefehle in topologisch sortierter Reihenfolge aus - Das frühe Jbuilder war von einem Build-System im üblichen Sinn noch recht weit entfernt
- Es führte nicht selektiv nur die Befehle erneut aus, deren Eingaben sich geändert hatten
- Stattdessen führte es jedes Mal alle Befehle erneut aus
Wie aus Jbuilder Dune wurde
- Jbuilder war ursprünglich als kleine Kompatibilitätsschicht gedacht, doch Nutzer begannen es über Jane-Street-Pakete hinaus auch zum Bauen ihrer eigenen Projekte zu verwenden
- Der wichtigste Grund für die Akzeptanz war Geschwindigkeit
- Beim Kompilieren von Jane-Street-Projekten war es etwa 5-mal schneller als OCamlbuild
- Es war portabel
- Seine Struktur war einfach und dadurch leicht zu ändern
- Gemeinsam mit OCaml Labs, heute Tarides, begann Jane Street, Jbuilder zu einem vollständigeren Build-System auszubauen
- Auch der Name wurde zu einem eigenen Problem
- Es gab bereits JBuilder, die Java-IDE von Borland
- Dieses System war zwar schon lange praktisch verschwunden, doch selbst nach einer Anfrage an die Rechteinhaber erhielt man keine Erlaubnis zur Nutzung des Namens
- Nach Diskussionen in der Community wurde Dune als neuer Name gewählt
- Die Diskussion dazu lief im Thread new name for jbuilder
Die Kosten für zwei parallel gepflegte Build-Systeme
- Mit der wachsenden Popularität von Dune musste Jane Street zwei selbst entwickelte vollständige Build-Systeme gleichzeitig pflegen und unterstützen: Jenga und Dune
- Dune etablierte sich als System mit neu entworfener Struktur, schneller Performance bei den meisten Nutzer-Builds, breiterer Akzeptanz sowie besserer API und User Experience
- Natürlich stellte sich die Frage, wann die interne Umgebung auf Dune umgestellt werden sollte, doch das Build-System-Team war bereits damit ausgelastet, mit der wachsenden Codebasis Schritt zu halten
- Als Dune 2016 begann, umfasste der OCaml-Code 4 Mio. Zeilen
- Heute sind es 65 Mio. Zeilen OCaml und 5 Mio. Zeilen Python
- Die Migration zu Dune war so aufwendig, dass sie lange nicht ernsthaft begonnen wurde; wiederholt blieb es bei der optimistischen Schätzung, das könne „in den nächsten 6 bis 12 Monaten“ möglich sein
- Im vergangenen Jahr vergrößerte Jane Street das Build-System-Team auf 5 Vollzeit-Ingenieure und begann dann die lange aufgeschobene Migration
Dune ersetzt Jenga intern bei Jane Street
- Eine der größten Aufgaben bestand darin, Dune so zu skalieren, dass es zur riesigen Codebasis von Jane Street passt
- Einer der Gründe, warum Dune extern schnell war, lag darin, dass die meisten Nutzer Projekte bauten, die deutlich kleiner waren als das 70-Mio.-Zeilen-Repository von Jane Street
- Auch Jenga war in den vergangenen 10 Jahren nicht stehen geblieben
- Jane Street hatte die Jenga-Implementierung kontinuierlich verbessert, um mit dem Wachstum der Codebasis Schritt zu halten
- Jenga war für die Anforderungen eines großen Monorepos erheblich optimiert
- Ein erheblicher Teil dieser Optimierungen musste nach Dune übertragen werden
- Auch die alltägliche Integration war nicht trivial
- Das Build-System wird in vielen Workflows aufgerufen
- Die drei Editoren Vim, Emacs und VSCode hatten jeweils eigene benutzerdefinierte Integrationen für Jenga
- Jede dieser Integrationen musste einzeln auf Dune migriert werden
- Nach mehr als einem Jahr konzentrierter Arbeit wird die Codebasis von Jane Street nun mit Dune gebaut
- Zum Zeitpunkt der Umstellung war die Dune-Performance insgesamt gleich gut oder besser als die von Jenga
- In manchen Fällen war sie deutlich besser
- Wenn bei den meisten Build-Aufgaben bereits ein Cache vorhanden ist, sind Builds 2- bis 3-mal schneller
Nächste Verbesserungen auf einer einzigen Basis
- Jane Street plant, einen erheblichen Teil der Arbeit an Dune-Performanceverbesserungen als Open Source zu veröffentlichen; ein Teil ist bereits öffentlich
- Um nicht erneut zwei Systeme zu schaffen — einen Dune-Fork für Jane Street und ein externes Dune — achtet man darauf, Änderungen nach Möglichkeit upstream einzubringen
- Dune eignet sich nun besser als Grundlage für neue Funktionen
- Die Codebasis ist einfacher und leichter zu bearbeiten
- Man kann sich auf ein einziges System konzentrieren
- Auch die folgenden Funktionen sind dadurch näher gerückt
-
Verteilte Builds
- Shallow Builds, also „builds without the bytes“
- Cache-Laden des Build-Graphen selbst
- Das Build-System-Team ist auf 12 Vollzeit-Ingenieure in New York, London und Singapur angewachsen, wodurch sich auch das Tempo der Dune-Weiterentwicklung erhöht
-
1 Kommentare
Hacker-News-Kommentare
Dunes Crash-Meldung:
https://github.com/ocaml/dune/issues/2767
Im Technik-Podcast von Jane Street, Signals and Threads, gab es 2020 eine Folge über Build-Systeme, sehr empfehlenswert.
Die anderen Folgen sind auch gut; besonders empfehlenswert sind The Future of Programming mit Richard Eisenberg und What is an Operating System? mit Anil Madhavapeddy.
¥https://signalsandthreads.com/build-systems/
°https://signalsandthreads.com/future-of-programming/
§https://signalsandthreads.com/what-is-an-operating-system/
https://signalsandthreads.com/multicast-and-the-markets/
Es ist respektabel, dass Jane Street gezeigt hat, dass funktionale Programmierung mit HM-Typsystem mit genügend Aufwand produktionsreif sein und sehr schnell laufen kann.
Man hört noch immer gelegentlich, dass funktionale Sprachen im eher akademischen Stil in der Produktion nicht einsetzbar seien, aber OCaml zeigt, dass das auch bei hohen Performance-Anforderungen gut möglich ist.
https://mercury.com/
Es ist eine hervorragende Wahl, um hochwertige Programme zu bauen und dabei breit mit bestehenden Systemen zu interagieren.
Laut einem Blogpost von vor einigen Jahren haben sie sich auch mit Roc beschäftigt, aber ich weiß nicht, ob sie es derzeit einsetzen.
[0] https://blog.noredink.com
Jedes Mal, wenn ich einen Blogpost von Janestreet lese, muss ich innerlich lachen, weil es so wirkt, als wäre Finanzarbeit bei Jane interessanter und besser bezahlt als 90 % der Jobs in der sogenannten Tech-Industrie.
In der Finanzwelt gibt es viel mehr Tech-Jobs, die weder so interessant noch so gut bezahlt sind wie bei Jane Street – nicht einmal auf dem Niveau eines durchschnittlichen Tech-Unternehmens.
Viel Arbeit im Finanzsektor besteht darin, 20 Jahre alten Java-Code zu reparieren oder neue Wege zu finden, Daten in Excel-Dateien hinein- und herauszubekommen, um maßgeschneiderte Berichte zu erstellen.
Und ich habe gehört, dass es deutlich schwerer ist, bei JS reinzukommen als bei Google/Meta.
Ich habe mich dort früher auch mal beworben, und der Interviewer war ziemlich unangenehm; bei Big-Tech-Interviews ist mir das nie passiert, daher war mein Eindruck nicht besonders gut.
Trotzdem würde ich das höher bewerten als Arbeit, die Leute dazu bringt, auf Werbung zu klicken.
Wie in anderen Unternehmen auch gibt es dort eine Mischung aus interessanten Projekten und öder Arbeit.
Das Einzige, was schlimmer ist als eine komplexe Codebasis, ist ein komplexes Build-System. CMake ist abscheulich.
Es ist wie: „Um diese Sprache zu kompilieren, lerne noch eine weitere neue Sprache!“
Ein paar Dinge macht es richtig, und manches von dem, was es falsch macht, ist handhabbar.
Wenn man mit einem Satz menschenlesbarer Konfigurationsdateien Build-Abläufe für mehrere Plattformen bekommt, kann man ein gewisses Maß an Schmerz ertragen.
Die schreckliche Skriptsprache bremst es aus, aber mit genügend Motivation ließe es sich verbessern.
Früher habe ich nach Lisp meine erste funktionale Erfahrung einige Jahre lang mit Haskell gemacht.
OCaml hat mich nicht wirklich angesprochen, und ich leide an einer seltenen Form von Semikolon-Allergie, daher fand ich Haskell deutlich angenehmer anzusehen.
Neulich habe ich aber Reason ausprobiert, und das war richtig gut — plötzlich fand ich alles rund um OCaml interessant.
https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
https://ocaml.org/docs/toplevel-introduction#loading-librari...
https://reasonml.github.io/ sieht cool aus, wie OCaml mit JavaScript-Gefühl.
Wenn man diesen Dreh einmal raus hat, ist es wahrscheinlich okay, aber wie bei Lisp muss man wohl erst lernen, in dieser Struktur zu denken. Trotzdem macht mir ein bildschirmfüllender Block Haskell-Code Angst.
Unter diesen Sprachen war SML/NJ für mich am leichtesten zu lesen.
Ich frage mich, ob jemand die Open-Source-OCaml-Bibliotheken und -Tools von Jane Street einmal in einem einigermaßen ernsthaften Projekt verwendet hat.
Mein kurzer Eindruck war, dass viel Arbeit in den Aufbau des Ökosystems und die Freigabe des Codes als Open Source geflossen ist, aber dass es für Menschen außerhalb von Jane Street nicht ganz „einsatzbereit“ wirkt.
Um Dinge zu finden, muss man Funktionssignaturen ziemlich sicher lesen können, aber abgesehen davon habe ich keine Beschwerden. Zum Beispiel spart es enorm viel Zeit, wenn für alle Basistypen Funktionen existieren, die in S-Expressions umwandeln und wieder zurück, sofern man weiß, dass es sie gibt, und entsprechend plant.
Ich habe auch andere Bibliotheken genutzt, und ihr Logging sowie die ppxs für Unit-Tests sind in der OCaml-Welt praktisch nah am Standard, sofern so etwas dort überhaupt möglich ist. Ich habe auch den Code-Formatter, ein Test-Framework und einige Implementierungen fortgeschrittener Datenstrukturen verwendet.
Man stößt gelegentlich, wie andere Kommentare sagen, auch auf Dinge, die wirklich nicht funktionieren — etwa weil sie von etwas Separat-Ausgeliefertem und Undokumentiertem abhängen oder eine geheime Konfiguration brauchen. Ich unterstelle da keine böse Absicht; oft funktioniert es, wenn man ein Issue eröffnet und ein oder zwei Jahre später noch einmal vorbeischaut.
Es ist nicht komplett frustfrei, aber ich schätze den Ansatz, alles offenzulegen, statt Ressourcen darauf zu verwenden, weniger Releases zu testen und zu polieren. Die Codequalität ist im Allgemeinen sehr hoch, und selbst wenn man es nicht direkt zum Laufen bekommt, bleibt es eine strenge und gut validierte Beispielimplementierung.
Meiner Meinung nach ist die API viel besser als die der Standard-stdlib.
Ich mag Lean 4, aber es ist nicht leicht, sich dabei von einer KI helfen zu lassen. Meine heutige Aufgabe besteht darin, das Referenzhandbuch so aufzubereiten, dass es bequem in ein 200K-Kontextfenster passt. Mal sehen, ob das hilft.
Ich finde es ziemlich erstaunlich, dass es immer noch sinnvoll sein kann, ein eigenes neues Build-System zu entwickeln und darauf zu migrieren, statt ein vorhandenes Tool wie buck2 oder bazel einzuführen.
Das heißt nicht, dass sich solche fortgeschrittenen Build-Tools leicht einführen lassen, aber wie sieht der Vergleich mit dem Eigenbau aus? Ich frage mich, ob dune etwas Besonderes anders macht.
Bazel hatte sein erstes Release 2015, Buck 2013.
JS hat zwar eine gewisse NIH-Kultur, aber ich weiß nicht, ob das hier eine Rolle gespielt hat. Damals gab es schlicht nicht viele gute Build-Tools, besonders nicht für Unternehmen mit einem eher unkonventionellen Tech-Stack.
Soweit ich weiß, muss man insbesondere
ocamldepvorab ausführen können oder zweimal kompilieren; buck2 kann das, und bei Bazel braucht man meiner Erinnerung nach Hacks.Die beiden sind grob vergleichbar. Bei der reinen Geschwindigkeit des Aufrufs von OCaml-Build-Tools ist dune schneller; wenn viel neu gebaut werden muss und ein verteiltes Build-System genutzt wird, gewinnt buck2.
Der große Schmerzpunkt ist die LSP-Integration. Da der LSP-Server nur über den Build die Dateiabhängigkeiten kennen kann, muss er eng mit dem Build-System gekoppelt sein. Bei dune ist das alles sauber vorhanden. Mit buck2 haben wir es zwar irgendwie zusammengebunden, aber es ist nicht annähernd so gut.
Dune ist mit Abstand der beste Name für ein Build-System, da kommt nichts auch nur in die Nähe.
Dass man loszieht, um ein besseres Build-System zu machen, und dann „aus Versehen“ tatsächlich ein besseres Build-System macht — schon seltsam, wie solche Zufälle passieren.