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 --static-analysis --lint -o firmware.elf
Flags können in beliebiger Reihenfolge angegeben werden. Kurzformen (‑o) und Langformen (--output) sind gleichwertig, wo beide existieren.
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,-Osafeund--no-optliefern an demselben Programm byte-gleiche Erzeugnisse (4243 Byte in allen sechs Läufen). Die Stufen sind untereinander nicht unterscheidbar (#1371).
--mcdcbaut 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-symbolswirkt (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.
| 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. 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=<fmt> | – | Ausgabeformat: elf, pe, macho — seit 1.0.20F wirken alle drei (#1526) |
--output-type=<typ> | – | 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 <ausgabe>.map (seit 1.0.20A, #1370) |
Es gibt keine Linker-Flags.--lib-path/-L,--link/-lund--staticexistieren nicht —lyxcerzeugt statische ELF-Dateien und bindet C-Bibliotheken überextern fn … link „libfoo.so“im Quelltext ein (→ FFI).--no-libc-initwird dagegen angenommen, obwohl es inlyxc --helpnicht auftaucht.
# 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
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-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.
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=xtensaabgewiesen, 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,arm64undriscv64arbeiten korrekt und liefern jeweils das passende ELF.
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.
Energy-Awareness-Annotationen und Compiler-Optimierungen:
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 |
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 -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
-O0und--no-optunterscheiden sich inzwischen vom Rest (#1647, nachgemessen mit lyxc 1.2.2B): sie erzeugen ein anderes Erzeugnis als der Aufruf ohne Schalter.-O1,-O2und-O3liefern 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-O0abschalten lässt — plus-Osafeals eigene, vorsichtigere Fassung.--helpnennt-O2als Standard.
-Osafegibt es inzwischen (#1525, nachgemessen mit lyxc 1.2.2D): der Schalter wird angenommen, steht in--helpund erzeugt ein drittes, von-O0und-O1…-O3verschiedenes 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-foldund--inline-thresholdgibt es nicht. Wer Fließkomma-Umordnung unterbinden will, annotiert die betroffene Funktion mit@flight_crit(→ Attribute); die Inline-Grenze ist nicht einstellbar.
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 |
--mcdc-reportzä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.
--mcdcbaut 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.
@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-reportund--run-testsexistieren 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.
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.
| 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 |
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.
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.
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 mitunbekannter Schalterund Exit 2 ab. Die Bausteine liegen im Repository (src/backend/ast_json.lyx,src/error_collector.lyx), sind aber insrc/lyxc.lyxan keine Kommandozeile angeschlossen — auch nicht aufdevelop(1.0.16A).
Das dokumentierte JSON-Schema bleibt gültig: KI-Integration — Datenformat und interne API.
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) |
| 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
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).
| Flag | Beschreibung |
|---|---|
-o <datei> | Ausgabedatei (Standard: a.out) |
-I <pfad> | 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=<fmt> | Ausgabeformat: elf, pe, macho |
--output-type=<typ> | executable (Standard) oder shared-lib |
--shared | Kurzform für --output-type=shared-lib |
| 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=<typ>'' / ''--shared | executable oder shared-lib; beide arbeiten korrekt |
| 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 |
| 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 |
| 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 <ausgabe>.asm — umgesetzt seit 1.1.12D, in der Datei statt auf stdout seit 1.1.14B (#1862) |
--map-file | Symbol- und Sektionskarte als <ausgabe>.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 |
| 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 <ausgabe>.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 |
| 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 <datei> | Informationen über eine .lyu anzeigen |
--include <hdr.h> | C-Header einlesen und extern-Deklarationen ausgeben |
| 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 mitlyxc: unbekannter Schalterund 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-checkbraucht es nicht — die@stack_limit-Prüfung läuft immer und meldet etwa@stack_limit ist mit Rekursion nicht nachweisbarauch ohne Flag. Statt--emit-irgibt es--dump-ir, statt--wcetdas--call-graph, statt--stack-checkdas--static-analysis, statt--lint-strictdas--lint, statt--mcdc-instrumentdas--mcdc. Für--emit-mapsteht--map-filebereit — es arbeitet seit 1.0.20A (#1370).
--no-libc-initsteht nicht in dieser Liste — es wird angenommen, obwohllyxc --helpes nicht nennt.
Typische Aufrufmuster:
lyxc main.lyx -o main
./main
lyxc main.lyx --debug --no-opt -o main_dbg
./main_dbg
# Bei Absturz: vollständiger Stack-Trace mit Zeilennummern
lyxc main.lyx --lint-only -we
# -we behandelt Warnungen als Fehler; Exit != 0 laesst die Pipeline scheitern
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-analysis \
-o sensor.elf
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 <ausgabe>.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.
# 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.
lyxc main.lyx --trace-passes -o main 2>&1 | grep "^\[pass\].*done"
# [pass] sema: done (1ms / 1337µs) <- Dauer je Pass, langsamste zuerst sortierbar
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:
.prov-Datei. Die Ausgabe geht ausschließlich nach stdout und muss umgeleitet werden.--build-info.
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>
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).