Werkzeuge
Programme weitergeben mit antra pack
Dein Spiel oder Werkzeug läuft — jetzt sollen es andere benutzen, ohne Antra
zu installieren. antra pack legt alles, was dein Programm braucht, in einen
Ordner und packt ihn als Zip (Windows) oder .tar.gz (macOS, Linux): antra
selbst unter dem Namen deines Programms, die Standardbibliothek, deine
Skripte und Assets und die C-Bibliotheken aus native.and. Der Empfänger
entpackt und startet — fertig.
Das Besondere: Du baust die Pakete für alle Systeme von einem Rechner aus. Unter macOS entsteht genauso ein Windows-Zip wie unter Linux ein macOS-Archiv.
Kurz: ein Kommando#
Im Ordner deines Projekts:
antra pack breakout.ant --target windows-x86_64,linux-x86_64,macos-aarch64Ergebnis:
dist/breakout-windows-x86_64.zip
dist/breakout-linux-x86_64.tar.gz
dist/breakout-macos-aarch64.tar.gzOhne --target packt antra pack für das System, auf dem du gerade
arbeitest; --target all für alle sechs. Heißt dein Hauptskript main.ant
oder gibt es im Ordner nur ein Skript, kannst du den Namen weglassen.
Was im Paket steckt#
breakout-windows-x86_64/
breakout.exe antra unter dem Namen deines Programms
antra-app.txt sagt breakout.exe, welches Skript es startet
lib/Antra/ die Standardbibliothek
app/ dein Projekt: Skripte, Assets, eigenes lib/
app/native/windows-x86_64/raylib.dll die C-Bibliotheken für dieses System
licenses/ Lizenzhinweise von antra und den Bibliothekenbreakout.exe ist das ganz normale antra-Programm. Findet es neben sich eine
antra-app.txt, startet es das dort genannte Skript und gibt ihm alle
Argumente weiter — auch solche wie --version, die antra sonst selbst
auswerten würde. Doppelklick, Startmenü-Verknüpfung und Aufruf aus dem
Terminal funktionieren gleich.
In app/ landet dein Projektordner, ohne:
- versteckte Dateien und Ordner (
.git,.vscode, …), dist/(die Pakete selbst) undapp.and,native/— von dort kommen nur die Bibliotheken des Zielsystems mit,- was du in
app.andunterexcludenennst (siehe unten), - Skripte, die das Programm nicht braucht.
Von den .ant-Dateien kommen nur das Hauptskript und die Pakete mit, die es
importiert, auch über andere Pakete hinweg (aus seinem Ordner, dessen lib/
und dem lib/ des Projekts). Ein Ordner, in dem danach nichts mehr liegt,
fällt weg. Alle anderen Dateien (Bilder, Sounds, Daten) kommen mit, denn ob
ein Programm sie liest, lässt sich nicht erkennen. Liegt das Hauptskript in
einem Ordner mit vielen anderen Programmen, gehört es deshalb in einen eigenen
Projektordner.
Startet dein Programm weitere Skripte erst zur Laufzeit (etwa über
Process), nenne sie oder ihren Ordner unter include; all_scripts: true
nimmt wieder alle Skripte mit.
Für andere Systeme packen#
Für ein fremdes System braucht pack das antra dieses Systems. Es lädt es
aus dem antra-Release derselben Version, die du gerade benutzt, und legt
es im Cache ab (ANTRA_CACHE, wie bei antra native). Eine selbst gebaute
Entwicklerversion (antra --version zeigt dev) nimmt das neueste Release.
Ohne Internet oder mit einem eigenen Build gibst du das antra pro System selbst an — ein Release-Archiv (Pfad oder URL) oder einen entpackten Ordner:
antra pack --target windows-x86_64 --runtime windows-x86_64=~/Downloads/antra-windows-x86_64.zipANTRA_RELEASE_URL (mit {platform} und {ext}, wie bei antra self update) verlegt alle Downloads auf einen eigenen Server.
C-Bibliotheken aus native.and#
Nutzt dein Programm Pakete wie Antra::Raylib, Antra::SDL oder
Antra::SQLite, listet eine native.and die C-Bibliotheken dazu — dieselbe
Datei, mit der du beim Entwickeln antra native install aufrufst (Format und
eigene Rezepte: 22-native-bibliotheken.md):
# native Bibliotheken für das Spiel
%{raylib: "6.2"}pack sucht sie im Ordner des Hauptskripts (neben app.and), nicht wie
antra native auch in den Ordnern darüber. Liegt dort keine, packt pack
keine Bibliotheken ein.
Für jedes Zielsystem installiert pack die Bibliotheken selbst
(antra native install --target …, mit Cache), du musst vorher nichts tun.
Ins Paket kommen dann nur die Dateien dieses Systems, nach
app/native/<system>/, wo Antra::FFI sie beim Start findet; ihre
Lizenztexte stehen in licenses/native-libraries.txt. Den eigenen
native/-Ordner deines Projekts mit den Bibliotheken aller Systeme nimmt
pack dagegen nie mit.
Zwei Fälle landen nicht im Paket:
- Bibliotheken vom System: Wo ein Rezept keinen Download hat, sondern auf
ein Systempaket verweist (
sdl2undsqliteunter Linux und macOS), meldetpacknot bundled — comes from the system. Der Empfänger muss sie selbst installieren (sudo apt install libsdl2-2.0-0,brew install sdl2), sofern das System sie nicht schon mitbringt wie SQLite unter macOS — schreib das in deineREADME.txt. linux-x86_64-musl: Dieses statische antra kann keine C-Bibliotheken laden;packlässt sie dort weg und sagt das.
Eine macOS-App zum Doppelklicken#
Mit macos_app: true in app.and (oder --macos-app) wird aus jedem
macOS-Ziel ein richtiges .app-Bundle, wie es der Finder erwartet:
Doppelklick startet es, im Dock erscheint dein Icon. Auch das geht von jedem
System aus.
Breakout.app/Contents/
Info.plist Name, Bundle-ID, Version, Icon
MacOS/breakout antra, daneben antra-app.txt
Resources/ lib/Antra/, app/, licenses/, breakout.icns%Packer{name: "breakout", version: "1.0", macos_app: true,
display_name: "Breakout", bundle_id: "org.example.breakout",
icon: "icon.png"}display_nameist der Name im Finder und im Dock (Standard:name).bundle_idist die eindeutige Kennung (CFBundleIdentifier); nimm eine umgekehrte Domain, die dir gehört. Standard:org.antra.app.<name>.iconist ein quadratisches PNG mit 16, 32, 64, 128, 256, 512 oder 1024 Pixeln, eine Liste solcher PNGs oder eine fertige.icns-Datei. Am besten ein 1024er-PNG, macOS skaliert es selbst.
Ein Programm, das per Doppelklick startet, hat kein Terminal. Ausgaben mit
println und Fehlermeldungen schreibt es deshalb nach
~/Library/Logs/<name>.log (in der App Konsole unter Protokollberichte
zu sehen). Startest du Breakout.app/Contents/MacOS/breakout im Terminal,
bleibt die Ausgabe dort.
Packst du auf einem Mac, signiert pack das Bundle ad hoc
(codesign --sign -). Das ist keine Beglaubigung durch Apple, sorgt aber
dafür, dass macOS das Programm nicht als „beschädigt“ ablehnt. Von Linux oder
Windows aus bleibt es unsigniert (pack sagt das); der Empfänger muss dann
auf jeden Fall das Quarantäne-Attribut entfernen (siehe unten).
Startet das Programm aus Downloads/, verschiebt macOS es beim Start an
einen zufälligen, schreibgeschützten Ort (App Translocation). Lesen der
eigenen Dateien geht weiter, Schreiben dort nicht: Spielstände und
Einstellungen gehören nach ~/Library/Application Support/<name>/.
Ein Bundle braucht ein antra, das Contents/Resources/lib kennt. Ist das
Release für ein anderes System älter, bricht pack mit too old for macOS app bundles ab; nimm dann mit --runtime ein neueres.
Ein einziges Programm: --onefile#
Mit onefile: true in app.and (oder --onefile) besteht die App aus einer
einzigen Datei: antra, an das Skripte, Stdlib, Assets und Bibliotheken als
ein komprimiertes Paket angehängt sind. Der Empfänger sieht keinen Ordner
voller .ant-Dateien, sondern nur breakout.exe.
dist/breakout-windows-x86_64/
breakout.exe antra + angehängtes PaketBeim ersten Start packt das Programm seinen Inhalt in den Cache aus und läuft dann von dort, wie eine normale gepackte App:
- Windows:
%LOCALAPPDATA%\antra\cache\apps\<hash>\ - Linux/macOS:
$XDG_CACHE_HOME/antra/apps/<hash>/, sonst~/.cache/antra/apps/<hash>/ ANTRA_CACHElegt den Ort fest, wie bei den nativen Bibliotheken.
Der Hash hängt am Inhalt: Jede neue Version bekommt ihren eigenen Ordner, spätere Starts derselben Version packen nichts mehr aus. Alte Versionen bleiben liegen, bis jemand den Ordner löscht.
Unter macOS würde ein angehängtes Paket die Code-Signatur ungültig machen.
Dort liegt es deshalb als eigene Datei app.pack neben dem Programm, in
einem Bundle unter Contents/Resources/app.pack. Zusammen mit
macos_app: true ist das die übliche Form: ein .app, in dem keine
Quelltexte offen liegen.
Was das Programm selbst schreibt, landet bei cwd: "main" im Cache-Ordner,
nicht neben der exe. Spielstände und Einstellungen gehören ohnehin in einen
festen Ort im Home-Verzeichnis. Eine README.txt im Projekt sieht der
Empfänger bei --onefile nicht; leg sie neben die exe ins Archiv.
Ein Onefile-Paket braucht ein antra, das das angehängte Paket sucht. Ist das
Release für ein anderes System älter, bricht pack mit too old for onefile apps ab.
Ein Disk-Image für den Mac: --dmg#
So installiert man Mac-Programme gewohnt: ein .dmg öffnen, im Fenster die App
auf den Ordner „Programme“ ziehen. --dmg baut genau das:
antra pack --dmgNeben dem Ordner liegt dann dist/breakout-1.0-macos-aarch64.dmg. Darin
stehen die App und eine Verknüpfung auf /Applications. --dmg schließt
--macos-app ein; in der antra.and heißt es pack: %{dmg: true}. Es
lässt sich mit --native und --onefile kombinieren.
Gebaut wird das Abbild mit hdiutil, das es nur auf dem Mac gibt; auf
anderen Systemen ist --dmg ein Fehler. Das Abbild selbst ist nicht signiert,
die App darin wie immer nur ad hoc
(oben): Auf einem fremden Mac fragt macOS
beim ersten Start nach.
Einstellungen in app.and#
Damit du nicht jedes Mal alle Optionen tippen musst, liest pack eine
app.and neben dem Hauptskript (AND-Format, # leitet Kommentare ein):
# antra pack: Breakout
%{name: "breakout",
main: "breakout.ant",
version: "1.0",
targets: ["windows-x86_64", "linux-x86_64", "macos-aarch64"],
exclude: ["tests", "*.psd", "docs/**"]}Statt %{...} geht auch %Packer{...} — dann sagt die Datei selbst, wofür
sie da ist. Mit einer Projektdatei antra.and
(Kapitel 21) stehen dieselben
Einstellungen dort unter pack:, name, version und main oben; eine
app.and daneben wird dann ignoriert. Dann reicht ein nacktes antra pack. Optionen auf der Kommandozeile gehen vor.
| Schlüssel | Bedeutung | Standard |
|---|---|---|
name | Programm- und Dateiname | Name des Hauptskripts |
main | Hauptskript, relativ zum Projekt | main.ant bzw. das einzige Skript |
version | steht im Ordner-/Archivnamen (breakout-1.0-…) | keine |
targets | Zielsysteme | dieses System |
out | Ausgabeordner | dist |
include | nur diese Einträge der obersten Ebene mitnehmen | alles |
exclude | diese Dateien/Ordner weglassen | nichts |
all_scripts | alle .ant-Dateien mitnehmen, nicht nur die importierten | false |
cwd | "main": das Programm startet im Ordner des Hauptskripts; "keep": im Ordner, aus dem es aufgerufen wird | "main" |
macos_app | macOS-Ziele als .app-Bundle (oben) | false |
display_name | Name des Bundles im Finder | name |
bundle_id | CFBundleIdentifier des Bundles | org.antra.app.<name> |
icon | PNG(s) oder .icns für das Bundle | keins |
onefile | eine einzige Datei (oben) | false |
dmg | macOS: zusätzlich ein Disk-Image (oben) | false |
native_build | das Programm nativ bauen (unten) | false |
Muster in include/exclude: * steht für beliebig viele Zeichen in einem
Namen, ** auch über Ordnergrenzen, ? für genau ein Zeichen. Ein Muster
passt auf den Pfad im Projekt (assets/raw) oder auf den bloßen Namen
(*.tmp).
Dateien des Programms finden#
Mit cwd: "main" (Standard) läuft dein gepacktes Programm im Ordner seines
Hauptskripts. Relative Pfade wie "resources/ball.png" funktionieren also
genau wie beim Entwickeln mit antra breakout.ant — egal, ob der Nutzer
doppelklickt oder es aus einem anderen Ordner aufruft.
Für Kommandozeilenwerkzeuge, die Dateinamen als Argumente bekommen, ist
cwd: "keep" richtig: dann meint meintool daten.csv die Datei im Ordner
des Nutzers. Die eigenen Dateien findest du in beiden Fällen über den Ordner
des Hauptskripts:
import Antra::System
import Antra::IO
val config = IO.slurp(System.script_dir().! <> "/config/default.and").!Eigene Module in lib/ neben dem Hauptskript (import Spiel::Level) und
Bibliotheken unter native/ findet antra im Paket automatisch, wie beim
Entwickeln.
Was der Empfänger tun muss#
- Windows: Zip entpacken,
breakout.exestarten. SmartScreen warnt bei neuen, unsignierten Programmen: Weitere Informationen → Trotzdem ausführen. - macOS: Archiv per Doppelklick entpacken. Weil das Programm nicht von
Apple beglaubigt ist, blockiert macOS den ersten Start. Entweder einmal
xattr -dr com.apple.quarantine Breakout.app(bzw. im entpackten Ordnerxattr -dr com.apple.quarantine .) ausführen, oder nach dem ersten Startversuch unter Systemeinstellungen → Datenschutz & Sicherheit auf Trotzdem öffnen klicken. Danach startet es normal per Doppelklick. - Linux:
tar xzf breakout-linux-x86_64.tar.gz, dann./breakout-linux-x86_64/breakout.
Braucht dein Programm C-Bibliotheken, die vom System kommen (siehe oben), muss der Empfänger sie zusätzlich installieren.
Schreib das am besten in eine README.txt in deinem Projekt — sie landet
mit im Paket (unter app/).
Unter Windows öffnet ein gepacktes Programm wie jedes Konsolenprogramm ein
Konsolenfenster; Ausgaben mit println und Fehlermeldungen erscheinen dort.
Alle Optionen#
antra pack [main.ant] [options]
--target T Zielsystem(e), mit Komma getrennt oder "all"
--out DIR Ausgabeordner (Standard: dist neben dem Hauptskript)
--name NAME Name von Programm und Archiv
--version V V in Ordner- und Archivnamen
--runtime T=SRC antra für System T aus SRC (Release-Archiv, URL oder Ordner)
--macos-app macOS-Ziele als .app-Bundle
--onefile eine einzige Datei (macOS: plus app.pack)
--dmg macOS: zusätzlich ein .dmg zum Installieren per Drag and Drop
--native das Programm mit antra build --native statt antras Runtime
--no-archive nur die Ordner bauen, ohne .zip/.tar.gzSysteme: linux-x86_64, linux-aarch64, linux-x86_64-musl,
macos-x86_64, macos-aarch64, windows-x86_64.
Nativ bauen: antra build --native (Vorschau)#
antra build --native macht aus einem Programm eine einzige ausführbare
Datei ohne Ordner und ohne Entpacken: antras Laufzeit mit deinem Skript,
den Paketen, die es importiert, und der Standardbibliothek darin.
antra build --native prog.ant # ./prog
antra build --native prog.ant -o bin/werkzeug
antra build --native prog.ant --target windows-x86_64 # prog.exe
antra build --native prog.ant --emit-zig gen/ # nur die Zig-QuellenDas ist die erste Stufe des Übersetzers nach Zig
(Spec): Noch läuft das Programm in der
Datei auf antras Interpreter, verhält sich also genau wie mit antra prog.ant.
Spätere Stufen übersetzen es Funktion für Funktion in Zig-Code.
antra pack | antra build --native | |
|---|---|---|
| Ergebnis | Ordner oder Archiv (oder --onefile) | eine Datei |
| eingebaut | alles im Projektordner, auch Assets | Skript, seine Pakete, Standardbibliothek |
C-Bibliotheken aus native.and | ja | nein |
| braucht zum Bauen | antra | antra, Zig und antras Quellen |
| Bauzeit | Sekunden | Sekunden (der erste Bau pro antra-Version und Ziel: einige Minuten) |
Eingebaut werden das Hauptskript, die Pakete, die es aus seinem Ordner, dessen
lib/ oder einem -I-Ordner importiert (auch deren Importe), und die ganze
Standardbibliothek. Dateien, die das Programm zur Laufzeit liest, bleiben
draußen und werden relativ zum aktuellen Ordner gesucht; System.script_dir()
zeigt in der nativen Datei auf die eingebauten Skripte und taugt dort nicht,
um Assets zu finden. Für Programme mit Assets oder C-Bibliotheken bleibt
antra pack der Weg.
Zum Bauen braucht es den Zig-Compiler (zig im PATH oder ZIG) und antras
Quelltext: den Checkout, aus dem antra läuft (zig-out/bin/antra), den
Checkout, aus dem das installierte antra stammt (zig-out/bin/antra self install merkt ihn sich in ~/.local/share/antra/source-tree.txt), oder
ANTRA_SRC. Der erste Bau für ein Ziel übersetzt antras Laufzeit zu einer
Bibliothek und dauert einige Minuten; sie landet im Cache (ANTRA_CACHE, sonst
~/.cache/antra/native/rt/) und gilt, bis sich antras Quellen oder die
Zig-Version ändern. Auch für dieses System wird für die allgemeine CPU des
Typs gebaut, nicht für genau diesen Rechner: Das Programm läuft so auf jedem
Mac bzw. PC derselben Art, und antra build --native und antra pack --native teilen sich dieselbe Laufzeit. Von den Laufzeiten im Cache bleiben
pro Ziel die zwei zuletzt benutzten; ältere räumt der nächste Bau weg, der
eine neue übersetzt. Jeder weitere Bau übersetzt nur noch den kleinen
erzeugten Teil und braucht wenige Sekunden. Die Datei ist um die 6 MB groß. --target nimmt dieselben
Plattformnamen wie antra pack oder ein Zig-Ziel (aarch64-linux-musl).
Dabei übersetzt antra build die Funktionen des Programms und seiner Pakete
nach Zig und bindet sie an die zwischengespeicherte Laufzeit. Mit
--no-optimize wird nichts übersetzt; dann läuft das ganze Programm auf dem
eingebauten Interpreter, genauso schnell wie mit antra selbst:
antra build --native prog.ant # übersetzt (Standard)
antra build --native prog.ant --no-optimize # nur der InterpreterDas Verhalten bleibt dasselbe. Was nicht übersetzt werden kann (Generatoren,
einzelne Anweisungen), läuft weiter auf dem Interpreter; der Bericht beim
Bauen nennt, wie viel davon übrig bleibt. Ein übersetzter Bau dauert wie
einer mit --no-optimize nur wenige Sekunden, sobald die Laufzeit einmal gebaut ist.
--optimize-full übersetzt die Laufzeit stattdessen mit dem Programm zusammen:
das dauert jedes Mal einige Minuten und ist kaum schneller.
Richtig schneller werden Funktionen, die nur rechnen: Sie werden ohne Umweg
über antras Werte übersetzt, mit Zig-Zahlen in lokalen Variablen, oft 10- bis
70-mal so schnell wie im Interpreter. Annotationen
(Typannotationen) sind dafür nicht nötig, helfen
aber: Fehlt eine, nimmt der Übersetzer zuerst Int an, dann Float, Bool,
String und Rat, und nimmt die erste Annahme, unter der der Rumpf passt.
Vorher schaut er, was die Typprüfung (--check) an den Aufrufen sieht: Geben
alle Aufrufe einer Funktion an einer Stelle dieselbe Art (steps(27) überall
ein Int), ist das die einzige Annahme, und es entstehen weniger Fassungen der
Funktion. Annotiert werden dürfen auch Arrays ([Int], Array[T]), Maps
(Map[K, V], %{…}) und Objekte (%Wallet{…}). Falsch werden kann das Programm dadurch
nicht: Jede getypte Fassung prüft beim Aufruf die Arten der Argumente, und
passt eine nicht, läuft der Aufruf wie im Interpreter. ANTRA_NATIVE_HINTS=0
schaltet die Hinweise der Typprüfung zum Vergleichen ab.
fn steps(start) -> {
my n = start
my k = 0
while (n != 1) {
n = if ((n & 1) == 0) then n >> 1 else 3 * n + 1
k += 1
}
k
}Dazu darf der Rumpf verwenden: Parameter, my/val, Rechnen, Vergleiche,
Bit-Operatoren, &&/||/!///, if/unless/while/return/last/next,
for über eine Range ganzer Zahlen (1..n, 0..<n, range(a, b, schritt)),
über ein Array oder eine Map, Strings mit <>, Interpolation, Vergleichen,
Index, len(...) und str(...), Brüche wie 1.5 oder 1 / 3, Keywords, das
Lesen aus Arrays und Maps (xs[i], m[k], m.name, x in xs),
map/filter/foreach mit einem Lambda direkt im Aufruf, Array.reduce, Math.sqrt und
andere Funktionen aus Antra::Math, float(...) und Aufrufe anderer solcher
Funktionen derselben Datei oder desselben Pakets, auch als Callback
(map(xs, sq)), Lambdas in lokalen Variablen (val f = |x| -> …) und Felder
von Objekten (self.cents, %{self | cents: …}). Schreiben (xs[i] = v,
m.k := v, Array.push) geht in jedes ungetaggte Array und jede Map; in
übergebene wird es protokolliert und bei einem Rückfall zurückgenommen.
Eine Variable darf nacheinander verschiedene Zahlarten halten (my s = 0,
später s = s + 1 / i), und eine Funktion, die sich am Ende selbst aufruft,
wird zur Schleife. Auch match mit Patterns, Funktionen mit mehreren Klauseln (fn fib(0) -> 0), defer, try/catch und die Operatoren .^, .?, .! werden übersetzt, ebenso Lambdas, die das Hauptprogramm an map und Co. übergibt. for- und while-Schleifen auf der obersten Ebene des Programms werden ebenfalls übersetzt, auch mit println/print darin: die Ausgabe wird gepuffert und erst geschrieben, wenn der Aufruf ohne Rückfall fertig ist (höchstens 50 ms lang, sonst bleibt die Funktion beim Interpreter). Methodenaufrufe mit -> auf Objekten der eigenen Pakete und Operatoren mit einem Impl (impl Add for %Vec{..}) laufen getypt. Andere Ausgaben, Lambdas, die
weitergegeben werden, oder andere Funktionen machen die Funktion nicht
falsch, nur nicht schneller. Strings, Brüche und Variablen mit gemischten Zahlarten
rechnen weiter über antras Laufzeit und gewinnen weniger (etwa Faktor 3). Der
Bericht markiert die getypten Funktionen mit typed; bei den anderen nennt er Zeile und Grund (not typed: line 4: output (println): …).
Kommt ein Argument einer anderen Art an als angenommen (steps(2.5)) oder
verlässt eine Rechnung den schnellen Bereich (eine ganze Zahl über 64 Bit,
% 0), rechnet die Funktion diesen Aufruf wie gewohnt. Ergebnisse und
Fehlermeldungen bleiben deshalb dieselben wie im Interpreter. Für Parameter
ohne Annotation entstehen zusätzlich Fassungen für Float, für beliebige
Zahlen und für Strings statt Arrays (und umgekehrt); eine Funktion sq(x)
ist also mit ganzen Zahlen und mit Float schnell. Eine Annotation legt den
Typ fest, wenn es auf eine bestimmte Art ankommt
(fn mean(a :- Float, b :- Float) -> …).
Eine native App packen: antra pack --native#
antra build --native liefert eine einzelne Datei ohne Assets und
C-Bibliotheken. antra pack --native verbindet beides: Statt antras Runtime
kommt das nativ gebaute Programm ins Paket, Assets und die C-Bibliotheken aus
native: bzw. native.and liegen wie sonst daneben. Mit --macos-app wird
daraus eine App zum Doppelklicken mit übersetztem Code:
antra pack --native --macos-appIn der antra.and (Kapitel 21) steht
dasselbe als pack: %{native_build: true, macos_app: true}.
Im Paket fehlt dann lib/Antra/: Die Standardbibliothek und die Pakete aus
dem eigenen lib/ sind in die Datei eingebaut. Das Programm startet wie jede
gepackte App im Ordner seines Hauptskripts (cwd), und System.script_dir()
zeigt auf app/ im Paket, also auf die echten Dateien. Assets werden so
gefunden wie beim Paket mit Runtime.
Bauen braucht wie antra build --native Zig und antras Quellen; der erste Bau
pro Ziel übersetzt die Laufzeit und dauert einige Minuten. Bei mehreren Zielen
(--target all) entstehen die fehlenden Laufzeiten gleichzeitig, das dauert
kaum länger als eine. Zusammen mit --onefile geht es noch nicht.
Bausteine für eigene Werkzeuge#
antra pack ist selbst in Antra geschrieben (lib/Antra/Packer.ant). Für
eigene Build-Skripte gibt es dieselben Teile als Funktionen:
import Antra::Packer
import Antra::Archive
Packer.pack(".", targets: ["windows-x86_64"], version: "1.0").! # %Ok[[archiv, ...]]
Packer.pack(".", targets: ["macos-aarch64"], macos_app: true).! # mit .app-Bundle
Archive.create("build/doku", "build/doku.zip").! # einen Ordner packenArchive.create schreibt .zip und .tar.gz ohne externe Programme;
executables: [...] markiert Dateien als ausführbar, auch wenn das Archiv
unter Windows entsteht.
