Antra

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-aarch64

Ergebnis:

dist/breakout-windows-x86_64.zip
dist/breakout-linux-x86_64.tar.gz
dist/breakout-macos-aarch64.tar.gz

Ohne --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 Bibliotheken

breakout.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) und app.and,
  • native/ — von dort kommen nur die Bibliotheken des Zielsystems mit,
  • was du in app.and unter exclude nennst (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.zip

ANTRA_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 (sdl2 und sqlite unter Linux und macOS), meldet pack not 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 deine README.txt.
  • linux-x86_64-musl: Dieses statische antra kann keine C-Bibliotheken laden; pack lä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_name ist der Name im Finder und im Dock (Standard: name).
  • bundle_id ist die eindeutige Kennung (CFBundleIdentifier); nimm eine umgekehrte Domain, die dir gehört. Standard: org.antra.app.<name>.
  • icon ist 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 Paket

Beim 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_CACHE legt 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 --dmg

Neben 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üsselBedeutungStandard
nameProgramm- und DateinameName des Hauptskripts
mainHauptskript, relativ zum Projektmain.ant bzw. das einzige Skript
versionsteht im Ordner-/Archivnamen (breakout-1.0-…)keine
targetsZielsystemedieses System
outAusgabeordnerdist
includenur diese Einträge der obersten Ebene mitnehmenalles
excludediese Dateien/Ordner weglassennichts
all_scriptsalle .ant-Dateien mitnehmen, nicht nur die importiertenfalse
cwd"main": das Programm startet im Ordner des Hauptskripts; "keep": im Ordner, aus dem es aufgerufen wird"main"
macos_appmacOS-Ziele als .app-Bundle (oben)false
display_nameName des Bundles im Findername
bundle_idCFBundleIdentifier des Bundlesorg.antra.app.<name>
iconPNG(s) oder .icns für das Bundlekeins
onefileeine einzige Datei (oben)false
dmgmacOS: zusätzlich ein Disk-Image (oben)false
native_builddas 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.exe starten. 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 Ordner xattr -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.gz

Systeme: 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-Quellen

Das 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 packantra build --native
ErgebnisOrdner oder Archiv (oder --onefile)eine Datei
eingebautalles im Projektordner, auch AssetsSkript, seine Pakete, Standardbibliothek
C-Bibliotheken aus native.andjanein
braucht zum Bauenantraantra, Zig und antras Quellen
BauzeitSekundenSekunden (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 Interpreter

Das 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-app

In 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 packen

Archive.create schreibt .zip und .tar.gz ohne externe Programme; executables: [...] markiert Dateien als ausführbar, auch wenn das Archiv unter Windows entsteht.

Quelle dieser Seite