Clause
← Gesamte Dokumentation

Übersetzt aus dem englischen Original · 06042fa · 2026-10-09 · Auf Englisch lesen

Kompilierung

clau kompiliert Erlang/OTP-29-Module über LLVM zu verifiziertem IR, Bitcode oder nativen Objekten. -o/--output linkt positionale Eingaben (oder ein ausgewähltes Projektziel), ihr Einstiegs-Startobjekt und die Runtime zu einer ausführbaren Datei (Linken); Projekt-Builds linken ausführbare Ziele zu den Ausgaben ihres Manifests (Projekte). Erzeugte Objekte können auch über ein C++-Harness laufen, das mit der Runtime gelinkt ist (siehe Beispiel unten).

Akzeptierte Teilmenge des Quelltexts

Benannte Module mit Exporten und geordneten Funktionsklauseln. Köpfe und Matches im Rumpf akzeptieren Variablen, _, Aliase, wiederholte Namen und Muster über Atome, beliebige Ganzzahlen, endliche Gleitkommazahlen, Tupel, Listen/Zeichenketten, Maps, Bitstrings und gewöhnliche Tupel-Records. Rümpfe sind Folgen von Matches, Konstruktoren, geprüften Operatoren/Guard-BIFs, erlang:display/1 (Ausgabe), halt/0,1 (Exit-Status), den auslösenden error/1,2,3, exit/1, throw/1 und erlang:raise/3 (ABI), den übrigen Brücken-Builtins (erlang:function_exported/3) und Funs von Builtins, case/if, catch Expr, try ... of ... catch Class:Reason:Stack ... after mit Stacktraces, maybe ... else ... end, Listen-, Binary- und Map-Comprehensions (Muster) sowie direkten lokalen oder literalen entfernten Aufrufen innerhalb des Batches, einschließlich Selbst-, wechselseitiger und modulübergreifender Rekursion auf expliziten Prozess-Frames mit echten Endaufrufen (tail calls) (Ausführungsmodell); Rumpfrekursion ist durch den Prozess-Stack begrenzt (standardmäßig unbegrenzt), nicht durch den nativen Stack. Guards unterstützen den vollständigen zugelassenen Katalog. Siehe Muster, Guards und Terme.

Funktionswerte fun F/A, fun M:F/A, anonyme und benannte Funs mit erfassten Variablen, Aufrufe von Funs und dynamische Aufrufe (M:F(...), apply/2,3) laufen (Funs). Mit Diagnosen abgewiesen, selbst in unbenutzten Funktionen: receive, Funs von Builtins, Prozesse und Nachrichtenaustausch. Akzeptierte Attribute: module, export, file, Tupel- und native record, export_record, import_record, Type/Spec-Formen, doc/moduledoc, author, vsn, copyright, deprecated, -compile mit {no_auto_import, ...} oder reinen Warnungsoptionen nowarn_* (zum Beispiel nowarn_deprecated_catch) und -import von erlang-Guard-BIFs. Andere Attribute (on_load, Parse-Transforms, andere compile-Optionen, parametrisierte Module) werden abgewiesen. Quellen, die mit #! beginnen, folgen den Escript-Regeln (implizites Modul und Export von main/1, -mode wird akzeptiert). Type/Spec-Formen werden analysiert, ändern aber nie den generierten Code. Reine Syntaxmodi (--parse-check, --print-ast, --print-source, ...) akzeptieren die vollständige Grammatik.

Das Beispiel mit kompilierten Modulen ausführen

client:main/1 macht das Beispiel zu einem Programm:

./build/debug/bin/clau -O2 -o build/demo examples/compile/answer.erl examples/compile/client.erl
./build/demo     # prints 42, -7 and {record,map,binary,list,integer,other}

Dieselben Module laufen auch über ein C++-Harness. Aus einer Windows-x64- Developer-PowerShell mit dem gebauten Compiler:

$tool = './build/debug/bin/clau.exe'
& $tool -O0 --emit obj --artifact-dir build/example-aot examples/compile/answer.erl examples/compile/client.erl
cmake -S examples/compile -B build/example-native -G Ninja -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Debug "-DGENERATED_DIR:PATH=$((Resolve-Path build/example-aot).Path)"
cmake --build build/example-native
./build/example-native/bin/Debug/compiled_modules.exe

Es gibt 42, -7, record, map, binary, list, integer, other aus, je eines pro Zeile. Das Harness registriert Module explizit, erzeugt einen Kontext und dekodiert Ergebnisse; es ist ein Beispiel-Host, kein produktiver Einstiegspunkt. Unter Unix build/debug/bin/clau, clang++ und -DGENERATED_DIR="$PWD/build/example-aot" verwenden (native Läufe sind dort noch nicht validiert).

Weitere Aktionen auf denselben Quellen:

& $tool -O2 --emit llvm-ir --artifact-dir build/example-ir examples/compile/answer.erl examples/compile/client.erl
& $tool --print-types --verbose examples/compile/answer.erl examples/compile/client.erl
& $tool --print-ir --print-optimized-ir examples/compile/answer.erl examples/compile/client.erl
& $tool -O2 --no-type-specialization --verbose examples/compile/answer.erl examples/compile/client.erl

Ausgabe des Quelltexts

--print-source (eine Frontend-Aktion wie --print-ast) gibt jedes geparste Modul als Erlang-Quelltext aus; --print-types gibt denselben Text mit Typannotationen aus. Der Printer (print_source, expression_source, type_source in printing.hpp; compiler/src/printing/source_*) ist wiederverwendbar:

Optionen

OptionVerhalten
--emit obj|llvm-ir|llvm-bcEin Artefakt pro Modul veröffentlichen
--artifact-dir DIRArtefaktwurzel (erfordert --emit)
-o PATH / --output PATHEine ausführbare Datei linken (Linken); kollidiert mit --emit
--linker PATH, --runtime-library PATHClang-Treiber und Runtime-Archiv für -o
--entry MODULE[:FUNCTION]Einstiegsfunktion/1 der ausführbaren Datei; wird in jedem Kompiliermodus validiert und fügt das Startartefakt clausev1_start hinzu (ausführbare Dateien)
--target-triple TRIPLEZielmaschine; --target ist die Auswahl des Projektziels
-O0 / -O2 / -OsGenerischer Standardcode + LLVM O0 / begrenzte Spezialisierung + LLVM O2 / LLVM Os, keine Spezialisierung, ein Abschnitt pro Symbol und Entfernen nicht referenzierten Codes und nicht referenzierter Daten durch den Linker
--no-type-specializationVarianten unabhängig von der Optionsreihenfolge deaktivieren
--print-ir / --print-optimized-irVerifiziertes IR vor/nach den LLVM-Pässen, mit Erlang-Quelltextzeilen als Kommentaren
--print-typesJedes Modul als Erlang-Quelltext, annotiert mit inferierten Typen (Semantik); stoppt vor LLVM
--verbosePhasenereignisse [pp], [parse] und [comp] auf stderr
--impldebug n[,n...]Debug-Ausgabe von Implementierungsschritten auf stderr (z. B. 23: Inferenz-Zusammenfassungen)

Backend

LLVM-SDK

Stabiles LLVM 23.1.x, mindestens 23.1.1. LLVM ist eine Host-Abhängigkeit: Architektur, C++-Standardbibliothek und Windows-CRT müssen zum Compiler-Werkzeug passen. Projektcode behält Ausnahmen/RTTI; keine Ausnahme darf durch LLVM abgewickelt werden. Die Runtime verwendet LLVM nie.

Referenz-Setup Windows x64 (2026-09-29): Host-clang-cl 23.1.2 in C:/Program Files/LLVM/bin, SDK thirdparty/clang+llvm-23.1.2-x86_64-pc-windows-msvc, Visual-Studio-18-x64-Werkzeuge, Windows SDK 10.0.26100.0, Ninja, /MT, _ITERATOR_DEBUG_LEVEL=0. Die automatische Auswahl wendet die Einstellungen für /MT und Iteratoren an; ein explizites LLVM_DIR tut das nicht, und die Link-Probe schlägt dann fehl.

Historische macOS-Referenz: Homebrew llvm 23.1.1_1 (arm64, gemeinsame libLLVM.23.1.dylib, Assertions aus) mit AppleClang 21.

Weitere Voraussetzungen: CMake ≥ 3.28, ein C++23-Compiler, Boost ≥ 1.90, toml++ 3.4.0 und die Qualitätswerkzeuge. OTP wird nur für optionale Audits und die Neuerzeugung von Fixtures benötigt.