Inhaltsverzeichnis

Lyx Compiler – CLI Referenz

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.

Aufruf-Syntax

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 --static-analysis --lint -o firmware.elf

Flags können in beliebiger Reihenfolge angegeben werden. Kurzformen (‑o) und Langformen (--output) sind gleichwertig, wo beide existieren.

Stand der Schalter

Alle Schalter aus lyxc –help wurden gegen 1.1.14A einzeln nachgemessen — nicht nur am Rückgabewert, sondern am erzeugten Programm (Byte-Vergleich, file auf das Format, Lauf des Erzeugnisses).

<WRAP info> Mit 1.1.12D sind die Assembler-Schalter umgesetzt. --emit-asm, --asm-listing und --dump-asm wurden bis dahin abgewiesen (#1370) — sie arbeiten jetzt. Auch --profile und --debug-symbols wirken inzwischen. Übrig bleibt ein einziger echter Mangel: die Optimierstufen sind untereinander nicht unterscheidbar. Wer eine ältere Fassung benutzt, findet den alten Stand in der Versionsgeschichte der Seite. </WRAP>

Gruppe Anzahl Bedeutung
arbeiten wie beschrieben 44 --target vollständig, --arch, --format, -I, --std-path, --shared, --target-energy, --emit=lbf, Linter, --debug, --debug-symbols, --runtime-checks, --verify-tmr, --mcdc-report, --seccomp-trap, --android-api, --dump-relocs, --map-file, --emit-asm, --asm-listing, --profile, die IR-Diagnose, --version/--build-info/--config
ausdrücklich abgewiesen 1 --trace — Exit 2 mit klarer Meldung; die Trace-Builtins arbeiten ohne Schalter
noch offen 1 siehe Kasten
 
Was weiterhin nicht hält, was die Hilfe verspricht (gemessen mit 1.1.14B):

* -O0, -O1, -O2, -O3, -Osafe und --no-opt liefern an demselben Programm byte-gleiche Erzeugnisse (4243 Byte in allen sechs Läufen). Die Stufen sind untereinander nicht unterscheidbar (#1371).

--mcdc baut weiterhin keine Instrumentierung ein — das ist seit 1.1.12D aber kein Mangel mehr, sondern die Ansage: die Hilfe nennt den Schalter „MC/DC-Strukturanalyse (Uebersetzungszeit, keine Laufzeitmessung)„. --debug-symbols wirkt (Programm 4243 → 5095 Byte).

Was sich mit 1.1.12D bis 1.1.14A geändert hat:

Schalter vorher jetzt (1.1.14A gemessen)
--emit-asm Exit 2, abgewiesen (#1370) schreibt ein Assembler-Listing nach <ausgabe>.asm (im Prüflauf 87 KB), Programm unverändert
--asm-listing Exit 2, abgewiesen (#1370) Auflistung mit Adressen, Bytes und Quellzeilen nach <ausgabe>.asm (seit 1.1.14B, #1862; bis 1.1.14A ging sie nach stdout); nicht gedeutete Bytes meldet sie ausdrücklich am Ende
--dump-asm Exit 2, abgewiesen (#1370) umgesetzt (#1370 geschlossen)
--profile Exit 2, abgewiesen (#1370) wirkt: Erzeugnis wächst von 4243 auf 4345 Byte
--debug-symbols „ohne Wirkung“ bettet Debug-Info ein (4243 → 5095 Byte)
--dump-relocs, --map-file in den Detailtabellen als „nicht umgesetzt„ geführt arbeiten: Relokationstabelle nach stdout, <ausgabe>.map (507 Byte)
Projektdatei gab es nicht lyxc projekt.lpf — siehe Projektdatei *.lpf

Was sich mit 1.0.20F geändert hat:

Schalter vorher jetzt
--dump-ir, --ir-source-map, --provenance erzeugten ein Programm mit Exit 42 erzeugen ein lauffähiges Programm, identisch zum Bau ohne den Schalter (#1523)
--config Exit 1, 61 Zeilen mit angehängter Hilfe Exit 0, 4 Zeilen (#1527)
--format=pe lieferte ELF liefert PE32+ (#1526)
--arch=xtensa lieferte still x86-64 wird abgewiesen (#1526)
--seccomp-trap ohne Wirkung SECCOMP_RET_TRAP statt KILL_PROCESS (#1526)
--android-api nahm jeden Wert an weist Werte außerhalb des Bereichs ab (#1526)
--trace ohne Wirkung wird abgewiesen (#1370)
--mcdc-report zählte a && b als eine Bedingung zählt richtig: n Bedingungen → n+1 Testfälle (#1524)

Zwei Schalter werden angenommen, fehlen aber in lyxc –help: --dump-ir und --meta-safe.


1. Eingabe & Ausgabe

Flag Kurzform Beschreibung
--output=&lt;datei&gt; -o Ausgabedatei. Standard: a.out (Linux/macOS) / a.exe (Windows)
--include=&lt;pfad&gt; -I Suchpfad für Units und Module. Mehrfach verwendbar: -I src -I lib
--std-path=&lt;pfad&gt;'' | – | Überschreibt den Pfad zur Standardbibliothek. Ohne Angabe sucht ''lyxc'' in dieser Reihenfolge: relativ zur Quelldatei → ''-I''/''LYX_PATH'' → ''--std-path/LYX_STD_PATH → Installationspfad /usr/include/lyx/units (seit 1.0.17I, #1368 — eine Umgebungsvariable ist nach der Paketinstallation nicht mehr nötig)
--format=&lt;fmt&gt; Ausgabeformat: elf, pe, macho — seit 1.0.20F wirken alle drei (#1526)
--output-type=&lt;typ&gt; executable (Standard) oder shared-lib
--shared Kurzform für --output-type=shared-lib
--compile-unit Kompiliert eine .lyx-Datei zu einer vorkompilierten .lyu-Unit
--map-file Symbol- und Sektionskarte als &lt;ausgabe&gt;.map (seit 1.0.20A, #1370)
Es gibt keine Linker-Flags. --lib-path / -L, --link / -l und --static existieren nicht — lyxc erzeugt statische ELF-Dateien und bindet C-Bibliotheken über extern fn … link „libfoo.so“ im Quelltext ein (→ FFI). --no-libc-init wird dagegen angenommen, obwohl es in lyxc --help nicht auftaucht.

Beispiele

# Normaler Build (Linux)
lyxc main.lyx -o myapp

# Shared Library erstellen
lyxc mylib.lyx --shared -o libmylib.so

# Unit vorkompilieren
lyxc --compile-unit src/utils.lyx
# → erzeugt: src/utils.lyu


2. Target & Architektur

lyxc ist vollständig self-contained: kein externer Linker (kein ld, lld o. ä.) nötig. Der Compiler schreibt ELF64/ELF32/PE32+/Mach-O direkt in einem Schritt.

→ Ausführlicher Guide: Cross-Compilation

--target=<TARGET>

Target-String Alias Architektur Format Status
linux x86_64 x86_64 ELF64 Stabil
arm64 linux-arm64 ARM64 Linux ELF64 Stabil *
linux-riscv64 riscv, riscv64 RV64GC Linux ELF64 Stabil *
arm-cm4 arm-cm33 ARM Cortex-M4/M33 ELF32 Stabil
arm_cm ARM Cortex-M (generisch) ELF32 Stabil
win64 windows-x86_64 Windows x64 PE32+ Stabil
windows-arm64 Windows ARM64 PE32+ Stabil
macosx64 macos-x86_64 macOS x86_64 Mach-O Stabil
macos-arm64 macOS ARM64 (Apple Silicon) Mach-O Stabil
android android-arm64 Android ARM64 (.so) ELF64 Stabil
android-x86_64 Android x86_64 (Emulator) ELF64 Stabil
esp32 esp32s3 Xtensa LX6 (ESP32) ELF32 Experimentell

* StrConcat fehlt auf arm64 und riscv (#2028, nachgemessen mit lyxc 1.2.5C):

error: arm64: Builtin-ID 7 wird im Linux-Zweig nicht behandelt
error: riscv: Builtin-ID 7 wird nicht behandelt

Damit lässt sich für diese beiden Ziele praktisch kein Programm bauen, das einen berechneten Wert mit Text verbindet. Die übrigen String-Builtins sind in Ordnung — geprüft mit IntToStr, StrLen, FloatToStr und StrSub. Der Rest der IR-Ziele wurde mit #2018, #2019 und #2022 gerade nachgezogen: zuvor waren 33 bzw. 41 stdlib-Units für arm64 unbaubar.

lyxc main.lyx --target=arm64 -o firmware.elf
lyxc main.lyx --target=win64 -o app.exe
lyxc main.lyx --target=linux-riscv64 -o controller.elf
lyxc mylib.lyx --target=android --output-type=shared-lib -o libmylib.so

Alle Ziele wurden mit file auf das erzeugte Format geprüft und liefern das jeweils richtige: PE32+ für win64, Mach-O für die macOS-Ziele, ARM aarch64, RISC-V. esp32 bricht mit einer klaren Meldung ab (Zeichenkettenliterale sind fuer xtensa nicht umgesetzt) — das ist der ehrliche Umgang mit einer Lücke.

--arch=<ARCH>

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, arm_cm

 
Seit 1.0.20F wird –arch=xtensa abgewiesen, statt still ein x86-64-Programm zu erzeugen (#1526). Für Xtensa führt der Weg über –target=esp32, das die eigentliche Lücke benennt (Zeichenkettenliterale sind fuer xtensa nicht umgesetzt).

x86_64, arm64 und riscv64 arbeiten korrekt und liefern jeweils das passende ELF.

--format=&lt;fmt&gt;

Seit 1.0.20F wirken alle drei Werte (#1526): –format=pe liefert ein PE32+, –format=macho ein Mach-O. Vorher kam in allen Fällen ELF heraus.

--format=elf    →  ELF 64-bit LSB executable, x86-64
--format=pe     →  PE32+ executable (console) x86-64, for MS Windows

Bequemer bleibt der Weg über –target, weil dieser zugleich die Architektur und die Aufrufkonvention festlegt.

Seit 1.1.3E ist das PE-Ziel auch für fremde Bibliotheken benutzbar: extern fn … link „x.dll“ erscheint in der Import-Tabelle, Argumente gehen nach Microsoft-x64-Konvention, und eine Relokationstabelle über einer Seite (0x1000) sprengt SizeOfImage nicht mehr — vorher lehnte Windows solche Dateien als „Fehlerhaftes EXE-Format“ ab, das Programm startete gar nicht (#1672, #1671, #1674, #1676). Einzelheiten in FFI — Windows-DLLs.


3. Optimierung & Energy-Awareness

Energy-Awareness-Annotationen und Compiler-Optimierungen:

--target-energy=<1–5>

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 Nein Konservativ IoT, Batterieknoten
2 Low Nein Moderat Mobile Embedded
3 Standard Optional Ausgewogen Server, Desktops
4 High Ja Aggressiv Hochleistungs-Server
5 Extreme 8× + SIMD Ja (AVX2/NEON) Maximal DSP, HPC, ML-Inferenz

Der Schalter wirkt tatsächlich, und zwar deutlich — dasselbe Programm über alle fünf Stufen:

Stufe 1:  33 107 Byte
Stufe 2:  49 491 Byte
Stufe 3:  94 547 Byte      = Standard, entspricht dem Aufruf ohne Schalter
Stufe 4:  94 547 Byte      identisch mit Stufe 3
Stufe 5: 237 907 Byte

Damit ist –target-energy der einzige Schalter dieses Abschnitts, der etwas bewirkt — er übernimmt die Rolle, die anderswo -O hätte.

 
Stufe 4 ist byte-identisch mit Stufe 3. Die Tabelle oben verspricht für Stufe 4 doppeltes Unrolling, SIMD und aggressiveres Inlining; erzeugt wird dasselbe Programm wie bei Stufe 3. Wirksam unterschieden sind nur 1, 2, 3/4 und 5.

Ein Wert außerhalb von 1–5 bricht ab (Exit 2).

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

--no-opt und -O<0-3> — beide ohne Wirkung

–no-opt und -O0 schalten seit 1.0.20A die Vereinfachungen ab, die der Codegen beim Emittieren vornimmt — Konstantenfaltung und tote Zweige (#1371). Das Erzeugnis unterscheidet sich messbar:

Standard   d61a5580b507  4216 B
-O0        917cb3e9c87e  4222 B
--no-opt   917cb3e9c87e  4222 B
-O3        d61a5580b507  4216 B

 
-O0 und --no-opt unterscheiden sich inzwischen vom Rest (#1647, nachgemessen mit lyxc 1.2.2B): sie erzeugen ein anderes Erzeugnis als der Aufruf ohne Schalter. -O1, -O2 und -O3 liefern weiterhin untereinander dasselbe — und dasselbe wie der Standardaufruf.

Gemessen an einem Schleifenprogramm (115304 Byte in allen Fällen, Prüfsummen):

^ Aufruf ^ Erzeugnis ^
| ohne Schalter (= -O2) | 93820736… |
| -O1 · -O2 · -O3 | 93820736… — identisch zum Standard |
| -O0 · --no-opt | d7109877… — abweichend |

Ein abgestufter IR-Optimierer ist das nicht: es gibt eine Optimierung, die sich mit -O0 abschalten lässt — plus -Osafe als eigene, vorsichtigere Fassung. --help nennt -O2 als Standard.

-Osafe gibt es inzwischen (#1525, nachgemessen mit lyxc 1.2.2D): der Schalter wird angenommen, steht in --help und erzeugt ein drittes, von -O0 und -O1-O3 verschiedenes Erzeugnis — „nur nachweislich sichere Umformungen„. Frühere Fassungen meldeten hier fünf Fehlermeldungen, weil der Parser den Namen zeichenweise zerlegte.

Die Fehlerbehandlung von -O arbeitet korrekt: -O, -O9 und -Ox brechen mit lyxc: -O erwartet eine Stufe 0..3 und Exit 2 ab.

-O0 übersetzt dasselbe Programm wie die höheren Stufen. Bis lyxc 1.1.3B wies es gültige Enum-Konstanten aus importierten Units ab (der Wert von AL_NONE muss zur Uebersetzungszeit feststehen), weil die Konstantenfaltung für Enums nur im Optimierer stattfand statt in der Semantikprüfung (#1647). Damit fiel gerade die Stufe aus, die man beim Eingrenzen von Codegen-Fehlern zuerst greift.

Für stärkeren Einfluss auf die Codeerzeugung bleibt –target-energy.

 
--no-fp-fold und --inline-threshold gibt es nicht. Wer Fließkomma-Umordnung unterbinden will, annotiert die betroffene Funktion mit @flight_crit (→ Attribute); die Inline-Grenze ist nicht einstellbar.

4. Safety & Verifikation (DO-178C)

Diese Flags sind für die Zertifizierung sicherheitskritischer Software gedacht. Gemessen mit 1.1.14A.

Flag Beschreibung
--static-analysis Statische Analyse: Data-Flow, Live-Variablen, Stack
--call-graph Statischer Aufrufgraph — Grundlage für WCET-Abschätzung und Rekursionserkennung
--runtime-checks Laufzeitprüfungen: Bereichsgrenzen, Null-Zeiger, Division durch null
--mcdc MC/DC-Strukturanalyse zur Übersetzungszeit; baut ausdrücklich keine Laufzeitmessung ein, das Erzeugnis bleibt byte-gleich
--mcdc-report Coverage-Bericht nach der Übersetzung; zählt seit 1.0.20F richtig (#1524)
--verify-tmr Bilanz der @redundant-Zugriffe; Fehler, wenn ein Zugriff am Voter vorbeigeht
--asm-listing Auflistung mit Adressen, Bytes und Quellzeilen (DO-178C 6.1) nach <ausgabe>.asm — seit 1.1.12D umgesetzt, seit 1.1.14B in der Datei statt auf stdout (#1862)
--map-file Symbol- und Sektionskarte als <ausgabe>.map — arbeitet
--provenance Provenance-Tracking IR → AST → Quelle; Erzeugnis unverändert (#1523)
--meta-safe .meta_safe-Section mit CRC32 je 4096-Byte-Page; wirkt, steht aber nicht in --help

MC/DC: der Bericht misst nicht, was er nennt

 
--mcdc-report zählt jede Entscheidung als genau eine Bedingung (#1524). Vier Funktionen mit 1, 2, 3 und 4 Bedingungen ergeben denselben Bericht:

> [MC/DC]   Eins: 1 decisions, 1 conditions → min 2 test cases
> [MC/DC]   Zwei: 1 decisions, 1 conditions → min 2 test cases      // a > 0 && b > 0
> [MC/DC]   Drei: 1 decisions, 1 conditions → min 2 test cases      // drei Bedingungen
> [MC/DC]   Vier: 1 decisions, 1 conditions → min 2 test cases      // vier Bedingungen
> 


^ Bedingungen ^ gemeldet ^ korrekt (n+1) ^
| 1 | 2 | 2 |
| 2 | 2 | 3 |
| 3 | 2 | 4 |
| 4 | 2 | 5 |

Genau die Aufschlüsselung zusammengesetzter Bedingungen ist das, was MC/DC von einfacher Zweigüberdeckung unterscheidet. Der Bericht misst derzeit Zweigüberdeckung.

--mcdc baut zudem keine Instrumentierung ein — das Programm ist mit und ohne den Schalter byte-identisch. Es gibt also nichts, was zur Laufzeit Überdeckung aufzeichnen könnte.

Brauchbar ist der Bericht als Strukturübersicht: er nennt Anzahl und Ort der Entscheidungspunkte je Funktion. Für einen Überdeckungsnachweis nach DO-178C Level A reicht das nicht — die Mindestzahl der Testfälle muss von Hand ermittelt werden.

Die Stack-Prüfung braucht kein Flag

@stack_limit wird bei jeder Übersetzung ausgewertet — ein früher hier dokumentiertes --stack-check gibt es nicht und ist auch nicht nötig:

$ lyxc rekursiv.lyx -o /dev/null
error: F: @stack_limit ist mit Rekursion nicht nachweisbar — die Aufruftiefe ist unbeschraenkt

Der Nachweis für @stack_limit selbst — Rahmengröße gegen die Schranke, Aufrufgraph bei Rekursion — wird seit lyxc 1.0.14K geführt, @wcet seit 1.0.14L, @flight_crit seit 1.0.14M; @redundant wirkt seit 1.0.15A auch an globalen Variablen und wird mit --verify-tmr geprüft. Ohne Nachweis bleiben @integrity, @dal und @critical — sie sind Vermerk, nicht Beweis.

 
Der MC/DC-Dreischritt aus früheren Fassungen läuft so nicht. --mcdc-instrument, --coverage-report und --run-tests existieren nicht. Vorhanden sind --mcdc (instrumentieren) und --mcdc-report (Bericht nach der Übersetzung, ohne .cov-Datei).

Ebenfalls nicht vorhanden: --wcet, --integrity-check, --symbol-sizes, --lint-strict.

--provenance

lyxc flight.lyx --provenance --target=arm64 -o flight.elf

Erfasst werden Quelldatei-Hash, Compiler-Version, Flags, Ziel und die importierten Units.

 
Bis 1.0.20E erzeugte dieser Aufruf ein nicht lauffähiges Programm (Exit 42). Seit 1.0.20F ist das Erzeugnis mit dem Bau ohne den Schalter identisch (#1523) — Diagnose und Auslieferungsstand entstehen also im selben Lauf, ein getrennter Aufruf ist nicht mehr nötig.

Für den Nachweis gehört die Compiler-Version aus lyxc –build-info ins Prüfprotokoll — bei dieser Doku 1.0.19E.


5. Analyse & Debugging

Flag Beschreibung
--dump-ir IR ausgeben; Erzeugnis unverändert (#1523). Fehlt in --help
--ir-source-map IR-Source-Mapping; Erzeugnis unverändert (#1523)
--emit-asm Assembler-Listing nach <ausgabe>.asm — seit 1.1.12D umgesetzt
--emit=lbf IR als .lbf-Bytecode (nur --target=lyxos)
--ast-dump AST nach dem Parsen anzeigen
--symtab-dump Symboltabelle ausgeben
--trace-passes Jeden Compiler-Pass mit Dauer protokollieren
--trace-imports Modul-Auflösung debuggen: welche Pfade je import durchsucht werden
--type-reasoning Herleitung des Typprüfers anzeigen
--constraint-log Constraint-Log ausgeben
--dump-relocs Relokationstabelle nach stdout (=== RELOCATION TABLE ===); arbeitet
--debug Debug-Informationen einbetten
--profile Laufzeitmessung je Funktion (nur x86-64) — seit 1.1.12D umgesetzt; das Erzeugnis wächst messbar
--trace wird abgewiesen (#1370); die Trace-Builtins arbeiten ohnehin immer

--dump-relocs und --map-file

Beide sind seit 1.0.20A umgesetzt (#1370) und ersetzen einen Teil dessen, was –emit-asm leisten sollte.

lyxc main.lyx --dump-relocs -o main

=== RELOCATION TABLE ===
  OFFSET    ART           ZIEL
  0x0000000000000033  STR          +32
  0x000000000000003A  STR          +40
  0x000000000000003F  CALL         main

–map-file legt die Karte neben dem Erzeugnis ab — bei -o main.bin also main.bin.map:

Lyx-Abbildkarte fuer h.bin

Sektionen
  NAME    ADRESSE           LAENGE
  .text   0x00000000004000b0  3920
  .data   0x0000000000401000  122

Anders als die drei Schalter im nächsten Abschnitt verändern beide das erzeugte Programm nicht.

--trace

Der Schalter wird seit 1.0.20F abgewiesen (Exit 2, #1370) — vorher wurde er angenommen und tat nichts. Die Trace-Builtins trace, trace_int und trace_str arbeiten unabhängig davon; wer die Ausgaben loswerden will, entfernt die Aufrufe aus dem Quelltext.


5b. KI-Integration (nicht verdrahtet)

Für KI-Agenten, IDEs und Build-Tooling sind zwei Flags vorgesehen, die JSON (Daten & Serialisierung) auf stdout schreiben: --ast-json (Parser-AST) und --error-json (strukturierte Sema-Fehler).

 
Beide Flags sind auch in 1.0.19E nicht erreichbar und brechen den Aufruf mit unbekannter Schalter und Exit 2 ab. Die Bausteine liegen im Repository (src/backend/ast_json.lyx, src/error_collector.lyx), sind aber in src/lyxc.lyx an keine Kommandozeile angeschlossen — auch nicht auf develop (1.0.16A).

Das dokumentierte JSON-Schema bleibt gültig: KI-Integration — Datenformat und interne API.

6. Linter & Verifikation

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)
--no-lint Linter-Warnungen abschalten
-wa / -we Alle Warnungen / Warnungen als Fehler
--verify-tmr Prüft ob alle @redundant-Variablen korrekt dreifach vorliegen
--static-analysis Erweiterte statische Analyse (Null-Pointer, uninit. Vars, dead code)

Lint-Kategorien

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
null-deref Pointer-Dereferenz ohne vorherigen null-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


7. Vollständige Flag-Referenz

Stand lyxc 1.0.19E, abgeglichen mit lyxc –help und je Schalter nachgerufen — mit Vergleich des Erzeugnisses, nicht nur des Rückgabewerts. Andere als die hier genannten Schalter werden seit 1.0.15D abgewiesen (Exit 2).

Eingabe und Ausgabe

Flag Beschreibung
-o &lt;datei&gt; Ausgabedatei (Standard: a.out)
-I &lt;pfad&gt; Include-Pfad für Module. Mehrfachangabe wirkt seit lyxc 1.1.6C (#1736, nachgemessen mit 1.1.11B): alle angegebenen Pfade werden durchsucht, und ein nicht existierender Pfad in der Liste macht den Bau nicht mehr kaputt
--std-path=PATH Pfad zur Standardbibliothek überschreiben
--format=&lt;fmt&gt; Ausgabeformat: elf, pe, macho
--output-type=&lt;typ&gt; executable (Standard) oder shared-lib
--shared Kurzform für --output-type=shared-lib

Ziel und Architektur

Flag Beschreibung
--target=TARGET win64, linux, arm64, macosx64, macos-arm64, esp32, riscv, android-arm64, android-x86_64, lyxos, lyxos-kernel — alle geprüft, alle liefern das richtige Format
--arch=ARCH x86_64, arm64, riscv wirken; xtensa erzeugt still x86-64 (#1526)
--format=fmt nur elf wirkt; pe und macho werden angenommen und liefern trotzdem ELF (#1526)
--android-api=N Android-API-Level; Werte außerhalb des Bereichs werden seit 1.0.20F abgewiesen (#1526)
--output-type=&lt;typ&gt;'' / ''--shared executable oder shared-lib; beide arbeiten korrekt

Optimierung

Flag Beschreibung
--target-energy=<1-5> Energy-Level des Backends; Vorgabe 3. Ungültige Werte werden abgewiesen. Der einzige wirksame Schalter dieser Gruppe — Stufe 4 ist allerdings identisch mit 3
-O0 schaltet Konstantenfaltung und tote Zweige ab (seit 1.0.20A, #1371)
-O1-O3 untereinander wirkungslos — alle drei entsprechen dem Aufruf ohne Schalter
--no-opt gleichbedeutend mit -O0

Linter

Flag Beschreibung
--lint Linter-Warnungen einschalten
--lint-only Nur linten, nicht übersetzen
--no-lint Linter-Warnungen abschalten
-wa / -we Warnungen alle / als Fehler; ohne a bzw. e bricht der Aufruf ab

Safety und Verifikation (DO-178C)

Flag Beschreibung
--static-analysis Statische Analyse (Data-Flow, Live-Vars, Stack)
--call-graph Statischer Aufrufgraph (WCET, Rekursionserkennung)
--runtime-checks Laufzeitprüfungen: Bereichs-, Null- und Division-durch-null-Prüfung
--mcdc baut keine Instrumentierung ein (#1524) — Programm byte-identisch
--mcdc-report Strukturbericht; zählt zusammengesetzte Bedingungen als eine (#1524)
--verify-tmr Bilanz der @redundant-Zugriffe; Fehler, wenn einer am Voter vorbeigeht — arbeitet korrekt
--asm-listing Auflistung mit Adressen, Bytes und Quellzeilen (DO-178C 6.1) nach &lt;ausgabe&gt;.asm — umgesetzt seit 1.1.12D, in der Datei statt auf stdout seit 1.1.14B (#1862)
--map-file Symbol- und Sektionskarte als &lt;ausgabe&gt;.map (seit 1.0.20A, #1370)
--provenance Provenance-Tracking IR → AST → Quelle; Erzeugnis unverändert (#1523)
--meta-safe .meta_safe-Section mit CRC32 je 4096-Byte-Page; wirkt, fehlt aber in --help

Analyse und Fehlersuche

Flag Beschreibung
--dump-ir IR ausgeben; Erzeugnis unverändert (#1523); fehlt in --help
--ir-source-map IR-Source-Mapping; Erzeugnis unverändert (#1523)
--emit-asm Assembler-Listung nach &lt;ausgabe&gt;.asm, ohne Quellzeilen — umgesetzt seit 1.1.12D
--emit=lbf IR als .lbf-Bytecode (nur --target=lyxos); korrekt gekoppelt
--dump-relocs Relokationstabelle nach stdout: Offset, Art, Ziel (seit 1.0.20A, #1370)
--ast-dump AST nach dem Parsen
--symtab-dump Symboltabelle
--trace-imports Import-Auflösung
--trace-passes Transformationen mitschreiben
--static-analysis / --call-graph erzeugen Zusatzausgabe, verändern das Programm nicht
--type-reasoning Herleitung des Typprüfers
--constraint-log Constraint-Log
--debug Debug-Informationen einbetten — vergrößert das Programm nachweislich
--runtime-checks Laufzeitprüfungen — vergrößert das Programm nachweislich
--profile Funktionsaufruf-Instrumentierung — umgesetzt seit 1.1.12D; das Erzeugnis waechst messbar
--trace wird abgewiesen (#1370); die Trace-Builtins arbeiten ohnehin immer

Unit-Kompilierung

Flag Beschreibung
--compile-unit Unit zu .lyu vorkompilieren
--debug-symbols Debug-Info in die .lyu einbetten — wirkt seit #1555: mit 1.1.2E nachgemessen 705 B ohne, 724 B mit
--unit-info &lt;datei&gt; Informationen über eine .lyu anzeigen
--include &lt;hdr.h&gt; C-Header einlesen und extern-Deklarationen ausgeben

Werkzeug-Qualifizierung (TOR)

Flag Beschreibung Verhalten
--version Versionsnummer (TOR-001) 2 Zeilen, Exit 0
--build-info Build-Identifikation (TOR-002) 5 Zeilen, Exit 0
--config Aktive Konfiguration (TOR-003) 4 Zeilen, Exit 0 (seit 1.0.20F, #1527)
--help Hilfe

Seit 1.0.20F arbeitet –config wie die beiden anderen TOR-Schalter: Exit 0, vier Zeilen, keine angehängte Hilfe (#1527). Vorher endete der Aufruf mit Exit 1 und gab 61 Zeilen aus — in einem Skript galt er damit als fehlgeschlagen.

 
Diese früher hier dokumentierten Flags gibt es nicht — sie brechen den Aufruf seit 1.0.15D mit lyxc: unbekannter Schalter und Exit 2 ab:

--stack-check, --wcet, --no-fp-fold, --inline-threshold, --lint-strict, --mcdc-instrument, --coverage-report, --integrity-check, --symbol-sizes, --emit-ir, --emit-map, --debug-level, --define / -D, --lib-path / -L, --link / -l, --static, --run-tests, --ast-json, --ast-json-pretty, --error-json.

Ersatz, soweit vorhanden: --stack-check braucht es nicht — die @stack_limit-Prüfung läuft immer und meldet etwa @stack_limit ist mit Rekursion nicht nachweisbar auch ohne Flag. Statt --emit-ir gibt es --dump-ir, statt --wcet das --call-graph, statt --stack-check das --static-analysis, statt --lint-strict das --lint, statt --mcdc-instrument das --mcdc. Für --emit-map steht --map-file bereit — es arbeitet seit 1.0.20A (#1370).

--no-libc-init steht nicht in dieser Liste — es wird angenommen, obwohl lyxc --help es nicht nennt.

8. Beispiel-Aufrufe

Typische Aufrufmuster:

A) Schneller Entwicklungs-Build

lyxc main.lyx -o main
./main

B) Debug-Build mit Stack-Trace

lyxc main.lyx --debug --no-opt -o main_dbg
./main_dbg
# Bei Absturz: vollständiger Stack-Trace mit Zeilennummern

C) Lint-Check für CI/CD

lyxc main.lyx --lint-only -we
# -we behandelt Warnungen als Fehler; Exit != 0 laesst die Pipeline scheitern

D) Cross-Compilation: ARM64 (Raspberry Pi / Server)

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

E) IoT-Build: ESP32 (Batterie-optimiert)

lyxc sensor.lyx \
    --target=esp32 \
    --target-energy=1 \
    --static-analysis \
    -o sensor.elf

F) Luftfahrt-Zertifizierung (DAL A)

Seit 1.0.20F genügt ein Aufruf: –provenance verändert das Erzeugnis nicht mehr (#1523), –map-file arbeitet seit 1.0.20A. –asm-listing legt seit 1.1.14B die Auflistung mit Quellzeilen als &lt;ausgabe&gt;.asm ab (#1862) — ein Griff zu objdump -d ist dafür nicht mehr nötig.

lyxc flight_control.lyx \
    --target=arm64 \
    --call-graph \
    --static-analysis \
    --verify-tmr \
    --runtime-checks \
    --lint \
    --mcdc-report \
    --provenance \
    --map-file \
    -o evidence/fcc.elf  > evidence/analyse.log 2>&1

Analysen, Traceability-Protokoll, Speicherkarte (evidence/fcc.elf.map) und Auslieferungsstand entstehen damit im selben Lauf — die frühere Lücke, dass geprüfte Artefakte und ausgeliefertes Programm aus verschiedenen Übersetzungen stammten, entfällt.

G) Energieprofil vergleichen

# Level 1: Batterie-optimiert
lyxc dsp.lyx --target-energy=1 -o dsp_low.elf

# Level 5: Maximum-Performance
lyxc dsp.lyx --target-energy=5 -o dsp_high.elf

# Größenvergleich
ls -l dsp_low.elf dsp_high.elf

Gemessen an einem kleinen Testprogramm über alle fünf Stufen:

Stufe 1:  33 107 Byte
Stufe 2:  49 491 Byte
Stufe 3:  94 547 Byte   (Vorgabe)
Stufe 4:  94 547 Byte   identisch mit Stufe 3
Stufe 5: 237 907 Byte

Der Faktor zwischen Stufe 1 und Stufe 5 beträgt hier gut sieben. Die absoluten Zahlen hängen vom Programm ab, das Verhältnis gibt aber die Größenordnung wieder.

H) Compiler-Performance analysieren

lyxc main.lyx --trace-passes -o main 2>&1 | grep "^\[pass\].*done"
# [pass] sema: done (1ms / 1337µs)   <- Dauer je Pass, langsamste zuerst sortierbar

I) Provenance-Log für Audit

lyxc main.lyx --provenance --target=arm64 -o /dev/null > audit/provenance.log

Ausgegeben wird eine Zuordnung von IR-Instruktionen über AST-Knoten zur Quellzeile:

=== PROVENANCE ===
IR[0] irLoadLocal  ->  AST[6] IF  ->  src:main.lyx:1
IR[1] irConstInt   ->  AST[6] IF  ->  src:main.lyx:1
IR[2] irCmpLe      ->  AST[6] IF  ->  src:main.lyx:1

<WRAP alert> Drei Dinge weichen von früheren Fassungen dieser Seite ab:

Seit 1.0.20F ist das dabei erzeugte Programm regulär lauffähig; -o /dev/null steht hier nur, weil allein das Protokoll gebraucht wird. </WRAP>


9. Kein --define / -D

lyxc kennt kein --define / -D-Flag für Präprozessor-Symbole, weil Lyx keinen Präprozessor hat. Die Alternativen:

C-Äquivalent Lyx-Weg
-DDEBUG=1 con DEBUG: bool := true; in einer Konfigurationsdatei oder Unit
-DMAX_SIZE=1024 con MAX_SIZE: int64 := 1024;
-DPLATFORM_ARM –target=arm64 + plattformspezifische Include-Pfade (–include)
#pragma once / Header Guards Nicht nötig — jede .lyx-Datei ist eine Unit mit eindeutigem Namen

→ Ausführlich: Bedingungen – Kein Präprozessor in Lyx (Abschnitt 7)


Weiterführende Seiten:

Letzte Aktualisierung: 2026-09-05 (#1647, nachgemessen mit lyxc 1.2.2B) — -O-Kasten präzisiert: -O0/--no-opt erzeugen inzwischen ein anderes Erzeugnis, -O1-O3 bleiben untereinander gleich.

Vorherige letzte Aktualisierung: 2026-08-31 — die drei Assembler-Schalter gegen 1.1.15B nachgemessen (#1862 geschlossen): –dump-asm schreibt nach stdout, –emit-asm die Datei ohne Quellzeilen, –asm-listing die Datei mit Quellzeilen. Zuvor am 2026-08-30 alle Schalter gegen 1.1.14A gemessen. Neu: Projektdatei *.lpf (eigene Seite). –emit-asm/–asm-listing/–dump-asm sind umgesetzt (#1370 geschlossen), ebenso –profile und –debug-symbols; –dump-relocs und –map-file arbeiten. Offen bleibt allein, dass die Optimierstufen untereinander byte-gleich sind (#1371).

Vorherige Aktualisierung: 2026-08-16 — alle Schalter gegen 1.0.20F neu gemessen (Byte-Vergleich, file, Lauf des Erzeugnisses). Von dreizehn zuvor defekten Schaltern sind elf in Ordnung: –dump-ir/–ir-source-map/–provenance liefern wieder ein lauffähiges Programm (#1523), –mcdc-report zählt Bedingungen richtig (#1524), –format und –arch wirken (#1526), –config endet mit Exit 0 (#1527). Offen: –mcdc instrumentiert nicht, –debug-symbols ohne Wirkung, -O1..-O3 untereinander gleich (#1371).