Clause
← Gesamte Dokumentation

Das englische Original wurde seit dieser Übersetzung geändert, daher können Teile davon veraltet sein. Auf Englisch lesen

Übersetzt aus dem englischen Original · 1e3a39c8-dirty · 2026-10-26

TOML-Projekte

Ein Projektmanifest wählt geordnete Gruppen von Erlang-Quellen aus und konfiguriert jedes Ziel unabhängig. Alle CLI-Aktionen akzeptieren Projekte. Siehe das funktionierende Beispiel.

Manifest (Schema 1)

schema_version = 1

[[targets]]
name = "app"
sources = ["main.erl", "src/workers/*.erl", "shared/**/*.erl"]
source_dirs = ["src/support"]
output = "build/app"
entry = "main:main"
build_dir = "build"

[targets.options]
source_search_paths = ["src", "generated"]
include_dirs = ["include", "vendor/include"]
defines = ["DEBUG", "LIMIT=100", 'LABEL="demo"']
enable_features = ["maybe_expr"]
disable_features = ["compr_assign"]
ignore_dirs = ["src/legacy", "deps/*/test"]
ignore_modules = ["telemetry", "*_SUITE"]
keep_exports = false
shell = false
cache_inference_in_dirs = ["deps/*"]

[targets.options.applications]
my_dependency = "vendor/my_dependency"

CLI und Zielauswahl

clau [options] <source.erl>...
clau [options] --project <path> [--target <name>]...
clau --new-project <filename>

Jedes ausgewählte Ziel ist ein separater Kompilier-Batch mit eigenen Präprozessor-Sitzungen. Die Planung (Dekodieren, Auswählen, Suchen, Prüfen auf Ausgabekollisionen) ist abgeschlossen, bevor irgendeine Quelle läuft; die Ausführung verarbeitet dann Ziele/Dateien der Reihe nach und hält Fehlschläge fest. Nutzausgaben gehen ohne Banner (außer den Zielzeilen von --print-inputs) in Ziel-/Dateireihenfolge nach stdout; Kontext und Diagnosen gehen nach stderr. Ein Ziel mit Diagnosen wird einmal genannt, in einer Zeile <manifest> [target <name>]: vor seiner ersten; die Diagnosen selbst (error: file:line:col: message) tragen kein Werkzeug- oder Zielpräfix.

./build/debug/bin/clau --parse-check --project examples/project/project.toml
./build/debug/bin/clau --print-ast --project examples/project/project.toml --target tests --target app

Ausführbare Dateien

clau --project FILE [--target T]... (kein --emit, keine Prüf-/Ausgabeaktion) linkt jedes ausgewählte Ziel, das einen Schlüssel output oder entry hat oder das CLI--o/--entry adressiert, zu einer ausführbaren Datei pro Ziel:

./build/debug/bin/clau --project tests/fixtures/linking/project/project.toml

Ein Projekt erstellen

--new-project <filename> schreibt ein kommentiertes Manifest und sonst nichts.

Build-Verzeichnis

Jedes Projektziel hat ein Build-Verzeichnis, in dem Clause seine eigenen temporären Dateien und seine Caches ablegt: das build_dir des Ziels, relativ zum Manifest, Standard <manifest-dir>/build. --build-dir DIR (relativ zum Aufruf) ersetzt es für jedes ausgewählte Ziel. Positionale Eingaben bekommen keines, außer --build-dir ist angegeben.

Build-Caches

Ergebnisse, die es wert sind, zwischen Läufen behalten zu werden, liegen unter <build_dir>/cache; --no-cache liest und schreibt sie weder. Es sind die Antworten des Laders für Parse-Transformationen und die Liste der Sticky-Module des Host-OTP, sodass ein warmer Build kein Host-erl für Module startet, deren Transformationseingaben sich nicht geändert haben, das Kompilierergebnis jedes Batches und die Inferenzergebnisse von Modulen in konfigurierten Verzeichnissen.

Inferenz-Cache

Bibliotheksmodule (die Quellen von OTPs stdlib, kernel, compiler und syntax_tools, die über source_search_paths gefunden werden, Clauses eigene Bibliothek) ändern sich selten, daher behalten Module in konfigurierten Verzeichnissen ihre Ergebnisse der Typinferenz im Build-Cache, pro Modul, und spätere Kompilierungen verwenden sie wieder, statt sie erneut zu inferieren.

Pfade und Suche

Verzeichnisindex

Lookups nach Namen sondieren nicht jedes Kandidatenverzeichnis. Ein Index pro Aufruf von clau, von allen Zielen geteilt, hält die Eintragsnamen jedes durchsuchten Verzeichnisses: einmal nicht rekursiv aufgelistet, wenn ein Lookup es zum ersten Mal braucht, oder von den rekursiven Durchläufen verzeichnet, die ** in sources, source_dirs, source_search_paths, include_dirs und transform_paths expandieren, sodass kein Verzeichnis zweimal aufgelistet wird. Er beantwortet die Fehltreffer der Modulsuche (die Bibliothek, dann source_search_paths), Transformationsquellen, literale sources, die über source_search_paths gefunden werden, und die Include-Auflösung (das Verzeichnis der einbindenden Datei, das Arbeitsverzeichnis, Include-Verzeichnisse der Reihe nach, dann include_lib-Anwendungen); ein Kandidat, den der Index hält, wird weiterhin wie zuvor geöffnet oder geprüft, sodass sich Vorrang, ignore_dirs und Fehlerberichte nicht ändern. Include-Namen mit Verzeichnisteilen (sub/x.hrl) werden in dem Verzeichnis nachgeschlagen, das sie benennen; Namen mit ..-Schritten, absolute Namen, relative Verzeichnisse und fehlgeschlagene Auflistungen werden wie zuvor sondiert.

Ignorierte Quellen

ignore_dirs und ignore_modules halten Quellen aus einem Ziel heraus, ohne sie aus dem Baum zu entfernen, z. B. mitgelieferte Tests, Altcode oder Module, die nur unter OTP eine Rolle spielen. Eine ignorierte Quelle wird stillschweigend übersprungen: Sie wird nie gelesen, geparst, kompiliert oder gelinkt, darf also sogar Syntaxfehler enthalten.

[targets.options]
source_search_paths = ["deps/**"]
ignore_dirs = ["deps/*/test", "src/legacy"]
ignore_modules = ["telemetry", "*_SUITE"]

Wirksame Optionen

EinstellungKombination aus Manifest und CLI
include_dirsManifestreihenfolge, nach CLI--I (letztes CLI--I wird zuerst durchsucht); ein Eintrag mit Wildcards (deps/*/include, apps/**/include) expandiert an Ort und Stelle zu den vorhandenen Verzeichnissen, auf die er passt, sortiert nach UTF-8-Pfadbytes (** passt auch auf keines, Verzeichnis-Symlinks werden übersprungen); ein Muster ohne Treffer ist ein Fehler
source_search_pathsErsatzwurzeln für literale Quellen und die Module, die das Ziel benennt, aber nicht aufführt; Muster expandieren wie bei include_dirs (ohne Treffer: unmatched source search path pattern)
definesZuerst Manifest, dann CLI; Duplikate über beide hinweg sind Fehler
applicationsManifest-Map; CLI-Einträge ersetzen gleichnamige
Feature-ListenManifesteinstellungen, dann geordnete CLI-Änderungen; CLI gewinnt
outputPro Ziel, nur ausführbare Ziele; CLI--o überschreibt für ein einzelnes ausgewähltes Ziel
entryPro Ziel; CLI---entry überschreibt für ein einzelnes ausgewähltes Ziel
cache_inference_in_dirsImplizite OTP-Muster, dann die des Manifests, dann CLI---cache-inference-in-dirs (Inferenz-Cache)

Build-Abhängigkeit

Compiler-internes toml++ 3.4.0 (MIT), nur Header, mit Ausnahmen, nicht veröffentlichte Syntax deaktiviert. SHA-256 des Archivs 8517f65938a4faae9ccf8ebb36631a38c1cadfb5efa85d9a72e15b9e97d25155.

Der Build-Cache verwendet das SQLite-3.54.0-Amalgamat (gemeinfrei), nur in die Cache-Bibliothek des Compilers kompiliert (clause_sqlite, ohne die Warnungsflags des Projekts). CMake lädt https://www.sqlite.org/2026/sqlite-amalgamation-3540000.zip auf jedem Host nach thirdparty/ herunter und verifiziert seine SHA-256 68e913b0fe8ec6b4e5f391c594a28872884e80d6cd042a1e50c957be46b5aa4d; -DCLAUSE_SQLITE_ROOT=<directory with sqlite3.c and sqlite3.h> hat Vorrang und deaktiviert den Download.

Grenzen

Manifestgröße 1 MiB; höchstens 1.024 Ziele und 100.000 TOML-Knoten. Jede Quellenexpansion erlaubt 100.000 besuchte Einträge, 128 Verzeichnisebenen und 16.000.000 Wildcard-Übergänge. Erschöpfung ist ein expliziter Fehler; dies sind Arbeitsgrenzen, keine I/O-Fristen.