Ein Lyx-Programm ist eine einzelne, statisch gelinkte Datei ohne Laufzeitumgebung. Das macht das Ausliefern einfach — und verschiebt die Fragen: nicht „welche Bibliotheken müssen mit?„, sondern „für welches Ziel, mit welchen Rechten, und wie beweise ich, dass es dasselbe Binary ist?“.
→ Cross-Compilation · Capabilities · lpm
lyxc app.lyx -o app
file app
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked
Kein Interpreter, keine libc-Pflicht, kein Garbage Collector — die Datei läuft auf jedem Linux mit passender Architektur. Ein Hello-World liegt bei rund 100 KB, ein Programm mit Dateizugriff und Capabilities im Beispiel unten bei 206 KB.
Ausnahme: Wer extern fn … link „lib…so“ benutzt, verlangt diese Bibliothek auf dem Zielsystem. Das ist die einzige Abhängigkeit, die entstehen kann — und sie steht im Quelltext.
lyxc app.lyx -o app # Linux x86-64
lyxc app.lyx --target=win64 --format=pe -o app.exe # Windows
lyxc app.lyx --target=arm64 -o app_arm64
lyxc app.lyx --target=riscv -o app_riscv
lyxc app.lyx --target=macosx64 --format=macho -o app_mac
Alle Ziele entstehen aus derselben Quelle, ohne Cross-Toolchain. Die vollständige Liste samt Einschränkungen steht im Cross-Compilation-Guide; für Oberflächen kommt die Backendwahl über den Include-Pfad dazu (Vega: portabel bauen).
@capabilities([system.exit, system.memory.heap, fs.read])
import std.io;
import std.fs;
import std.alloc;
fn main(): int64 {
var buf: int64 := alloc(256);
var n: int64 := ReadFile("/etc/hostname", buf as pchar, 255);
if (n > 0) { PrintLn("gelesen"); } else { PrintLn("nicht lesbar"); }
free(buf, 256);
return 0;
}
Aus der Deklaration entsteht ein seccomp-Filter. Das Audit im Build zeigt, was daraus wurde:
Explizite Capabilities:
+ W^X (RX-Code / RW-Daten getrennt — zwei PT_LOAD)
+ RELRO (kein GOT/PLT-Angriffsziel — statisches ELF)
+ seccomp (SECCOMP_RET_KILL_PROCESS, 121 Regeln)
Sicherheits-Score: 35/35
Und der Filter greift wirklich. Dasselbe Programm ohne fs.read in der Liste:
vor dem Lesen
Ungültiger Betriebssystemaufruf (Speicherabzug geschrieben), rc=159
Der Prozess stirbt beim nicht deklarierten Syscall. Für die Fehlersuche macht –seccomp-trap daraus ein SIGSYS mit Syscall-Nummer, statt stumm zu töten.
Ohne @capabilities gibt es keinen Filter — das Audit sagt dann Capability-Modell: NONE. Für ein ausgeliefertes Programm ist die Liste deshalb Pflichtprogramm, nicht Kür.
lyx.lock einchecken und mit lpm install –offline bauen — ein Bau, der aus dem Netz nachlädt, ist nicht wiederholbar.lyxc –version) — sie gehört ins Build-Protokoll wie die Quellversion.| Fall | Mitliefern |
|---|---|
| Reines Rechenprogramm | nur die Datei |
extern fn … link „libfoo.so“ | die Bibliothek muss auf dem Ziel vorhanden sein |
| Vega-Anwendung | nichts zusätzlich — X11 bzw. Win32 stellt das System |
Eigene Themes (.vtheme) oder Formulare (.lfm) | die Dateien, relativ zum Arbeitsverzeichnis |
| Daten, die zur Laufzeit gelesen werden | dieselbe Überlegung — und die passende Capability |
lyxc –version notieren, lpm install –offline, Bau aus sauberem Stand.seccomp dort? Ist der Score, was er sein soll?file auf das Ergebnis: richtiges Format, richtige Architektur, statically linked.system.unsafe.* hebt den Sinn der Übung auf.–target vergessen. Ein ELF auf einem Windows-Ziel fällt sofort auf, ein x86-64-Binary auf ARM erst beim Kunden.
Letzte Aktualisierung: 2026-08-19 — Beispiel, Audit-Ausgabe und die Wirkung des seccomp-Filters mit lyxc 1.1.3I nachgemessen.