====== Vega — Portabel bauen ====== Ein Quelltext, drei Ziele: X11 unter Linux, Win32 unter Windows, Ring-3 unter Lyx OS. Der Unterschied steht **nicht** im Programm, sondern im Include-Pfad des Übersetzungsaufrufs. → [[lyx_-_programmiersprache:vega:guides|Vega-Guides]] · [[lyx_-_programmiersprache:vega:backends|Backends]] · [[lyx_-_programmiersprache:vega:bauen|Bauen und Testen]] · [[lyx_-_programmiersprache:guides:crosscompiling|Cross-Compilation]] ---- ===== Der Trick: eine Unit, dreimal vorhanden ===== ''Vega.BackendAuto'' liegt je einmal unter ''platform/linux'', ''platform/win64'' und ''platform/lyxos''. Alle drei exportieren dieselbe Funktion: pub fn NewPlatformBackend(): IVegaBackend Welche gebunden wird, entscheidet die **letzte** ''-I''-Angabe — deshalb steht der Plattformpfad hinter dem Projektpfad. lyxc app.lyx -I . -I platform/linux -o app # X11 lyxc app.lyx -I . -I platform/win64 --target=win64 --format=pe -o app.exe # Win32 lyxc app.lyx -I . -I platform/lyxos -o app.elf # Lyx OS > **Der Bau für Lyx OS läuft //noch// ohne ''%%--target=lyxos%%'' — die Gründe dafür sind aber weg.** > > Das native Zielformat von Lyx OS ist ''LYX!'', der Maschinencode-Container des LX-34-Loaders; ''%%--target=lyxos%%'' erzeugt ihn (Magic ''4C 59 58 21''). ELF wird von Lyx OS nur **weiterhin mitgeladen**. > > Was Vega an diesem Ziel bislang gehindert hat, ist mit ''lyxc 1.1.4D'' erledigt und mit **1.1.11B nachgemessen**: ''alloc''/''free'' übersetzen ([[https://github.com/SEOLizer/LyX-Compiler/issues/1718|#1718]] — die eigene ''platform/lyxos/Vega/Mem.lyx'' über ''mmap'' ist damit kein Zwang mehr), die stdlib-Importe tragen wieder ([[https://github.com/SEOLizer/LyX-Compiler/issues/1717|#1717]]: ''std.fs'' mit ''FileExists'', ''std.io'' mit ''StrNew''), die Builtin-IDs 3 und 6–15 sind im Backend belegt ([[https://github.com/SEOLizer/LyX-Compiler/issues/1715|#1715]]), und ''Print''/''PrintLn'' nehmen Variable, Zahl, Ausdruck und Funktionsaufruf ([[https://github.com/SEOLizer/LyX-Compiler/issues/1716|#1716]]). Ein Programm mit allen dreien baut zum ''LYX!''-Container durch. > > Offen ist damit nur noch die Umstellung des Vega-Baus selbst — ''%%--target=lyxos%%'' ist der Weg, der ELF-Weg der Übergang. ---- ===== Warum keine Fallunterscheidung im Code ===== ''TARGET_OS'' gibt es (1 = Linux, 3 = Windows), und es ändert sich mit ''--target''. Für die Backendwahl reicht es trotzdem nicht: Beide Zweige müssten übersetzt **und** gebunden werden, und ''extern''-Deklarationen sind harte Abhängigkeiten — auch in einem Zweig, der nie läuft. Eine Linux-Binary mit eingebundenem Win32-Backend verlangt beim Start ''kernel32.dll'' und startet gar nicht erst. Deshalb die Trennung über den Pfad. Es ist dasselbe Verfahren, mit dem Lazarus seine Widgetsets auswählt. ---- ===== Beispiel ===== Dieses Programm ist unverändert für alle drei Ziele übersetzbar: unit Main; import std.io; import vega.types; import vega.events; import vega.canvas; import vega.theme; import vega.control; import vega.font; import vega.strings; import vega.lists; import vega.style; import vega.stdctrls; import vega.backend; // Diese Unit gibt es dreimal — unter platform/linux, platform/win64 und // platform/lyxos. Welche gilt, entscheidet der Include-Pfad, nicht der Code. import vega.backendauto; import vega.forms; var g_app: TApplication; var g_stand: TLabel; var g_zaehler: int64; fn OnZaehl(sender: TControl): void { g_zaehler := g_zaehler + 1; g_stand.SetCaption(StrConcat("Geklickt: ", IntToStr(g_zaehler))); } fn OnBeenden(sender: TControl): void { g_app.Terminate(); } fn main(): int64 { g_app := new TApplication(NewPlatformBackend()); if (!g_app.Ready) { PrintLn("Kein Fenstersystem erreichbar."); return 1; } var f: TForm := new TForm(320, 160, "Portabel"); g_zaehler := 0; g_stand := new TLabel("Geklickt: 0"); g_stand.SetBounds(16, 16, 280, 18); g_stand.SetParent(f); var b1: TButton := new TButton("Zaehlen"); b1.SetBounds(16, 56, 130, 28); b1.OnClick := OnZaehl; b1.SetParent(f); var b2: TButton := new TButton("Beenden"); b2.SetBounds(166, 56, 130, 28); b2.OnClick := OnBeenden; b2.SetParent(f); if (!g_app.ShowForm(f)) { return 2; } g_app.Run(); g_app.Shutdown(); return 0; } Nachgemessen mit ''lyxc 1.1.3I'' — dieselbe Datei, drei Aufrufe: ^ Ziel ^ Aufruf ^ Ergebnis ^ | Linux/X11 | ''-I . -I platform/linux'' | ELF 64-bit, 787 KB | | Windows | ''-I . -I platform/win64 %%--target=win64 --format=pe%%'' | PE32+ x86-64, 803 KB | | Lyx OS | ''-I . -I platform/lyxos'' | ELF 64-bit statisch, 764 KB | Die PE-Datei wurde zusätzlich unter Wine gestartet und zeigt ihr Fenster. ---- ===== Was portabel ist und was nicht ===== ^ Portabel ^ Nicht portabel ^ | Alles aus ''Vega.*'' — Controls, Layout, Themes, LFM | Direkte ''extern''-Aufrufe in Systembibliotheken | | Zeichnen, Schriften, Ereignisse | Pfade mit ''/'' oder ''\\'' fest im Code | | ''std''-Units ohne Systembezug | Annahmen über Zeilenenden oder Dateirechte | Die HAL ist bewusst klein — 21 Methoden. Alles darüber ist geteilter Code und läuft überall gleich; genau deshalb ist sie ein Interface. ---- ===== Bauen mit Skript ===== Im Repository nimmt ''build.sh'' die Unterscheidung über den Dateinamen ab: ein Beispiel ''name_win'' wird als PE gebaut, ''name_lyxos'' für Lyx OS, alles andere für X11. Für ein eigenes Projekt genügt dasselbe Muster — drei Aufrufe, ein Quelltext. ---- ===== Fallstricke ===== * **Plattformpfad vor dem Projektpfad.** Die letzte ''-I''-Angabe gewinnt; steht ''platform/linux'' zuerst, greift sie nicht. * **''--target=win64'' ohne ''platform/win64''.** Dann wird das X11-Backend in eine PE-Datei gebunden — sie startet, findet aber kein Fenstersystem. * **''--target=lyxos'' benutzt, solange die Builtins fehlen.** Der Bau bricht bei der ersten ''alloc''- oder ''std.fs''-Stelle ab; siehe Kasten. Es ist das künftige, noch nicht das gangbare Ziel. * **Backend direkt importiert.** ''import vega.backend.x11'' bindet fest an X11; portable Programme nehmen ''vega.backendauto''. Letzte Aktualisierung: 2026-08-20 — drei Ziele mit ''lyxc 1.1.3I'' aus derselben Datei gebaut und mit ''file'' geprüft; der Lyx-OS-Abschnitt am 2026-08-27 gegen ''lyxc 1.1.11B'' neu nachgemessen — ''alloc''/''free'', ''std.io'', ''std.fs'' und ''Print(variable)'' bauen dort jetzt zum ''LYX!''-Container durch (#1715, #1716, #1717, #1718 behoben). Codebeispiele geprüft: gegen **lyxc 1.2.5C** übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die ''pub fn''-Signaturen in ''aurum/std'' gehalten, 0 Abweichungen).