Phase 6: P-Code-Bibliotheken und Linker abschließen, Cross-Buildplan festhalten
This commit is contained in:
159
docs/pcode-bibliotheken.md
Normal file
159
docs/pcode-bibliotheken.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# P-Code-Bibliotheken und Linker
|
||||
|
||||
Eine `.tbl` enthält übersetzte BASIC-Module mit Deklarationen, typisierten
|
||||
Imports, COMMON-Verträgen, DATA, Forms-Anfangsdaten und Quellpositionen. Sie
|
||||
enthält weder BASIC-Programmrümpfe als Quelltext noch native Runtime oder
|
||||
Maschinencode. Dieselben Bytes sind für Windows amd64, macOS arm64 und Linux
|
||||
amd64/arm64 vorgesehen. Der Verbraucher braucht die Bibliotheksquellen nicht.
|
||||
|
||||
## Befehle
|
||||
|
||||
```text
|
||||
tbc build library.mak --library --output library.tbl
|
||||
tbc link app.mak library.tbl --output app.tbc
|
||||
tbc link app.mak library.tbl --exe --target aarch64-apple-darwin --output app
|
||||
```
|
||||
|
||||
`build --library` akzeptiert BAS, FRM oder MAK sowie zusätzliche TBL-Eingaben.
|
||||
Ohne `--output` entsteht eine gleichnamige `.tbl`. Alle angegebenen Module,
|
||||
einschließlich eingebundener Bibliotheken, werden in Reihenfolge übernommen;
|
||||
Abhängigkeiten werden flach mitgegeben, ohne automatische Paketsuche.
|
||||
|
||||
`link` benötigt ein BASIC-/Form-Hauptmodul oder ein entsprechendes MAK-Projekt.
|
||||
Zusätzliche Argumente müssen TBL-Dateien sein. Ohne `--exe` entsteht ein
|
||||
vollständig verknüpftes `.tbc`, standardmäßig neben dem Hauptprojekt. Ein
|
||||
fertiges TBC kann ausschließlich mit `tbc link app.tbc --exe` verpackt werden;
|
||||
weitere TBL-Dateien sind dabei unzulässig, da das TBC bereits aufgelöst ist.
|
||||
|
||||
`--library` und `--exe` schließen sich aus. `--target` und `--template` sind
|
||||
EXE-Optionen. TBL-/Link-/EXE-Ausgaben überschreiben vorhandene Ziele nur mit
|
||||
`--force`. Eingaben, Includes, MAK- und TBL-Dateien bleiben auch dann geschützt.
|
||||
`build app.mak`, `run app.mak` und `check app.mak` verwenden denselben Resolver.
|
||||
Beim erneuten `build` eines MAK mit TBL-Mitgliedern ist ebenfalls `--force`
|
||||
zum Ersetzen nötig. Der bisherige Aufruf `build source.bas` bleibt eine
|
||||
TBC-Übersetzung; reine Quellprojekte behalten ihre Standardausgabe.
|
||||
|
||||
Für TBL und TBC genügen die ausgelieferten TB-Werkzeuge. Ein C-/Rust-Compiler
|
||||
oder nativer Linker wird beim Anwender nicht aufgerufen. Für EXE gilt der
|
||||
[Runtime-Vorlagenvertrag](native-executables.md): passende vorgebaute
|
||||
`runtimes/<Triple>/tbrt[.exe]` mit Metadaten oder ausdrücklich `--template`;
|
||||
auf macOS die dort beschriebene System-Signierung. Eine fehlende, falsche oder
|
||||
inkompatible Vorlage liefert eine Diagnose und kein fertiges Executable.
|
||||
|
||||
## Projektmitglieder, Auflösung und Initialisierung
|
||||
|
||||
Beispiel `app.mak`:
|
||||
|
||||
```text
|
||||
' $STARTUP: "main.bas"
|
||||
main.bas
|
||||
lib/common.tbl
|
||||
last.bas
|
||||
```
|
||||
|
||||
MAK-Pfade sind relativ zur MAK-Datei und werden wie bisher ohne Beachtung der
|
||||
Groß-/Kleinschreibung aufgelöst. Eine TBL wird an ihrer Position in ihre
|
||||
Modulreihenfolge aufgefächert. Zusätzliche CLI-Bibliotheken folgen danach.
|
||||
Das gewählte Quell-Startmodul steht zuerst; ohne explizite Wahl ist es das
|
||||
erste Quellmitglied. Eine TBL ist weder Textdokument noch Startdatei. Die
|
||||
Form-Startauswahl gehört dem Verbraucher; eine Bibliothek speichert keine
|
||||
aktive Startform. Reine Forms-Projekte behalten ihren bisherigen Startvertrag.
|
||||
|
||||
Alle globalen Anfangswerte und Array-Initialisierungen stehen vor den
|
||||
Modulrümpfen bereit. Die Rümpfe folgen der erweiterten Projektreihenfolge mit
|
||||
dem normalen BASIC-Kontrollfluss: ein `END` im Hauptmodul beendet auch das
|
||||
Gesamtprogramm. Ein Prozeduraufruf führt keinen zusätzlichen Modulrumpf aus.
|
||||
`RUN` ohne Ziel erzeugt die gesamte Runtime einschließlich Bibliotheksvariablen,
|
||||
DATA-Zeiger, Forms und Textbildschirm erneut. Gespeicherte physische Quellorte
|
||||
und BASIC-Zeilenlabels bleiben für Laufzeitfehler verfügbar.
|
||||
|
||||
Die vorhandene Sichtbarkeit gilt: lokale Definitionen gewinnen, fremde
|
||||
Prozeduren müssen eindeutig sein, Konstanten und TYPE-Deklarationen werden
|
||||
vor der Verbraucher-Semantikanalyse importiert. Prozedurparameter und
|
||||
Ergebnisse werden nach dem UDT-Remapping geprüft; COMMON wird nur bei
|
||||
kompatiblen Typen und Array-Grenzen geteilt. Offene `DECLARE`-Imports dürfen in
|
||||
einer TBL verbleiben, müssen aber im ausführbaren Endprodukt aufgelöst sein.
|
||||
Nicht aufgerufene reine DECLARE-Prototypen sind keine Imports und werden aus
|
||||
dem Endprodukt entfernt; Aufrufe in mitgelieferten Prozedurrümpfen müssen auch
|
||||
dann auflösbar sein, wenn diese Prozedur noch nicht aufgerufen wird. Die bereits
|
||||
vorhandenen nativen Runtime-Dialogfunktionen bleiben Runtime-Imports.
|
||||
Doppelte Modulidentitäten, etwa durch überlappende flache Bibliotheken, sind
|
||||
Fehler. Bibliotheksdateien werden bei jedem Build nach ihrem tatsächlichen
|
||||
Inhalt gelesen; gleiche Dateigröße oder Zeitstempel können alte Deklarationen
|
||||
oder alten Code nicht im Ergebnis festhalten.
|
||||
|
||||
## TBL-Version 1
|
||||
|
||||
Alle Ganzzahlen sind Little Endian und haben feste Breiten; Zeichenketten sind
|
||||
UTF-8 mit `u32`-Byteanzahl. Es werden keine Rust-Structlayouts serialisiert.
|
||||
|
||||
| Feld | Darstellung |
|
||||
|---|---|
|
||||
| Magic | vier Bytes `TBL\0` |
|
||||
| TBL-Version | `u16`, aktuell 1 |
|
||||
| P-Code-Version | `u16`, aktuell TBC 4 |
|
||||
| Runtime-Vertragsversion | `u32`, aktuell 1; gemeinsam mit EXE-Vorlagen |
|
||||
| Modulanzahl | `u32`, 1 bis 65535 |
|
||||
| Module | je `u32`-Abschnittslänge und Abschnittsbytes |
|
||||
| Prüfsumme | `u64` FNV-1a über alle vorherigen Bytes; erkennt Beschädigung, authentisiert keine Herkunft |
|
||||
|
||||
Ein Modulabschnitt enthält in dieser Reihenfolge:
|
||||
|
||||
1. Modulname und Quellposition (`source`, `line`, `column`, jeweils `u32`).
|
||||
2. Exportdeklarationen mit `u32`-Anzahl: Prozedur (Tag 0), TYPE (Tag 1),
|
||||
aufgelöste Konstante (Tag 2). Jede Deklaration hat eine Quellposition.
|
||||
Prozeduren speichern Art, Name, Suffix und Parameter mit Name, Suffix,
|
||||
Array-Markierung und optionalem Typ. TYPE speichert Namen und geordnete
|
||||
Felder. Konstanten speichern Name, Suffix und gefaltetes `f64` oder String.
|
||||
3. Deklarationsorte (Name/Position) und Namen tatsächlich definierter
|
||||
Prozeduren, jeweils mit `u32`-Anzahl. Die übrigen typisierten Prozedurzeilen
|
||||
im Modulprodukt sind Imports. Es werden keine vollständigen ASTs gespeichert.
|
||||
4. COMMON-Zeilen mit Slot (`u16`), optionalem Blocknamen, Schlüssel,
|
||||
HIR-Typ, Position und optionalen Array-Grenzen (`i32`, einzeln optional).
|
||||
5. `u32`-Länge und Bytecode-Produkt mit dem bestehenden TBC-Codec. Dieses
|
||||
Produkt ist **unverknüpft** und auf genau ein Modul begrenzt: eigene
|
||||
Quell-IDs, Typen, Globals, Prozeduren, Strings, DATA, Sprungtabellen,
|
||||
Objektkatalog, Ereignisse und eigene Forms-Anfangswerte. Es ist kein
|
||||
umbenanntes fertiges Projekt-TBC.
|
||||
|
||||
Optionen und Booleans sind strikt 0/1; Suffixe sind 0 oder das ASCII-Zeichen
|
||||
`%`, `&`, `!`, `#`, `$`, `@`. Typ-Tags 0–9 stehen für INTEGER, LONG, SINGLE,
|
||||
DOUBLE, CURRENCY, STRING, festen STRING (`i64` Länge), FORM, CONTROL und TYPE
|
||||
(UTF-8-Name). Konstantenwert-Tags sind 0 (`f64`) und 1 (String).
|
||||
|
||||
Der Leser prüft Prüfsumme, Versionen, Abschnittsgrenzen, Restbytes, Tags,
|
||||
Tabellen- und Symbolreferenzen, Export-/Bytecode-Signaturen, COMMON sowie
|
||||
Forms-Anfangsdaten vor der Weitergabe. Der Linker prüft auch die vereinigten
|
||||
Tabellengrenzen und remappt alle Typ-, Global-, Prozedur-, String-, DATA-,
|
||||
Sprung-, Objekt-, Ereignis- und Quellreferenzen. Veröffentlichungen verwenden
|
||||
die gemeinsame temporäre Datei mit erneuter Validierung, Abbruchprüfung und
|
||||
atomarer Freigabe. Fehler erhalten vorhandene Ziele und Eingaben.
|
||||
|
||||
## Reproduzierbare Abnahme und Übergabe
|
||||
|
||||
`tests/libraries/portable.tbl` ist das gemeinsame unveränderte TBL-Artefakt.
|
||||
Seine SHA-256 lautet
|
||||
`5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df`.
|
||||
`portable.bas` dokumentiert den einmaligen Ursprung; die Verbraucherprobe
|
||||
liest oder übersetzt diese Quelle nicht.
|
||||
|
||||
```text
|
||||
python3 tests/support/library-abnahme.py --bin-dir target/release
|
||||
```
|
||||
|
||||
Auf jedem echten Ziel werden dieselben TBL-Bytes geprüft, ein separater
|
||||
Verbraucher zu TBC und EXE verknüpft und nach Entfernen von Quellen, TBL, TBC
|
||||
und Runtime-Vorlage das Executable mit leerem PATH ausgeführt. Resultate,
|
||||
Dateieffekt und Neustart durch `RUN` werden geprüft. Die JSON-Ausgabe nennt
|
||||
Host-Target, Prüfsumme und Ergebnis. Ein Cross-Compile ersetzt diesen Lauf
|
||||
nicht. Die vier JSON-Nachweise gehören in die Plattform-/Gitea-Abnahme.
|
||||
|
||||
IDE-Change 04 kann `ProjectSources::compile_library`, `compile` und
|
||||
`protected_inputs` sowie `ProjectCompiler::link_library` nutzen. Er ergänzt
|
||||
das IDE-Dokumentmodell für nicht editierbare TBL-Mitglieder und verbindet
|
||||
Make Library/Make EXE mit derselben Veröffentlichung; die UI ist Teil von 04.
|
||||
Change 05 führt den identischen Verbrauchercheck auf allen vier echten
|
||||
Zielsystemen aus. Change 06 baut die vier nativen Compiler-/Runtime-Pakete
|
||||
zentral auf dem Linux-arm64-Gitea-Runner per Cross-Kompilierung und bindet
|
||||
die echten Verbraucherprüfungen für die entpackten Pakete an Revision und
|
||||
Paketprüfsumme. Vier native Buildrunner sind dafür nicht erforderlich.
|
||||
Reference in New Issue
Block a user