Der Lyx-Compiler (lyxc) ist ein moderner Cross-Compiler für Linux, Windows, macOS und Embedded-Systeme. Er kombiniert Compiler, Linker und statisches Analyse-Werkzeug in einem einzigen Binary.
lyxc [Optionen] <Eingabedatei(en)>
# Einfaches Beispiel
lyxc main.lyx -o main
# Mehrere Quelldateien
lyxc main.lyx utils.lyx protocol.lyx -o app
# Cross-Compilation mit vollständigem Safety-Build
lyxc main.lyx --target=arm64 --target-energy=1 --stack-check --lint -o firmware.elf
Flags können in beliebiger Reihenfolge angegeben werden. Kurzformen (‑o) und Langformen (--output) sind gleichwertig, wo beide existieren.
| Flag | Kurzform | Beschreibung |
|---|---|---|
--output=<datei> | -o | Ausgabedatei. Standard: a.out (Linux/macOS) / a.exe (Windows) |
--include=<pfad> | -I | Suchpfad für Units und Module. Mehrfach verwendbar: -I src -I lib |
--std-path=<pfad> | – | Überschreibt den Pfad zur Standardbibliothek (Standard: /usr/lib/lyx/std/) |
--lib-path=<pfad> | -L | Suchpfad für zu linkende Bibliotheken (statisch oder dynamisch) |
--link=<lib> | -l | Bibliothek linken (z. B. -lm, -lc, -lpthread) |
--static | – | Erstellt eine statisch gelinkte Binärdatei (kein .so/.dll nötig) |
--shared | – | Erstellt eine Shared Library (.so / .dll / .dylib) |
--compile-unit | – | Kompiliert eine .lyx-Datei zu einer vorkompilierten .lyu-Unit |
--emit-map | – | Erzeugt eine .map-Datei mit allen Symbol-Adressen und -Größen |
# Normaler Build (Linux)
lyxc main.lyx -o myapp
# Mit externer C-Bibliothek linken
lyxc main.lyx -o myapp -lm -lpthread
# Shared Library erstellen
lyxc mylib.lyx --shared -o libmylib.so
# Unit vorkompilieren
lyxc --compile-unit src/utils.lyx
# → erzeugt: src/utils.lyu
Lyx unterstützt native Cross-Compilation ohne externe Toolchain-Konfiguration (sofern der Linker installiert ist).
| Target-Name | Alias | Plattform | Format |
|---|---|---|---|
linux | elf | Linux x86_64 | ELF64 |
win64 | windows | Windows x64 | PE32+ |
arm64 | linux-arm64 | Linux ARM64 (Server, Raspberry Pi, …) | ELF64 |
macosx64 | darwin | macOS x86_64 | Mach-O |
macos-arm64 | – | macOS ARM64 (Apple Silicon) | Mach-O |
esp32 | xtensa | ESP32 Microcontroller (Xtensa LX6) | ELF32 |
riscv | riscv64 | RISC-V 64-Bit (RV64GC) | ELF64 |
lyxc main.lyx --target=arm64 -o firmware.elf
lyxc main.lyx --target=win64 -o app.exe
lyxc main.lyx --target=riscv -o controller.elf
Erzwingt eine spezifische CPU-Architektur, unabhängig vom Target:
lyxc main.lyx --target=linux --arch=arm64 -o cross.elf
Verfügbare Werte: x86_64, arm64, xtensa, riscv64
Gibt das Sysroot für Cross-Compilation an (Pfad zu den Ziel-System-Bibliotheken):
lyxc main.lyx --target=arm64 --sysroot=/opt/arm64-sysroot -o app.elf
Steuert das Energy-Aware-Backend. Beeinflusst Loop Unrolling, SIMD-Nutzung, Inlining-Aggressivität und Instruktions-Scheduling.
| Level | Name | Loop Unrolling | SIMD | Inlining | Einsatz |
|---|---|---|---|---|---|
| 1 | Minimal | 2× | Nein | Konservativ | IoT, Batterieknotenµ |
| 2 | Low | 4× | Nein | Moderat | Mobile Embedded |
| 3 | Standard | 4× | Optional | Ausgewogen | Server, Desktops |
| 4 | High | 8× | Ja | Aggressiv | Hochleistungs-Server |
| 5 | Extreme | 8× + SIMD | Ja (AVX2/NEON) | Maximal | DSP, HPC, ML-Inferenz |
lyxc node.lyx --target=arm64 --target-energy=1 -o sensor.elf # Batterie-optimiert
lyxc dsp.lyx --target=linux --target-energy=5 -o dsp.out # Max-Performance
Deaktiviert alle IR-Optimierungen (Constant Folding, Dead Code Elimination, Loop Unrolling). Nützlich für Debugging und Timing-Messungen.
lyxc main.lyx --no-opt --debug -o main_dbg
Deaktiviert Constant Folding für Fließkomma-Operationen. Verhindert, dass der Compiler Berechnungen umordnet oder zusammenfasst (äquivalent zu globalem @flight_crit für FPU). Pflicht für DO-178C-Zertifizierung mit FPU-Nutzung.
lyxc flight.lyx --no-fp-fold --target=arm64 -o flight.elf
Maximale Größe (in IR-Instruktionen), bis zu der Funktionen automatisch inline gesetzt werden. Standard: 20. Irrelevant bei @inline (immer) und @no_opt (nie).
Diese Flags sind für die Zertifizierung sicherheitskritischer Software essenziell. Sie erzeugen Reports und schärfen die Prüfungen des Compilers.
| Flag | Beschreibung |
|---|---|
--stack-check | Statische Stack-Analyse: berechnet maximalen Stack-Verbrauch entlang aller Call-Pfade; Fehler bei Überschreitung von @stack_limit |
--call-graph | Erzeugt vollständigen Call-Graph als Bericht (Nachweis-Dokument für DO-178C) |
--static-analysis | Aktiviert erweiterte statische Analyse: Null-Pointer, uninitalisierte Variablen, nicht-erreichbarer Code |
--lint | Warnungen für Stil-Verstöße, ungenutzte Variablen, riskante Casts, Schleife ohne limit |
--lint-only | Nur Lint-Analyse, keine Binärdatei erzeugen |
--mcdc-instrument | Instrumentiert den Code für Modified Condition/Decision Coverage (Schritt 1 von 3) |
--coverage-report | Erzeugt MC/DC-Coverage-Bericht nach Test-Ausführung (Schritt 3 von 3) |
--integrity-check | Erzwingt @integrity-Annotation; berechnet CRC32-Hash des Code-Segments, schreibt ihn dreifach in .meta_safe (TMR) |
--verify-tmr | Prüft statisch, ob alle @redundant-Variablen korrekt dreifach abgelegt sind |
--wcet | WCET-Analyse (Worst-Case Execution Time): annotiert Schleifen und berichtet maximale Iterationszahlen |
--provenance | Erzeugt Provenance-Log: Quellcode-Hash, Compile-Zeitstempel, Compiler-Version, alle Flags (Audit-Trail) |
--symbol-sizes | Gibt Größe jedes Symbols (Funktionen, Variablen) aus – nützlich für Code-Größen-Nachweis |
# Schritt 1: Instrumentieren
lyxc flight.lyx --mcdc-instrument -o flight_instr.elf
# Schritt 2: Tests ausführen (erzeugt flight.cov)
./flight_instr.elf --run-tests
# Schritt 3: Report erstellen
lyxc flight.lyx --coverage-report=flight.cov -o evidence/mcdc_report.txt
$ lyxc flight.lyx --stack-check --call-graph
Stack-Analyse:
ProcessSensor → Frame: 48 B, max. Tiefe: 1 → Gesamt: 48 B ✅
FilterData → Frame: 96 B, max. Tiefe: 1 → Gesamt: 96 B ✅
ParsePacket → Frame: 32 B, max. Tiefe: 8 → Gesamt: 256 B ✅ (limit: 512)
MergeSort → Frame: 64 B, max. Tiefe: 10 → Gesamt: 640 B ✅ (limit: 8192)
RecursiveCalc → Tiefe nicht beschränkbar ✗ Fehler
Fehler: RecursiveCalc besitzt kein @stack_limit und keine nachweisbare Terminierung.
$ lyxc flight.lyx --provenance -o flight.elf
Provenance-Log: flight.elf.prov
Quelldatei: flight.lyx (SHA-256: a3f7c2...)
Compiler: lyxc v0.9.0
Compile-Zeit: 2026-05-22T14:30:00Z
Flags: --target=arm64 --stack-check --no-fp-fold --lint --provenance
Target: arm64 (AAPCS64, ELF64)
Energy-Level: 3 (Standard)
Units importiert: std.io, std.result, std.math (je mit SHA-256)
| Flag | Beschreibung |
|---|---|
--emit-asm | Gibt den generierten Maschinencode als lesbaren Pseudo-Assembler aus (je nach Target: x86_64-AT&T, ARM64, RISC-V) |
--emit-ir | Gibt die interne Intermediate Representation (IR) aus – vor der Backend-Optimierung |
--trace-passes | Gibt für jeden Compiler-Pass Name, Dauer und Änderungsanzahl aus (Profiling des Compilers) |
--trace-imports | Debuggt die Modul-Auflösung: zeigt, welche Pfade für jeden import durchsucht werden |
--dump-relocs | Zeigt Relocation-Tabelle aller externen Symbole (PLT/GOT-Einträge) |
--symbol-sizes | Gibt Größe jedes Symbols in Bytes aus (Code und Daten getrennt) |
--debug | Aktiviert Debug-Informationen (DWARF) in der Ausgabedatei |
--debug-level=<1-3> | Detailtiefe der Debug-Info: 1 = Zeilennummern, 2 = Variablen, 3 = vollständig |
--emit-map | Erzeugt .map-Datei mit Adressen aller Symbole |
$ lyxc add.lyx --emit-asm --target=linux
; fn Add(a: int64, b: int64): int64
Add:
push rbp
mov rbp, rsp
mov rax, rdi
add rax, rsi
pop rbp
ret
$ lyxc add.lyx --emit-asm --target=arm64
Add:
stp x29, x30, [sp, #-16]!
mov x29, sp
add x0, x0, x1
ldp x29, x30, [sp], #16
ret
$ lyxc main.lyx --trace-passes -o main
Pass: Parser 2.3 ms (823 Nodes)
Pass: Semantic 1.1 ms (0 Fehler, 2 Warnungen)
Pass: IR-Gen 3.4 ms (1204 IR-Instruktionen)
Pass: Constant-Fold 0.4 ms (37 Faltungen)
Pass: DCE 0.2 ms (12 Instruktionen entfernt)
Pass: Loop-Unroll 0.6 ms (8 Schleifen, Faktor 4×)
Pass: Register-Alloc 1.8 ms
Pass: Code-Emit 2.1 ms (3.2 KB Code)
Pass: Linker 0.9 ms
Gesamt: 12.8 ms → main (3.6 KB)
$ lyxc flight.lyx --symbol-sizes --target=arm64
Symbol-Größen:
Funktionen:
ProcessFlightData 312 B
FilterAltitude 88 B
ParsePacket 156 B
main 64 B
Globale Variablen:
g_sensor_buffer 2048 B
g_config 32 B
Gesamt Code: 620 B
Gesamt Daten: 2080 B
Der integrierte Linter läuft als Teil des Compile-Prozesses oder eigenständig.
| Flag | Beschreibung |
|---|---|
--lint | Aktiviert alle Standard-Warnungen |
--lint-only | Nur Lint, keine Binärdatei erzeugen (schneller Feedback) |
--lint-strict | Alle Warnungen als Fehler behandeln (für CI/CD-Pipelines) |
--verify-tmr | Prüft ob alle @redundant-Variablen korrekt dreifach vorliegen |
--static-analysis | Erweiterte statische Analyse (Null-Pointer, uninit. Vars, dead code) |
| Warnung | Auslöser |
|---|---|
unused-var | Variable deklariert, nie gelesen |
unused-import | import ohne Verwendung im Modul |
risky-cast | as-Konvertierung mit möglichem Datenverlust (f64→int32, int64→uint8) |
unbounded-loop | while ohne limit in @dal(A/B)-Modul |
nil-deref | Pointer-Dereferenz ohne vorherigen nil-Check |
unreachable-code | Code nach return oder break |
missing-case | match über Enum ohne vollständige Abdeckung |
unsafe-in-dal | unsafe-Block in @dal(A/B)-Modul |
$ lyxc main.lyx --lint-only
main.lyx:12: Warnung [unused-var] 'temp' wird nie gelesen
main.lyx:28: Warnung [risky-cast] int64 → uint8 (mögliche Truncation)
main.lyx:41: Warnung [unbounded-loop] while ohne 'limit' in @dal(B)-Modul
main.lyx:55: Fehler [unsafe-in-dal] unsafe-Block in @dal(A)-Modul nicht erlaubt
3 Warnungen, 1 Fehler
| Flag | Typ | Beschreibung |
|---|---|---|
--arch=<ARCH> | Target | CPU-Architektur erzwingen |
--call-graph | Safety | Call-Graph-Bericht erzeugen |
--compile-unit | Ausgabe | .lyx → .lyu vorkompilieren |
--coverage-report=<datei> | Safety | MC/DC-Coverage-Bericht aus .cov-Datei |
--debug | Debug | DWARF-Debug-Informationen einbetten |
--debug-level=<1-3> | Debug | Detailtiefe der Debug-Informationen |
--dump-relocs | Debug | Relocation-Tabelle ausgeben |
--emit-asm | Debug | Assembler-Ausgabe |
--emit-ir | Debug | IR-Ausgabe (vor Backend) |
--emit-map | Ausgabe | .map-Symboldatei erzeugen |
-I <pfad> | Eingabe | Include-Pfad hinzufügen |
--inline-threshold=<n> | Opt. | Auto-Inline-Grenze in IR-Instruktionen |
--integrity-check | Safety | CRC32-Hash dreifach in .meta_safe schreiben |
-L <pfad> | Linker | Bibliotheks-Suchpfad |
-l <lib> | Linker | Bibliothek linken |
--lint | Linter | Standard-Warnungen aktivieren |
--lint-only | Linter | Nur Lint (kein Build) |
--lint-strict | Linter | Alle Warnungen als Fehler |
--mcdc-instrument | Safety | MC/DC-Instrumentierung einbetten |
--mcdc-report | Safety | MC/DC-Report erzeugen (ohne .cov) |
--no-fp-fold | Safety | Float Constant Folding deaktivieren |
--no-opt | Opt. | Alle IR-Optimierungen deaktivieren |
-o <datei> | Ausgabe | Ausgabedatei benennen |
--provenance | Safety | Provenance-Log (Audit-Trail) erzeugen |
--shared | Ausgabe | Shared Library erstellen |
--stack-check | Safety | Statische Stack-Limit-Prüfung |
--static | Linker | Statisch linken |
--static-analysis | Linter | Erweiterte statische Analyse |
--std-path=<pfad> | Eingabe | Standardbibliothek-Pfad überschreiben |
--symbol-sizes | Debug | Symbolgröße ausgeben |
--sysroot=<pfad> | Target | Sysroot für Cross-Compilation |
--target=<TARGET> | Target | Zielplattform (→ Tabelle Abschnitt 2) |
--target-energy=<1-5> | Opt. | Energy-Level des Backends |
--trace-imports | Debug | Modul-Auflösung protokollieren |
--trace-passes | Debug | Compiler-Passes mit Zeitangabe |
--verify-tmr | Safety | TMR-Korrektheit prüfen |
--wcet | Safety | WCET-Analyse und Schleifen-Report |
lyxc main.lyx -o main
./main
lyxc main.lyx --debug --debug-level=2 --no-opt -o main_dbg
./main_dbg
# Bei Absturz: vollständiger Stack-Trace mit Zeilennummern
lyxc main.lyx --lint-only --lint-strict
# Exit-Code 0 = sauber, 1 = Warnungen/Fehler → Pipeline schlägt fehl
lyxc main.lyx \
--target=arm64 \
--target-energy=3 \
-o app.elf
# Auf dem Zielgerät ausführen:
scp app.elf pi@raspberrypi:~/
ssh pi@raspberrypi ./app.elf
lyxc sensor.lyx \
--target=esp32 \
--target-energy=1 \
--static \
--stack-check \
-o sensor.elf
lyxc flight_control.lyx \
--target=arm64 \
--no-fp-fold \
--stack-check \
--call-graph \
--static-analysis \
--lint --lint-strict \
--mcdc-instrument \
--integrity-check \
--provenance \
--symbol-sizes \
--emit-map \
-o evidence/fcc.elf
# MC/DC-Nachweis (nach Test-Durchlauf):
./evidence/fcc.elf --run-tests
lyxc flight_control.lyx --coverage-report=fcc.cov -o evidence/mcdc_report.txt
# Level 1: Batterie-optimiert
lyxc dsp.lyx --target-energy=1 --symbol-sizes -o dsp_low.elf
# Level 5: Maximum-Performance
lyxc dsp.lyx --target-energy=5 --symbol-sizes -o dsp_high.elf
# Größenvergleich
ls -lh dsp_low.elf dsp_high.elf
# dsp_low.elf: 8.2 KB (wenig Unrolling, kein SIMD)
# dsp_high.elf: 24.1 KB (8× Unrolling, AVX2-Instruktionen)
lyxc main.lyx --trace-passes --emit-ir --emit-asm -o main 2>build.log
grep "Pass:" build.log | sort -k3 -n # Langsamste Passes zuerst
lyxc main.lyx \
--provenance \
--call-graph \
--target=arm64 \
-o release/main.elf
cat release/main.elf.prov # Vollständiger Audit-Trail
Weiterführende Seiten: