This is guix.de.info, produced by makeinfo version 6.7 from
guix.de.texi.

Copyright © 2012-2022 Ludovic Courtès
Copyright © 2013, 2014, 2016 Andreas Enge
Copyright © 2013 Nikita Karetnikov
Copyright © 2014, 2015, 2016 Alex Kost
Copyright © 2015, 2016 Mathieu Lirzin
Copyright © 2014 Pierre-Antoine Rault
Copyright © 2015 Taylan Ulrich Bayırlı/Kammer
Copyright © 2015, 2016, 2017, 2019, 2020, 2021 Leo Famulari
Copyright © 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Ricardo
Wurmus
Copyright © 2016 Ben Woodcroft
Copyright © 2016, 2017, 2018, 2021 Chris Marusich
Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2022 Efraim Flashner
Copyright © 2016 John Darrington
Copyright © 2016, 2017 Nikita Gillmann
Copyright © 2016, 2017, 2018, 2019, 2020 Jan Nieuwenhuizen
Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Julien Lepiller
Copyright © 2016 Alex ter Weele
Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Christopher Baines
Copyright © 2017, 2018, 2019 Clément Lassieur
Copyright © 2017, 2018, 2020, 2021, 2022 Mathieu Othacehe
Copyright © 2017 Federico Beffa
Copyright © 2017, 2018 Carlo Zancanaro
Copyright © 2017 Thomas Danckaert
Copyright © 2017 humanitiesNerd
Copyright © 2017, 2021 Christine Lemmer-Webber
Copyright © 2017, 2018, 2019, 2020, 2021, 2022 Marius Bakke
Copyright © 2017, 2019, 2020, 2022 Hartmut Goebel
Copyright © 2017, 2019, 2020, 2021, 2022 Maxim Cournoyer
Copyright © 2017–2022 Tobias Geerinckx-Rice
Copyright © 2017 George Clemmer
Copyright © 2017 Andy Wingo
Copyright © 2017, 2018, 2019, 2020 Arun Isaac
Copyright © 2017 nee
Copyright © 2018 Rutger Helling
Copyright © 2018, 2021 Oleg Pykhalov
Copyright © 2018 Mike Gerwitz
Copyright © 2018 Pierre-Antoine Rouby
Copyright © 2018, 2019 Gábor Boskovits
Copyright © 2018, 2019, 2020, 2022 Florian Pelz
Copyright © 2018 Laura Lazzati
Copyright © 2018 Alex Vong
Copyright © 2019 Josh Holland
Copyright © 2019, 2020 Diego Nicola Barbato
Copyright © 2019 Ivan Petkov
Copyright © 2019 Jakob L. Kreuze
Copyright © 2019 Kyle Andrews
Copyright © 2019 Alex Griffin
Copyright © 2019, 2020, 2021, 2022 Guillaume Le Vaillant
Copyright © 2020 Liliana Marie Prikler
Copyright © 2019, 2020, 2021, 2022 Simon Tournier
Copyright © 2020 Wiktor Żelazny
Copyright © 2020 Damien Cassou
Copyright © 2020 Jakub Kądziołka
Copyright © 2020 Jack Hill
Copyright © 2020 Naga Malleswari
Copyright © 2020, 2021 Brice Waegeneire
Copyright © 2020 R Veera Kumar
Copyright © 2020, 2021 Pierre Langlois
Copyright © 2020 pinoaffe
Copyright © 2020 André Batista
Copyright © 2020, 2021 Alexandru-Sergiu Marton
Copyright © 2020 raingloom
Copyright © 2020 Daniel Brooks
Copyright © 2020 John Soo
Copyright © 2020 Jonathan Brielmaier
Copyright © 2020 Edgar Vincent
Copyright © 2021, 2022 Maxime Devos
Copyright © 2021 B. Wilson
Copyright © 2021 Xinglu Chen
Copyright © 2021 Raghav Gururajan
Copyright © 2021 Domagoj Stolfa
Copyright © 2021 Hui Lu
Copyright © 2021 pukkamustard
Copyright © 2021 Alice Brenon
Copyright © 2021, 2022 Josselin Poiret
Copyright © 2021 muradm
Copyright © 2021, 2022 Andrew Tropin
Copyright © 2021 Sarah Morgensen
Copyright © 2022 Remco van ’t Veer
Copyright © 2022 Aleksandr Vityazev
Copyright © 2022 Philip M^{c}Grath
Copyright © 2022 Karl Hallsby
Copyright © 2022 Justin Veilleux
Copyright © 2022 Reily Siegel
Copyright © 2022 Simon Streit
Copyright © 2022 (
Copyright © 2022 John Kehayias

   Es ist Ihnen gestattet, dieses Dokument zu vervielfältigen,
weiterzugeben und/oder zu verändern, unter den Bedingungen der GNU Free
Documentation License, entweder gemäß Version 1.3 der Lizenz oder (nach
Ihrer Option) einer späteren Version, die von der Free Software
Foundation veröffentlicht wurde, ohne unveränderliche Abschnitte, ohne
vorderen Umschlagtext und ohne hinteren Umschlagtext. Eine Kopie der
Lizenz finden Sie im Abschnitt mit dem Titel „GNU Free Documentation
License“.
INFO-DIR-SECTION Systemadministration
START-INFO-DIR-ENTRY
* Guix: (guix.de).           Installierte Software und Systemkonfigurationen
                               verwalten.
* guix package: (guix.de)guix package aufrufen.  Pakete installieren,
                                                   entfernen und
                                                   aktualisieren.
* guix gc: (guix.de)guix gc aufrufen.  Unbenutzten Plattenspeicher wieder
                                         freigeben.
* guix pull: (guix.de)guix pull aufrufen.  Die Liste verfügbarer Pakete
                                             aktualisieren.
* guix system: (guix.de)guix system aufrufen.  Die
                                                 Betriebssystemkonfiguration
                                                 verwalten.
* guix deploy: (guix.de)guix deploy aufrufen.  Betriebssystemkonfigurationen
                                                 entfernter Rechner verwalten.
END-INFO-DIR-ENTRY

INFO-DIR-SECTION Softwareentwicklung
START-INFO-DIR-ENTRY
* guix shell: (guix.de)guix shell aufrufen.  Software-Umgebungen erzeugen.
* guix environment: (guix.de)guix environment aufrufen.  Umgebungen für
                                                           Entwickler
                                                           erstellen
* guix build: (guix.de)guix build aufrufen.  Erstellen von Paketen.
* guix pack: (guix.de)guix pack aufrufen.  Bündel aus Binärdateien
                                             erstellen.
END-INFO-DIR-ENTRY


File: guix.de.info,  Node: Aufruf von guix pack,  Next: GCC-Toolchain,  Prev: Aufruf von guix environment,  Up: Entwicklung

8.3 ‘guix pack’ aufrufen
========================

Manchmal möchten Sie Software an Leute weitergeben, die (noch!) nicht
das Glück haben, Guix zu benutzen. Mit Guix würden sie nur ‘guix package
-i IRGENDETWAS’ einzutippen brauchen, aber wenn sie kein Guix haben,
muss es anders gehen. Hier kommt ‘guix pack’ ins Spiel.

     Anmerkung: Wenn Sie aber nach einer Möglichkeit suchen,
     Binärdateien unter Maschinen auszutauschen, auf denen Guix bereits
     läuft, sollten Sie einen Blick auf die Abschnitte *note Aufruf von
     guix copy::, *note Aufruf von guix publish:: und *note Aufruf von
     guix archive:: werfen.

   Der Befehl ‘guix pack’ erzeugt ein gut verpacktes “Software-Bündel”:
Konkret wird dadurch ein Tarball oder eine andere Art von Archiv mit den
Binärdateien der Software erzeugt, die Sie sich gewünscht haben,
zusammen mit all ihren Abhängigkeiten. Der resultierende Archiv kann
auch auf jeder Maschine genutzt werden, die kein Guix hat, und jeder
kann damit genau dieselben Binärdateien benutzen, die Ihnen unter Guix
zur Verfügung stehen. Das Bündel wird dabei auf eine Bit für Bit
reproduzierbare Art erzeugt, damit auch jeder nachprüfen kann, dass
darin wirklich diejenigen Binärdateien enthalten sind, von denen Sie es
behaupten.

   Um zum Beispiel ein Bündel mit Guile, Emacs, Geiser und all ihren
Abhängigkeiten zu erzeugen, führen Sie diesen Befehl aus:

     $ guix pack guile emacs emacs-geiser
     …
     /gnu/store/…-pack.tar.gz

   Als Ergebnis erhalten Sie einen Tarball mit einem Verzeichnis
‘/gnu/store’, worin sich alles relevanten Pakete befinden. Der
resultierende Tarball enthält auch ein “Profil” mit den drei angegebenen
Paketen; es ist dieselbe Art von Profil, die auch ‘guix package -i’
erzeugen würde. Mit diesem Mechanismus wird auch der binäre Tarball zur
Installation von Guix erzeugt (siehe *note Aus Binärdatei
installieren::).

   Benutzer des Bündels müssten dann aber zum Beispiel
‘/gnu/store/…-profile/bin/guile’ eintippen, um Guile auszuführen, was
Ihnen zu unbequem sein könnte. Ein Ausweg wäre, dass Sie etwa eine
symbolische Verknüpfung ‘/opt/gnu/bin’ auf das Profil anlegen:

     guix pack -S /opt/gnu/bin=bin guile emacs emacs-geiser

Benutzer müssten dann nur noch ‘/opt/gnu/bin/guile’ eintippen, um Guile
zu genießen.

   Doch was ist, wenn die Empfängerin Ihres Bündels keine
Administratorrechte auf ihrer Maschine hat, das Bündel also nicht ins
Wurzelverzeichnis ihres Dateisystems entpacken kann? Dann möchten Sie
vielleicht die Befehlszeilenoption ‘--relocatable’ benutzen (siehe
weiter unten). Mit dieser Option werden “verschiebliche Binärdateien”
erzeugt, die auch in einem beliebigen anderen Verzeichnis in der
Dateisystemhierarchie abgelegt und von dort ausgeführt werden können.
Man könnte sagen, sie sind pfad-agnostisch. In obigem Beispiel würden
Benutzer Ihren Tarball in ihr Persönliches Verzeichnis (das
„Home“-Verzeichnis) entpacken und von dort den Befehl
‘./opt/gnu/bin/guile’ ausführen.

   Eine weitere Möglichkeit ist, das Bündel im Format eines
Docker-Abbilds (englisch Docker-Image) zu erzeugen. Das geht mit dem
folgenden Befehl:

     guix pack -f docker -S /bin=bin guile guile-readline

Das Ergebnis ist ein Tarball, der dem Befehl ‘docker load’ übergeben
werden kann, gefolgt von ‘docker run’:

     docker load < DATEI
     docker run -ti guile-guile-readline /bin/guile

Dabei steht DATEI für das durch GUIX PACK gelieferte Abbild und
‘guile-guile-readline’ für den „Image-Tag“, der diesem zugewiesen wurde.
In der Dokumentation von Docker
(https://docs.docker.com/engine/reference/commandline/load/) finden Sie
nähere Informationen.

   Und noch eine weitere Möglichkeit ist, dass Sie ein SquashFS-Abbild
mit folgendem Befehl erzeugen:

     guix pack -f squashfs bash guile emacs emacs-geiser

Das Ergebnis ist ein SquashFS-Dateisystemabbild, dass entweder als
Dateisystem eingebunden oder mit Hilfe der
Singularity-Container-Ausführungsumgebung (https://www.sylabs.io/docs/)
als Dateisystemcontainer benutzt werden kann, mit Befehlen wie
‘singularity shell’ oder ‘singularity exec’.

   Es gibt mehrere Befehlszeilenoptionen, mit denen Sie Ihr Bündel
anpassen können:

‘--format=FORMAT’
‘-f FORMAT’
     Generiert ein Bündel im angegebenen FORMAT.

     Die verfügbaren Formate sind:

     ‘tarball’
          Das standardmäßig benutzte Format. Damit wird ein Tarball
          generiert, der alle angegebenen Binärdateien und symbolischen
          Verknüpfungen enthält.

     ‘docker’
          Generiert einen Tarball gemäß der Spezifikation für
          Docker-Abbilder
          (https://github.com/docker/docker/blob/master/image/spec/v1.2.md).
          Der „Repository-Name“, wie er in der Ausgabe des Befehls
          ‘docker images’ erscheint, wird anhand der Paketnamen
          berechnet, die auf der Befehlszeile oder in der Manifest-Datei
          angegeben wurden.

     ‘squashfs’
          Generiert ein SquashFS-Abbild, das alle angegebenen
          Binärdateien und symbolischen Verknüpfungen enthält, sowie
          leere Einhängepunkte für virtuelle Dateisysteme wie procfs.

               Anmerkung: Für Singularity _müssen_ Sie eine ‘/bin/sh’ in
               das Abbild aufnehmen. Aus diesem Grund gilt für ‘guix
               pack -f squashfs’ implizit immer auch ‘-S /bin=bin’.
               Daher muss Ihr Aufruf von ‘guix pack’ immer ungefähr so
               beginnen:

                    guix pack -f squashfs bash …

               Wenn Sie vergessen, das ‘bash’-Paket (oder etwas
               Ähnliches) zu bündeln, werden ‘singularity run’ und
               ‘singularity exec’ mit der wenig hilfreichen Meldung
               „Datei oder Verzeichnis nicht gefunden“ scheitern.

     ‘deb’
          Hiermit wird ein Debian-Archiv erzeugt (ein Paket mit der
          Dateinamenserweiterung „‘.deb’“), in dem alle angegebenen
          Binärdateien und symbolischen Verknüpfungen enthalten sind. Es
          kann auf jeder dpkg-basierten GNU(/Linux)-Distribution
          installiert werden. Fortgeschrittene Optionen werden Ihnen
          angezeigt, wenn Sie die Befehlszeilenoption
          ‘--help-deb-format’ angeben. Mit jenen können Control-Dateien
          hinzugefügt werden für eine genaue Steuerung z.B. welche
          bestimmten Trigger aktiviert werden oder um mit einem
          Betreuerskript beliebigen Konfigurations-Code einzufügen, der
          bei Installation ausgeführt werden soll.

               guix pack -f deb -C xz -S /usr/bin/hello=bin/hello hello

               Anmerkung: Weil in den mit ‘guix pack’ erzeugten Archiven
               eine Ansammlung von Store-Objekten enthalten ist und weil
               in jedem ‘dpkg’-Paket keine im Konflikt stehenden Dateien
               enthalten sein dürfen, können Sie de facto wahrscheinlich
               nur ein einziges mit ‘guix pack’ erzeugtes
               „‘.deb’“-Archiv je System installieren.

               Warnung: ‘dpkg’ übernimmt die Zuständigkeit für alle
               Dateien, die im Bündel enthalten sind, auch wenn es die
               Dateien _nicht_ kennt. Es ist unklug, mit Guix erzeugte
               „‘.deb’“-Dateien auf einem System zu installieren, auf
               dem ‘/gnu/store’ bereits von anderer Software verwendet
               wird, also wenn z.B. Guix bereits installiert ist oder
               andere Nicht-‘deb’-Bündel installiert sind.

‘--relocatable’
‘-R’
     Erzeugt “verschiebliche Binärdateien” – also pfad-agnostische,
     „portable“ Binärdateien, die an einer beliebigen Stelle in der
     Dateisystemhierarchie platziert und von dort ausgeführt werden
     können.

     Wenn diese Befehlszeilenoption einmal übergeben wird, funktionieren
     die erzeugten Binärdateien nur dann, wenn “Benutzernamensräume” des
     Linux-Kernels unterstützt werden. Wenn sie _zweimal_(1) übergeben
     wird, laufen die Binärdateien notfalls mit anderen Methoden, wenn
     keine Benutzernamensräume zur Verfügung stehen, funktionieren also
     ziemlich überall – siehe unten für die Auswirkungen.

     Zum Beispiel können Sie ein Bash enthalltendes Bündel erzeugen mit:

          guix pack -RR -S /meine-bin=bin bash

     … Sie können dieses dann auf eine Maschine ohne Guix kopieren und
     als normaler Nutzer aus Ihrem Persönlichen Verzeichnis (auch
     „Home“-Verzeichnis genannt) dann ausführen mit:

          tar xf pack.tar.gz
          ./meine-bin/sh

     Wenn Sie in der so gestarteten Shell dann ‘ls /gnu/store’
     eintippen, sehen Sie, dass Ihnen angezeigt wird, in ‘/gnu/store’
     befänden sich alle Abhängigkeiten von ‘bash’, obwohl auf der
     Maschine überhaupt kein Verzeichnis ‘/gnu/store’ existiert! Dies
     ist vermutlich die einfachste Art, mit Guix erstellte Software für
     eine Maschine ohne Guix auszuliefern.

          Anmerkung: Wenn die Voreinstellung verwendet wird,
          funktionieren verschiebliche Binärdateien nur mit
          “Benutzernamensräumen” (englisch “User namespaces”), einer
          Funktionalität des Linux-Kernels, mit der Benutzer ohne
          besondere Berechtigungen Dateisysteme einbinden (englisch
          „mount“) oder die Wurzel des Dateisystems wechseln können
          („change root“, kurz „chroot“). Alte Versionen von Linux haben
          diese Funktionalität noch nicht unterstützt und manche
          Distributionen von GNU/Linux schalten sie ab.

          Um verschiebliche Binärdateien zu erzeugen, die auch ohne
          Benutzernamensräume funktionieren, können Sie die
          Befehlszeilenoption ‘--relocatable’ oder ‘-R’ _zweimal_
          angeben. In diesem Fall werden die Binärdateien zuerst
          überprüfen, ob Benutzernamensräume unterstützt werden, und
          sonst notfalls einen anderen “Ausführungstreiber” benutzen, um
          das Programm auszuführen, wenn Benutzernamensräume nicht
          unterstützt werden. Folgende Ausführungstreiber werden
          unterstützt:

          ‘default’
               Es wird versucht, Benutzernamensräume zu verwenden. Sind
               Benutzernamensräume nicht verfügbar (siehe unten), wird
               auf PRoot zurückgegriffen.

          ‘performance’
               Es wird versucht, Benutzernamensräume zu verwenden. Sind
               Benutzernamensräume nicht verfügbar (siehe unten), wird
               auf Fakechroot zurückgegriffen.

          ‘userns’
               Das Programm wird mit Hilfe von Benutzernamensräumen
               ausgeführt. Wenn sie nicht unterstützt werden, bricht das
               Programm ab.

          ‘proot’
               Durch PRoot ausführen. Das Programm PRoot
               (https://proot-me.github.io/) bietet auch Unterstützung
               für Dateisystemvirtualisierung, indem der Systemaufruf
               ‘ptrace’ auf das laufende Programm angewendet wird.
               Dieser Ansatz funktioniert auch ohne besondere
               Kernel-Unterstützung, aber das Programm braucht mehr
               Zeit, um selbst Systemaufrufe durchzuführen.

          ‘fakechroot’
               Durch Fakechroot laufen lassen. Fakechroot
               (https://github.com/dex4er/fakechroot/) virtualisiert
               Dateisystemzugriffe, indem Aufrufe von Funktionen der
               C-Bibliothek wie ‘open’, ‘stat’, ‘exec’ und so weiter
               abgefangen werden. Anders als bei PRoot entsteht dabei
               kaum Mehraufwand. Jedoch funktioniert das nicht immer,
               zum Beispiel werden manche Dateisystemzugriffe aus der
               C-Bibliothek heraus _nicht_ abgefangen, ebenso wenig wie
               Dateisystemaufrufe über direkte Systemaufrufe, was zu
               fehlerbehaftetem Verhalten führt.

          Wenn Sie ein verpacktes Programm ausführen, können Sie einen
          der oben angeführten Ausführungstreiber ausdrücklich
          anfordern, indem Sie die Umgebungsvariable
          ‘GUIX_EXECUTION_ENGINE’ entsprechend festlegen.

‘--entry-point=BEFEHL’
     Den BEFEHL als den “Einsprungpunkt” des erzeugten Bündels
     verwenden, wenn das Bündelformat einen solchen unterstützt –
     derzeit tun das ‘docker’ und ‘squashfs’ (Singularity). Der BEFEHL
     wird relativ zum Profil ausgeführt, das sich im Bündel befindet.

     Der Einsprungpunkt gibt den Befehl an, der mit ‘docker run’ oder
     ‘singularity run’ beim Start nach Voreinstellung automatisch
     ausgeführt wird. Zum Beispiel können Sie das hier benutzen:

          guix pack -f docker --entry-point=bin/guile guile

     Dann kann das erzeugte Bündel mit z.B. ‘docker run’ ohne weitere
     Befehlszeilenargumente einfach geladen und ausgeführt werden, um
     ‘bin/guile’ zu starten:

          docker load -i pack.tar.gz
          docker run ABBILD-ID

‘--expression=AUSDRUCK’
‘-e AUSDRUCK’
     Als Paket benutzen, wozu der AUSDRUCK ausgewertet wird.

     Der Zweck hiervon ist derselbe wie bei der gleichnamigen
     Befehlszeilenoption in ‘guix build’ (siehe *note ‘--expression’ in
     ‘guix build’: Zusätzliche Erstellungsoptionen.).

‘--manifest=DATEI’
‘-m DATEI’
     Die Pakete benutzen, die im Manifest-Objekt aufgeführt sind, das
     vom Scheme-Code in der angegebenen DATEI geliefert wird. Wenn diese
     Befehlszeilenoption mehrmals wiederholt angegeben wird, werden die
     Manifeste aneinandergehängt.

     Dies hat einen ähnlichen Zweck wie die gleichnamige
     Befehlszeilenoption in ‘guix package’ (siehe *note ‘--manifest’:
     profile-manifest.) und benutzt dieselben Regeln für
     Manifest-Dateien. Damit können Sie eine Reihe von Paketen einmal
     definieren und dann sowohl zum Erzeugen von Profilesn als auch zum
     Erzeugen von Archiven benutzen, letztere für Maschinen, auf denen
     Guix nicht installiert ist. Beachten Sie, dass Sie _entweder_ eine
     Manifest-Datei _oder_ eine Liste von Paketen angeben können, aber
     nicht beides.

     Siehe *note Manifeste verfassen:: für Informationen dazu, wie man
     ein Manifest schreibt. Siehe *note ‘guix shell --export-manifest’:
     shell-export-manifest. für Informationen, wie Sie
     Befehlszeilenoptionen in ein Manifest „verwandeln“ können.

‘--system=SYSTEM’
‘-s SYSTEM’
     Versuchen, für die angegebene Art von SYSTEM geeignete Binärdateien
     zu erstellen – z.B. ‘i686-linux’ – statt für die Art von System,
     das die Erstellung durchführt.

‘--target=TRIPEL’
     Lässt für das angegebene TRIPEL cross-erstellen, dieses muss ein
     gültiges GNU-Tripel wie z.B. ‘"aarch64-linux-gnu"’ sein (siehe
     *note GNU-Tripel für configure: (autoconf)Specifying target
     triplets.).

‘--compression=WERKZEUG’
‘-C WERKZEUG’
     Komprimiert den resultierenden Tarball mit dem angegebenen
     WERKZEUG – dieses kann ‘gzip’, ‘zstd’, ‘bzip2’, ‘xz’, ‘lzip’ oder
     ‘none’ für keine Kompression sein.

‘--symlink=SPEZIFIKATION’
‘-S SPEZIFIKATION’
     Fügt die in der SPEZIFIKATION festgelegten symbolischen
     Verknüpfungen zum Bündel hinzu. Diese Befehlszeilenoption darf
     mehrmals vorkommen.

     Die SPEZIFIKATION muss von der Form ‘QUELLORT=ZIELORT’ sein, wobei
     der QUELLORT der Ort der symbolischen Verknüpfung, die erstellt
     wird, und ZIELORT das Ziel der symbolischen Verknüpfung ist.

     Zum Beispiel wird mit ‘-S /opt/gnu/bin=bin’ eine symbolische
     Verknüpfung ‘/opt/gnu/bin’ auf das Unterverzeichnis ‘bin’ im Profil
     erzeugt.

‘--save-provenance’
     Provenienzinformationen für die auf der Befehlszeile übergebenen
     Pakete speichern. Zu den Provenienzinformationen gehören die URL
     und der Commit jedes benutzten Kanals (siehe *note Kanäle::).

     Provenienzinformationen werden in der Datei
     ‘/gnu/store/…-profile/manifest’ im Bündel zusammen mit den üblichen
     Paketmetadaten abgespeichert – also Name und Version jedes Pakets,
     welche Eingaben dabei propagiert werden und so weiter. Die
     Informationen nützen den Empfängern des Bündels, weil sie dann
     wissen, woraus das Bündel (angeblich) besteht.

     Der Vorgabe nach wird diese Befehlszeilenoption _nicht_ verwendet,
     weil Provenienzinformationen genau wie Zeitstempel nichts zum
     Erstellungsprozess beitragen. Mit anderen Worten gibt es unendlich
     viele Kanal-URLs und Commit-IDs, aus denen dasselbe Bündel stammen
     könnte. Wenn solche „stillen“ Metadaten Teil des Ausgabe sind, dann
     wird also die bitweise Reproduzierbarkeit von Quellcode zu
     Binärdateien eingeschränkt.

‘--root=DATEI’
‘-r DATEI’
     Die DATEI zu einer symbolischen Verknüpfung auf das erzeugte Bündel
     machen und als Müllsammlerwurzel registrieren.

‘--localstatedir’
‘--profile-name=NAME’
     Das „lokale Zustandsverzeichnis“ ‘/var/guix’ ins resultierende
     Bündel aufnehmen, speziell auch das Profil
     ‘/var/guix/profiles/per-user/root/NAME’ – der vorgegebene NAME ist
     ‘guix-profile’, was ‘~root/.guix-profile’ entspricht.

     ‘/var/guix’ enthält die Store-Datenbank (siehe *note Der Store::)
     sowie die Müllsammlerwurzeln (siehe *note Aufruf von guix gc::). Es
     ins Bündel aufzunehmen, bedeutet, dass der enthaltene Store
     „vollständig“ ist und von Guix verwaltet werden kann, andernfalls
     wäre der Store im Bündel „tot“ und nach dem Auspacken des Bündels
     könnte Guix keine Objekte mehr dort hinzufügen oder entfernen.

     Ein Anwendungsfall hierfür ist der eigenständige, alle Komponenten
     umfassende binäre Tarball von Guix (siehe *note Aus Binärdatei
     installieren::).

‘--derivation’
‘-d’
     Den Namen der Ableitung ausgeben, die das Bündel erstellt.

‘--bootstrap’
     Mit den Bootstrap-Binärdateien das Bündel erstellen. Diese Option
     ist nur für Guix-Entwickler nützlich.

   Außerdem unterstützt ‘guix pack’ alle gemeinsamen Erstellungsoptionen
(siehe *note Gemeinsame Erstellungsoptionen::) und alle
Paketumwandlungsoptionen (siehe *note Paketumwandlungsoptionen::).

   ---------- Footnotes ----------

   (1) Es gibt einen Trick, wie Sie sich das merken können: ‘-RR’, womit
PRoot-Unterstützung hinzugefügt wird, kann man sich als Abkürzung für
„Rundum Relocatable“ oder englisch „Really Relocatable“ vorstellen. Ist
das nicht prima?


File: guix.de.info,  Node: GCC-Toolchain,  Next: Aufruf von guix git authenticate,  Prev: Aufruf von guix pack,  Up: Entwicklung

8.4 GCC-Toolchain
=================

Wenn Sie einen vollständigen Werkzeugsatz zum Kompilieren und Binden von
Quellcode in C oder C++ brauchen, werden Sie das Paket ‘gcc-toolchain’
haben wollen. Das Paket bietet eine vollständige GCC-Toolchain für die
Entwicklung mit C/C++, einschließlich GCC selbst, der GNU-C-Bibliothek
(Header-Dateien und Binärdateien samt Symbolen zur Fehlersuche/Debugging
in der ‘debug’-Ausgabe), Binutils und einen Wrapper für den
Binder/Linker.

   Der Zweck des Wrappers ist, die an den Binder übergebenen
Befehlszeilenoptionen mit ‘-L’ und ‘-l’ zu überprüfen und jeweils
passende Argumente mit ‘-rpath’ anzufügen, womit dann der echte Binder
aufgerufen wird. Standardmäßig weigert sich der Binder-Wrapper, mit
Bibliotheken außerhalb des Stores zu binden, um „Reinheit“ zu
gewährleisten. Das kann aber stören, wenn man die Toolchain benutzt, um
mit lokalen Bibliotheken zu binden. Um Referenzen auf Bibliotheken
außerhalb des Stores zu erlauben, müssen Sie die Umgebungsvariable
‘GUIX_LD_WRAPPER_ALLOW_IMPURITIES’ setzen.

   Das Paket ‘gfortran-toolchain’ stellt eine vollständige GCC-Toolchain
für die Entwicklung mit Fortran zur Verfügung. Pakete für die
Entwicklung mit anderen Sprachen suchen Sie bitte mit ‘guix search gcc
toolchain’ (siehe *note Invoking guix package: guix-search.).


File: guix.de.info,  Node: Aufruf von guix git authenticate,  Prev: GCC-Toolchain,  Up: Entwicklung

8.5 ‘guix git authenticate’ aufrufen
====================================

Der Befehl ‘guix git authenticate’ authentifiziert ein Git-Checkout nach
derselben Regel wie für Kanäle (siehe *note Kanalauthentifizierung:
channel-authentication.). Das bedeutet, dass angefangen beim angegebenen
Commit sichergestellt wird, dass alle nachfolgenden Commits mit einem
OpenPGP-Schlüssel signiert worden sind, dessen Fingerabdruck in der
‘.guix-authorizations’-Datei seines bzw. seiner jeweiligen Elterncommits
aufgeführt ist.

   Sie werden diesen Befehl zu schätzen wissen, wenn Sie einen Kanal
betreuen. Tatsächlich ist dieser Authentifizierungsmechanismus aber auch
bei weiteren Dingen nützlich; vielleicht möchten Sie ihn für
Git-Repositorys einsetzen, die gar nichts mit Guix zu tun haben?

   Die allgemeine Syntax lautet:

     guix git authenticate COMMIT UNTERZEICHNER [OPTIONEN…]

   Nach Vorgabe wird mit diesem Befehl das Git-Checkout im aktuellen
Arbeitsverzeichnis authentifiziert. Es wird bei Erfolg nichts ausgegeben
und der Exit-Status null zurückgeliefert; bei einem Fehler wird ein von
null verschiedener Exit-Status zurückgeliefert. COMMIT gibt den ersten
Commit an, der authentifiziert wird, und UNTERZEICHNER ist der
OpenPGP-Fingerabdruck des öffentlichen Schlüssels, mit dem der COMMIT
signiert wurde. Zusammen bilden sie eine „Kanaleinführung“ (siehe *note
Kanaleinführung: channel-authentication.). Mit den unten aufgeführten
Befehlszeilenoptionen können Sie Feineinstellungen am Prozess vornehmen.

‘--repository=VERZEICHNIS’
‘-r VERZEICHNIS’
     Das Git-Repository im VERZEICHNIS statt im aktuellen Verzeichnis
     öffnen.

‘--keyring=REFERENZ’
‘-k REFERENZ’
     Den OpenPGP-Schlüsselbund („Keyring“) von der angegebenen REFERENZ
     laden, einem Verweis auf einen Branch wie ‘origin/keyring’ oder
     ‘my-keyring’. Der Branch muss öffentliche Schlüssel im
     OpenPGP-Format in ‘.key’-Dateien enthalten, entweder als
     Binärdateien oder mit „ASCII-Hülle“. Nach Vorgabe wird der
     Schlüsselbund von einem Branch namens ‘keyring’ geladen.

‘--stats’
     Nach Abschluss Statistiken über die signierten Commits anzeigen.

‘--cache-key=SCHLÜSSEL’
     Bereits authentifizierte Commits werden in einer Datei unter
     ‘~/.cache/guix/authentication’ zwischengespeichert. Diese Option
     erzwingt, dass der Speicher innerhalb dieses Verzeichnisses in der
     Datei SCHLÜSSEL angelegt wird.

‘--historical-authorizations=DATEI’
     Nach Vorgabe wird jeder Commit, dessen Elterncommit(s) die Datei
     ‘.guix-authorizations’ fehlt, als gefälscht angesehen. Mit dieser
     Option werden dagegen die Autorisierungen in der DATEI für jeden
     Commit ohne ‘.guix-authorizations’ verwendet. Das Format der DATEI
     ist dasselbe wie bei ‘.guix-authorizations’ (siehe *note Format von
     ‘.guix-authorizations’: channel-authorizations.).


File: guix.de.info,  Node: Programmierschnittstelle,  Next: Zubehör,  Prev: Entwicklung,  Up: Top

9 Programmierschnittstelle
**************************

GNU Guix bietet mehrere Programmierschnittstellen (APIs) in der
Programmiersprache Scheme an, mit denen Software-Pakete definiert,
erstellt und gesucht werden können. Die erste Schnittstelle erlaubt es
Nutzern, ihre eigenen Paketdefinitionen in einer Hochsprache zu
schreiben. Diese Definitionen nehmen Bezug auf geläufige Konzepte der
Paketverwaltung, wie den Namen und die Version eines Pakets, sein
Erstellungssystem (Build System) und seine Abhängigkeiten
(Dependencies). Diese Definitionen können dann in konkrete
Erstellungsaktionen umgewandelt werden.

   Erstellungsaktionen werden vom Guix-Daemon für dessen Nutzer
durchgeführt. Bei einer normalen Konfiguration hat der Daemon
Schreibzugriff auf den Store, also das Verzeichnis ‘/gnu/store’, Nutzer
hingegen nicht. Die empfohlene Konfiguration lässt den Daemon die
Erstellungen in chroot-Umgebungen durchführen, mit eigenen
Benutzerkonten für „Erstellungsbenutzer“, um gegenseitige Beeinflussung
der Erstellung und des übrigen Systems zu minimieren.

   Systemnahe APIs stehen zur Verfügung, um mit dem Daemon und dem Store
zu interagieren. Um den Daemon anzuweisen, eine Erstellungsaktion
durchzuführen, versorgen ihn Nutzer jeweils mit einer “Ableitung”. Eine
Ableitung ist, wie durchzuführende Erstellungsaktionen, sowie die
Umgebungen, in denen sie durchzuführen sind, in Guix eigentlich intern
dargestellt werden. Ableitungen verhalten sich zu Paketdefinitionen
vergleichbar mit Assembler-Code zu C-Programmen. Der Begriff „Ableitung“
kommt daher, dass Erstellungsergebnisse daraus _abgeleitet_ werden.

   Dieses Kapitel beschreibt der Reihe nach all diese
Programmierschnittstellen (APIs), angefangen mit hochsprachlichen
Paketdefinitionen.

* Menu:

* Paketmodule::              Pakete aus Sicht des Programmierers.
* Pakete definieren::        Wie Sie neue Pakete definieren.
* Paketvarianten definieren::  Pakete anpassen.
* Manifeste verfassen::      Woraus Ihre Umgebung besteht.
* Erstellungssysteme::       Angeben, wie Pakete erstellt werden.
* Erstellungsphasen::        Die Phasen im Erstellungsprozess eines Pakets.
* Werkzeuge zur Erstellung::  Helferlein für Ihre Paketdefinitionen und
                                anderes.
* Suchpfade::                Umgebungsvariable mit Suchpfaden deklarieren.
* Der Store::                Den Paket-Store verändern.
* Ableitungen::              Systemnahe Schnittstelle für Paketableitungen.
* Die Store-Monade::         Rein funktionale Schnittstelle zum Store.
* G-Ausdrücke::             Erstellungsausdrücke verarbeiten.
* Aufruf von guix repl::     Guix in Guile programmieren.
* Interaktiv mit Guix arbeiten::  Genau steuern auf der REPL.


File: guix.de.info,  Node: Paketmodule,  Next: Pakete definieren,  Up: Programmierschnittstelle

9.1 Paketmodule
===============

Aus Programmierersicht werden die Paketdefinitionen der GNU-Distribution
als Guile-Module in Namensräumen wie ‘(gnu packages …)’ sichtbar
gemacht(1) (siehe *note Guile-Module: (guile)Module.). Zum Beispiel
exportiert das Modul ‘(gnu packages emacs)’ eine Variable namens
‘emacs’, die an ein ‘<package>’-Objekt gebunden ist (siehe *note Pakete
definieren::).

   Der Modulnamensraum ‘(gnu packages …)’ wird von
Befehlszeilenwerkzeugen automatisch nach Paketen durchsucht. Wenn Sie
zum Beispiel ‘guix install emacs’ ausführen, werden alle ‘(gnu packages
…)’-Module durchlaufen, bis eines gefunden wird, das ein Paketobjekt mit
dem Namen ‘emacs’ exportiert. Diese Paketsuchfunktion ist im Modul ‘(gnu
packages)’ implementiert.

   Benutzer können Paketdefinitionen auch in Modulen mit anderen Namen
unterbringen – z.B. ‘(my-packages emacs)’(2). Es gibt zwei Arten, solche
Paketdefinitionen für die Benutzungsschnittstelle sichtbar zu machen:

  1. Eine Möglichkeit ist, das Verzeichnis, in dem Ihre Paketmodule
     stehen, mit der Befehlszeilenoption ‘-L’ von ‘guix package’ und
     anderen Befehlen (siehe *note Gemeinsame Erstellungsoptionen::)
     oder durch Setzen der unten beschriebenen Umgebungsvariablen
     ‘GUIX_PACKAGE_PATH’ zum Suchpfad hinzuzufügen.

  2. Die andere Möglichkeit ist, einen “Kanal” zu definieren und ‘guix
     pull’ so zu konfigurieren, dass es davon seine Module bezieht. Ein
     Kanal ist im Kern nur ein Git-Repository, in welchem Paketmodule
     liegen. Siehe *note Kanäle:: für mehr Informationen, wie Kanäle
     definiert und benutzt werden.

   ‘GUIX_PACKAGE_PATH’ funktioniert ähnlich wie andere Variable mit
Suchpfaden:

 -- Umgebungsvariable: GUIX_PACKAGE_PATH
     Dies ist eine doppelpunktgetrennte Liste von Verzeichnissen, die
     nach zusätzlichen Paketmodulen durchsucht werden. In dieser
     Variablen aufgelistete Verzeichnisse haben Vorrang vor den Modulen,
     die zur Distribution gehören.

   Die Distribution wird komplett von Grund auf initialisiert – man sagt
zur Initialisierung auch “Bootstrapping” – und sie ist “eigenständig”
(„self-contained“): Jedes Paket wird nur auf Basis von anderen Paketen
in der Distribution erstellt. Die Wurzel dieses Abhängigkeitsgraphen ist
ein kleiner Satz von Initialisierungsbinärdateien, den
“Bootstrap-Binärdateien”, die im Modul ‘(gnu packages bootstrap)’
verfügbar gemacht werden. Für mehr Informationen über Bootstrapping,
siehe *note Bootstrapping::.

   ---------- Footnotes ----------

   (1) Beachten Sie, dass Pakete unter dem Modulnamensraum ‘(gnu
packages …)’ nicht notwendigerweise auch „GNU-Pakete“ sind. Dieses
Schema für die Benennung von Modulen folgt lediglich den üblichen
Guile-Konventionen: ‘gnu’ bedeutet, dass die Module als Teil des
GNU-Systems ausgeliefert werden, und ‘packages’ gruppiert Module mit
Paketdefinitionen.

   (2) Beachten Sie, dass Dateiname und Modulname übereinstimmen müssen.
Zum Beispiel muss das Modul ‘(my-packages emacs)’ in einer Datei
‘my-packages/emacs.scm’ relativ zum mit ‘--load-path’ oder
‘GUIX_PACKAGE_PATH’ angegebenen Ladepfad stehen. Siehe *note
(guile)Modules and the File System:: für Details.


File: guix.de.info,  Node: Pakete definieren,  Next: Paketvarianten definieren,  Prev: Paketmodule,  Up: Programmierschnittstelle

9.2 Pakete definieren
=====================

Mit den Modulen ‘(guix packages)’ und ‘(guix build-system)’ können
Paketdefinitionen auf einer hohen Abstraktionsebene geschrieben werden.
Zum Beispiel sieht die Paketdefinition bzw. das “Rezept” für das Paket
von GNU Hello so aus:

     (define-module (gnu packages hello)
       #:use-module (guix packages)
       #:use-module (guix download)
       #:use-module (guix build-system gnu)
       #:use-module (guix licenses)
       #:use-module (gnu packages gawk))

     (define-public hello
       (package
         (name "hello")
         (version "2.10")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
         (build-system gnu-build-system)
         (arguments '(#:configure-flags '("--enable-silent-rules")))
         (inputs (list gawk))
         (synopsis "Hello, GNU world: An example GNU package")
         (description "Guess what GNU Hello prints!")
         (home-page "https://www.gnu.org/software/hello/")
         (license gpl3+)))

Auch ohne ein Experte in Scheme zu sein, könnten Leser erraten haben,
was die verschiedenen Felder dabei bedeuten. Dieser Ausdruck bindet die
Variable ‘hello’ an ein ‘<package>’-Objekt, was an sich nur ein Verbund
(Record) ist (siehe *note Scheme-Verbünde: (guile)SRFI-9.). Die Felder
dieses Paket-Objekts lassen sich mit den Prozeduren aus dem Modul ‘(guix
packages)’ auslesen, zum Beispiel liefert ‘(package-name hello)’ –
Überraschung! – ‘"hello"’.

   Mit etwas Glück können Sie die Definition vielleicht teilweise oder
sogar ganz aus einer anderen Paketsammlung importieren, indem Sie den
Befehl ‘guix import’ verwenden (siehe *note Aufruf von guix import::).

   In obigem Beispiel wurde ‘hello’ in einem eigenen Modul ganz für sich
alleine definiert, und zwar ‘(gnu packages hello)’. Technisch gesehen
muss es nicht unbedingt in einem solchen Modul definiert werden, aber es
ist bequem, denn alle Module unter ‘(gnu packages …)’ werden automatisch
von den Befehlszeilenwerkzeugen gefunden (siehe *note Paketmodule::).

   Ein paar Dinge sind noch erwähnenswert in der obigen Paketdefinition:

   • Das ‘source’-Feld für die Quelle des Pakets ist ein
     ‘<origin>’-Objekt, was den Paketursprung angibt (siehe *note
     „origin“-Referenz:: für eine vollständige Referenz). Hier wird
     dafür die Methode ‘url-fetch’ aus dem Modul ‘(guix download)’
     benutzt, d.h. die Quelle ist eine Datei, die über FTP oder HTTP
     heruntergeladen werden soll.

     Das Präfix ‘mirror://gnu’ lässt ‘url-fetch’ einen der
     GNU-Spiegelserver benutzen, die in ‘(guix download)’ definiert
     sind.

     Das Feld ‘sha256’ legt den erwarteten SHA256-Hashwert der
     herunterzuladenden Datei fest. Ihn anzugeben ist Pflicht und er
     ermöglicht es Guix, die Integrität der Datei zu überprüfen. Die
     Form ‘(base32 …)’ geht der base32-Darstellung des Hash-Wertes
     voraus. Sie finden die base32-Darstellung mit Hilfe der Befehle
     ‘guix download’ (siehe *note Aufruf von guix download::) und ‘guix
     hash’ (siehe *note Aufruf von guix hash::).

     Wenn nötig kann in der ‘origin’-Form auch ein ‘patches’-Feld
     stehen, wo anzuwendende Patches aufgeführt werden, sowie ein
     ‘snippet’-Feld mit einem Scheme-Ausdruck mit den Anweisungen, wie
     der Quellcode zu modifizieren ist.

   • Das Feld ‘build-system’ legt fest, mit welcher Prozedur das Paket
     erstellt werden soll (siehe *note Erstellungssysteme::). In diesem
     Beispiel steht ‘gnu-build-system’ für das wohlbekannte
     GNU-Erstellungssystem, wo Pakete mit der üblichen Befehlsfolge
     ‘./configure && make && make check && make install’ konfiguriert,
     erstellt und installiert werden.

     Sobald Sie anfangen, Pakete für nichttriviale Software zu
     schreiben, könnten Sie Werkzeuge benötigen, um jene
     Erstellungsphasen abzuändern, Dateien zu verändern oder Ähnliches.
     Siehe *note Werkzeuge zur Erstellung:: für mehr Informationen dazu.

   • Das Feld ‘arguments’ gibt an, welche Optionen dem Erstellungssystem
     mitgegeben werden sollen (siehe *note Erstellungssysteme::). In
     diesem Fall interpretiert ‘gnu-build-system’ diese als Auftrag,
     ‘configure’ mit der Befehlszeilenoption ‘--enable-silent-rules’
     auszuführen.

     Was hat es mit diesen einfachen Anführungszeichen (‘'’) auf sich?
     Sie gehören zur Syntax von Scheme und führen eine wörtlich zu
     interpretierende Datenliste ein; dies nennt sich Maskierung oder
     Quotierung. ‘'’ ist synonym mit ‘quote’. Ihnen könnte auch ‘`’
     begegnen (ein Backquote, stattdessen kann man auch das längere
     Synonym ‘quasiquote’ schreiben); damit können wir eine wörtlich als
     Daten interpretierte Liste einführen, aber bei dieser
     „Quasimaskierung“ kann ‘,’ (ein Komma, oder dessen Synonym
     ‘unquote’) benutzt werden, um den ausgewerteten Wert eines
     Ausdrucks in diese Liste einzufügen. *note Quotierung:
     (guile)Expression Syntax. enthält weitere Details. Hierbei ist also
     der Wert des ‘arguments’-Feldes eine Liste von Argumenten, die an
     das Erstellungssystem weitergereicht werden, wie bei ‘apply’ (siehe
     *note ‘apply’: (guile)Fly Evaluation.).

     Ein Doppelkreuz gefolgt von einem Doppelpunkt (‘#:’) definiert ein
     Scheme-“Schlüsselwort” (siehe *note (guile)Keywords::) und
     ‘#:configure-flags’ ist ein Schlüsselwort, um eine
     Befehlszeilenoption an das Erstellungssystem mitzugeben (siehe
     *note (guile)Coding With Keywords::).

   • Das Feld ‘inputs’ legt Eingaben an den Erstellungsprozess fest –
     d.h. Abhängigkeiten des Pakets zur Erstellungs- oder Laufzeit. Hier
     fügen wir eine Eingabe hinzu, eine Referenz auf die Variable
     ‘gawk’; GAWK ist auch selbst wiederum an ein ‘<package>’-Objekt als
     Variablenwert gebunden.

     Beachten Sie, dass GCC, Coreutils, Bash und andere essenzielle
     Werkzeuge hier nicht als Eingaben aufgeführt werden müssen.
     Stattdessen sorgt schon ‘gnu-build-system’ dafür, dass diese
     vorhanden sein müssen (siehe *note Erstellungssysteme::).

     Sämtliche anderen Abhängigkeiten müssen aber im ‘inputs’-Feld
     aufgezählt werden. Jede hier nicht angegebene Abhängigkeit wird
     während des Erstellungsprozesses schlicht nicht verfügbar sein,
     woraus ein Erstellungsfehler resultieren kann.

   Siehe *note „package“-Referenz:: für eine umfassende Beschreibung
aller erlaubten Felder.

     Vertiefung: Fühlen Sie sich eingeschüchtert von der Scheme-Sprache
     oder wurde Ihre Neugier geweckt? Im Kochbuch gibt es einen kurzen
     Abschnitt, wie man anfängt. Dort werden einige der oben gezeigten
     Dinge wiederholt und die Grundlagen erklärt. Siehe *note
     (guix-cookbook.de)Ein Schnellkurs in Scheme:: für weitere
     Informationen.

   Sobald eine Paketdefinition eingesetzt wurde, können Sie das Paket
mit Hilfe des Befehlszeilenwerkzeugs ‘guix build’ dann auch tatsächlich
erstellen (siehe *note Aufruf von guix build::) und dabei jegliche
Erstellungsfehler, auf die Sie stoßen, beseitigen (siehe *note
Fehlschläge beim Erstellen untersuchen::). Sie können den Befehl ‘guix
edit’ benutzen, um leicht zur Paketdefinition zurückzuspringen (siehe
*note Aufruf von guix edit::). Unter *note Paketrichtlinien:: finden Sie
mehr Informationen darüber, wie Sie Paketdefinitionen testen, und unter
*note Aufruf von guix lint:: finden Sie Informationen, wie Sie prüfen,
ob eine Definition alle Stilkonventionen einhält. Zuletzt finden Sie
unter *note Kanäle:: Informationen, wie Sie die Distribution um Ihre
eigenen Pakete in einem „Kanal“ erweitern.

   Zu all dem sei auch erwähnt, dass Sie das Aktualisieren einer
Paketdefinition auf eine vom Anbieter neu veröffentlichte Version mit
dem Befehl ‘guix refresh’ teilweise automatisieren können (siehe *note
Aufruf von guix refresh::).

   Hinter den Kulissen wird die einem ‘<package>’-Objekt entsprechende
Ableitung zuerst durch ‘package-derivation’ berechnet. Diese Ableitung
wird in der ‘.drv’-Datei unter ‘/gnu/store’ gespeichert. Die von ihr
vorgeschriebenen Erstellungsaktionen können dann durch die Prozedur
‘build-derivations’ umgesetzt werden (siehe *note Der Store::).

 -- Scheme-Prozedur: package-derivation STORE PAKET [SYSTEM]
     Das ‘<derivation>’-Objekt zum PAKET für das angegebene SYSTEM
     liefern (siehe *note Ableitungen::).

     Als PAKET muss ein gültiges ‘<package>’-Objekt angegeben werden und
     das SYSTEM muss eine Zeichenkette sein, die das Zielsystem angibt –
     z.B. ‘"x86_64-linux"’ für ein auf x86_64 laufendes, Linux-basiertes
     GNU-System. STORE muss eine Verbindung zum Daemon sein, der die
     Operationen auf dem Store durchführt (siehe *note Der Store::).

Auf ähnliche Weise kann eine Ableitung berechnet werden, die ein Paket
für ein anderes System cross-erstellt.

 -- Scheme-Prozedur: package-cross-derivation STORE PAKET ZIEL [SYSTEM]
          Liefert das
     ‘<derivation>’-Objekt, um das PAKET zu cross-erstellen vom SYSTEM
     aus für das ZIEL-System.

     Als ZIEL muss ein gültiges GNU-Tripel angegeben werden, was die
     Ziel-Hardware und das zugehörige Betriebssystem beschreibt, wie
     z.B. ‘"aarch64-linux-gnu"’ (siehe *note (autoconf)Specifying Target
     Triplets::).

   Wenn Sie einmal Paketdefinitionen fertig verfasst haben, können Sie
leicht _Varianten_ derselben Pakete definieren. Siehe *note
Paketvarianten definieren:: für mehr Informationen dazu.

* Menu:

* „package“-Referenz::   Der Datentyp für Pakete.
* „origin“-Referenz::    Datentyp für Paketursprünge.


File: guix.de.info,  Node: „package“-Referenz,  Next: „origin“-Referenz,  Up: Pakete definieren

9.2.1 ‘package’-Referenz
------------------------

Dieser Abschnitt fasst alle in ‘package’-Deklarationen zur Verfügung
stehenden Optionen zusammen (siehe *note Pakete definieren::).

 -- Datentyp: package
     Dieser Datentyp steht für ein Paketrezept.

     ‘name’
          Der Name des Pakets als Zeichenkette.

     ‘version’
          Die Version des Pakets als Zeichenkette. Siehe *note
          Versionsnummern::, wo erklärt wird, worauf Sie achten müssen.

     ‘source’
          Ein Objekt, das beschreibt, wie der Quellcode des Pakets
          bezogen werden soll. Meistens ist es ein ‘origin’-Objekt,
          welches für eine aus dem Internet heruntergeladene Datei steht
          (siehe *note „origin“-Referenz::). Es kann aber auch ein
          beliebiges anderes „dateiähnliches“ Objekt sein, wie z.B. ein
          ‘local-file’, was eine Datei im lokalen Dateisystem bezeichnet
          (siehe *note ‘local-file’: G-Ausdrücke.).

     ‘build-system’
          Das Erstellungssystem, mit dem das Paket erstellt werden soll
          (siehe *note Erstellungssysteme::).

     ‘arguments’ (Vorgabe: ‘'()’)
          Die Argumente, die an das Erstellungssystem übergeben werden
          sollen (siehe *note Erstellungssysteme::). Dies ist eine
          Liste, typischerweise eine Reihe von Schlüssel-Wert-Paaren wie
          in diesem Beispiel:

               (package
                 (name "beispiel")
                 ;; hier würden noch ein paar Felder stehen
                 (arguments
                   (list #:tests? #f                     ;Tests überspringen
                         #:make-flags #~'("VERBOSE=1")   ;Optionen für 'make'
                         #:configure-flags #~'("--enable-frobbing"))))

          Welche Schlüsselwortargumente genau unterstützt werden, hängt
          vom jeweiligen Erstellungssystem ab (siehe *note
          Erstellungssysteme::), doch werden Sie feststellen, dass fast
          alle ‘#:configure-flags’, ‘#:make-flags’, ‘#:tests?’ und
          ‘#:phases’ berücksichtigen. Insbesondere können Sie mit dem
          Schlüsselwort ‘#:phases’ den Satz von Erstellungsphasen, der
          für Ihr Paket zum Einsatz kommt, ändern (siehe *note
          Erstellungsphasen::).

     ‘inputs’ (Vorgabe: ‘'()’)
     ‘native-inputs’ (Vorgabe: ‘'()’)
     ‘propagated-inputs’ (Vorgabe: ‘'()’)
          In diesen Feldern wird eine Liste der Abhängigkeiten des
          Pakets aufgeführt. Dabei ist jedes Listenelement ein
          „package“-, „origin“- oder sonstiges dateiartiges Objekt
          (siehe *note G-Ausdrücke::). Um die zu benutzende Ausgabe zu
          benennen, übergeben Sie eine zweielementige Liste mit der
          Ausgabe als zweitem Element (siehe *note Pakete mit mehreren
          Ausgaben.:: für mehr Informationen zu Paketausgaben). Im
          folgenden Beispiel etwa werden drei Eingaben festgelegt:

               (list libffi libunistring
                     `(,glib "bin"))      ;Ausgabe "bin" von GLib

          Im obigen Beispiel wird die Ausgabe ‘"out"’ für ‘libffi’ und
          ‘libunistring’ benutzt.

               Anmerkung zur Kompatibilität: Bis Version 1.3.0 waren
               Eingabelisten noch Listen von Tupeln, wobei jedes Tupel
               eine Bezeichnung für die Eingabe (als Zeichenkette) als
               erstes Element, dann ein „package“-, „origin“- oder
               „derivation“-Objekt (Paket, Ursprung oder Ableitung) als
               zweites Element und optional die Benennung der davon zu
               benutzenden Ausgabe umfasste; letztere hatte als
               Vorgabewert ‘"out"’. Im folgenden Beispiel wird dasselbe
               wie oben angegeben, aber im “alten Stil für Eingaben”:

                    ;; Alter Eingabenstil (veraltet).
                    `(("libffi" ,libffi)
                      ("libunistring" ,libunistring)
                      ("glib:bin" ,glib "bin"))  ;Ausgabe "bin" von GLib

               Dieser Stil gilt als veraltet. Er wird bislang
               unterstützt, aber er wird in einer zukünftigen Version
               entfernt werden. Man sollte ihn nicht für neue
               Paketdefinitionen gebrauchen. Siehe *note Aufruf von guix
               style:: für eine Erklärung, wie Sie zum neuen Stil
               migrieren.

          Die Unterscheidung zwischen ‘native-inputs’ und ‘inputs’ ist
          wichtig, damit Cross-Kompilieren möglich ist. Beim
          Cross-Kompilieren werden als ‘inputs’ aufgeführte
          Abhängigkeiten für die Ziel-Prozessorarchitektur (_target_)
          erstellt, andersherum werden als ‘native-inputs’ aufgeführte
          Abhängigkeiten für die Prozessorarchitektur der erstellenden
          Maschine (_build_) erstellt.

          ‘native-inputs’ listet typischerweise die Werkzeuge auf, die
          während der Erstellung gebraucht werden, aber nicht zur
          Laufzeit des Programms gebraucht werden. Beispiele sind
          Autoconf, Automake, pkg-config, Gettext oder Bison. ‘guix
          lint’ kann melden, ob wahrscheinlich Fehler in der Auflistung
          sind (siehe *note Aufruf von guix lint::).

          Schließlich ist ‘propagated-inputs’ ähnlich wie ‘inputs’, aber
          die angegebenen Pakete werden automatisch mit ins Profil
          installiert (siehe *note die Rolle von Profilen in Guix:
          Funktionalitäten.), wenn das Paket installiert wird, zu dem
          sie gehören (siehe *note ‘guix package’:
          package-cmd-propagated-inputs. für Informationen darüber, wie
          ‘guix package’ mit propagierten Eingaben umgeht).

          Dies ist zum Beispiel nötig, wenn Sie ein Paket für eine
          C-/C++-Bibliothek schreiben, die Header-Dateien einer anderen
          Bibliothek braucht, um mit ihr kompilieren zu können, oder
          wenn sich eine pkg-config-Datei auf eine andere über ihren
          ‘Requires’-Eintrag bezieht.

          Noch ein Beispiel, wo ‘propagated-inputs’ nützlich ist, sind
          Sprachen, die den Laufzeit-Suchpfad _nicht_ zusammen mit dem
          Programm abspeichern (_nicht_ wie etwa im ‘RUNPATH’ bei
          ELF-Dateien), also Sprachen wie Guile, Python, Perl und
          weitere. Wenn Sie ein Paket für eine in solchen Sprachen
          geschriebene Bibliothek schreiben, dann sorgen Sie dafür, dass
          es zur Laufzeit den von ihr benötigten Code finden kann, indem
          Sie ihre Laufzeit-Abhängigkeiten in ‘propagated-inputs’ statt
          in ‘inputs’ aufführen.

     ‘outputs’ (Vorgabe: ‘'("out")’)
          Die Liste der Benennungen der Ausgaben des Pakets. Der
          Abschnitt *note Pakete mit mehreren Ausgaben.:: beschreibt
          übliche Nutzungen zusätzlicher Ausgaben.

     ‘native-search-paths’ (Vorgabe: ‘'()’)
     ‘search-paths’ (Vorgabe: ‘'()’)
          Eine Liste von ‘search-path-specification’-Objekten, die
          Umgebungsvariable für von diesem Paket beachtete Suchpfade
          („search paths“) beschreiben. Siehe *note Suchpfade::, wenn
          Sie mehr über Suchpfadspezifikationen erfahren möchten.

          Wie auch bei Eingaben wird zwischen ‘native-search-paths’ und
          ‘search-paths’ nur dann ein Unterschied gemacht, wenn Sie
          cross-kompilieren. Beim Cross-Kompilieren bezieht sich
          ‘native-search-paths’ ausschließlich auf native Eingaben,
          wohingegen sich die ‘search-paths’ ausschließlich auf Eingaben
          für den „Host“ genannten Rechner beziehen.

          Für Pakete wie z.B. Cross-Compiler sind die Ziel-Eingaben
          wichtig, z.B. hat unser (angepasster) GCC-Cross-Compiler einen
          Eintrag für ‘CROSS_C_INCLUDE_PATH’ in ‘search-paths’, damit er
          ‘.h’-Dateien für das Zielsystem auswählt und _nicht_ die aus
          nativen Eingaben. Für die meisten Pakete ist aber einzig
          ‘native-search-paths’ von Bedeutung.

     ‘replacement’ (Vorgabe: ‘#f’)
          Dies muss entweder ‘#f’ oder ein package-Objekt sein, das als
          Ersatz (“replacement”) dieses Pakets benutzt werden soll. Im
          Abschnitt zu *note Veredelungen: Sicherheitsaktualisierungen.
          wird dies erklärt.

     ‘synopsis’
          Eine einzeilige Beschreibung des Pakets.

     ‘description’
          Eine ausführlichere Beschreibung des Pakets, als eine
          Zeichenkette in Texinfo-Syntax.

     ‘license’
          Die Lizenz des Pakets; benutzt werden kann ein Wert aus dem
          Modul ‘(guix licenses)’ oder eine Liste solcher Werte.

     ‘home-page’
          Die URL, die die Homepage des Pakets angibt, als Zeichenkette.

     ‘supported-systems’ (Vorgabe: ‘%supported-systems’)
          Die Liste der vom Paket unterstützten Systeme als
          Zeichenketten der Form ‘Architektur-Kernel’, zum Beispiel
          ‘"x86_64-linux"’.

     ‘location’ (Vorgabe: die Stelle im Quellcode, wo die ‘package’-Form steht)
          Wo im Quellcode das Paket definiert wurde. Es ist sinnvoll,
          dieses Feld manuell zuzuweisen, wenn das Paket von einem
          anderen Paket erbt, weil dann dieses Feld nicht automatisch
          berichtigt wird.

 -- Scheme-Syntax: this-package
     Wenn dies im _lexikalischen Geltungsbereich_ der Definition eines
     Feldes im Paket steht, bezieht sich dieser Bezeichner auf das
     Paket, das gerade definiert wird.

     Das folgende Beispiel zeigt, wie man ein Paket als native Eingabe
     von sich selbst beim Cross-Kompilieren deklariert:

          (package
            (name "guile")
            ;; …

            ;; Wenn es cross-kompiliert wird, hängt zum Beispiel
            ;; Guile von einer nativen Version von sich selbst ab.
            ;; Wir fügen sie hier hinzu.
            (native-inputs (if (%current-target-system)
                               (list this-package)
                               '())))

     Es ist ein Fehler, außerhalb einer Paketdefinition auf
     ‘this-package’ zu verweisen.

   Die folgenden Hilfsprozeduren sind für den Umgang mit Paketeingaben
gedacht.

 -- Scheme-Prozedur: lookup-package-input PAKET NAME
 -- Scheme-Prozedur: lookup-package-native-input PAKET NAME
 -- Scheme-Prozedur: lookup-package-propagated-input PAKET NAME
 -- Scheme-Prozedur: lookup-package-direct-input PAKET NAME
     NAME unter den (nativen, propagierten, direkten) Eingaben von PAKET
     suchen und die Eingabe zurückliefern, wenn sie gefunden wird,
     ansonsten ‘#f’.

     NAME ist der Name eines Pakets, von dem eine Abhängigkeit besteht.
     So benutzen Sie die Prozeduren:

          (use-modules (guix packages) (gnu packages base))

          (lookup-package-direct-input coreutils "gmp")
          ⇒ #<package gmp@6.2.1 …>

     In diesem Beispiel erhalten wir das ‘gmp’-Paket, das zu den
     direkten Eingaben von ‘coreutils’ gehört.

   Manchmal werden Sie die Liste der zur Entwicklung an einem Paket
nötigen Eingaben brauchen, d.h. alle Eingaben, die beim Kompilieren des
Pakets sichtbar gemacht werden. Diese Liste wird von der Prozedur
‘package-development-inputs’ geliefert.

 -- Scheme-Prozedur: package-development-inputs PAKET [SYSTEM] [#:target
          #f] Liefert die Liste derjenigen Eingaben, die das
     PAKET zu Entwicklungszwecken für SYSTEM braucht. Wenn TARGET wahr
     ist, muss dafür ein Ziel wie das GNU-Tripel ‘"aarch64-linux-gnu"’
     übergeben werden, damit die Eingaben zum Cross-Kompilieren von
     PAKET zurückgeliefert werden.

     Beachten Sie, dass dazu sowohl explizite als auch implizite
     Eingaben gehören. Mit impliziten Eingaben meinen wir solche, die
     vom Erstellungssystem automatisch hinzugefügt werden (siehe *note
     Erstellungssysteme::). Nehmen wir das Paket ‘hello’ zur
     Illustration:

          (use-modules (gnu packages base) (guix packages))

          hello
          ⇒ #<package hello@2.10 gnu/packages/base.scm:79 7f585d4f6790>

          (package-direct-inputs hello)
          ⇒ ()

          (package-development-inputs hello)
          ⇒ (("source" …) ("tar" #<package tar@1.32 …>) …)

     Für dieses Beispiel liefert ‘package-direct-inputs’ die leere Liste
     zurück, weil ‘hello’ keinerlei explizite Abhängigkeiten hat. Zu
     ‘package-development-inputs’ gehören auch durch ‘gnu-build-system’
     implizit hinzugefügte Eingaben, die für die Erstellung von ‘hello’
     gebraucht werden, nämlich tar, gzip, GCC, libc, Bash und weitere.
     Wenn Sie sich das anschauen wollen, zeigt Ihnen ‘guix graph hello’
     die expliziten Eingaben, dagegen zeigt ‘guix graph -t bag hello’
     auch die impliziten Eingaben (siehe *note Aufruf von guix graph::).

   Weil Pakete herkömmliche Scheme-Objekte sind, die einen vollständigen
Abhängigkeitsgraphen und die zugehörigen Erstellungsprozeduren umfassen,
bietet es sich oftmals an, Prozeduren zu schreiben, die ein Paket
entgegennehmen und in Abhängigkeit bestimmter Parameter eine abgeänderte
Fassung desselben zurückliefern. Es folgen einige Beispiele.

 -- Scheme-Prozedur: package-with-c-toolchain PAKET TOOLCHAIN
     Liefert eine Variante des PAKETs, die die angegebene TOOLCHAIN
     anstelle der vorgegebenen GNU-C/C++-Toolchain benutzt. Als
     TOOLCHAIN muss eine Liste von Eingaben (als Tupel aus Bezeichnung
     und bezeichnetem Paket) angegeben werden, die eine gleichartige
     Funktion erfüllen, wie zum Beispiel das Paket ‘gcc-toolchain’.

     Das folgende Beispiel liefert eine Variante des Pakets ‘hello’, die
     mit GCC 10.x und den übrigen Komponenten der GNU-Toolchain
     (Binutils und GNU-C-Bibliothek) erstellt wurde statt mit der
     vorgegebenen Toolchain:

          (let ((toolchain (specification->package "gcc-toolchain@10")))
            (package-with-c-toolchain hello `(("toolchain" ,toolchain))))

     Die Erstellungs-Toolchain gehört zu den “impliziten Eingaben” von
     Paketen – sie wird normalerweise nicht ausdrücklich unter den
     verschiedenen „inputs“-Feldern mit verschiedenen Arten von Eingaben
     aufgeführt, stattdessen kommt sie über das Erstellungssystem dazu.
     Daher funktioniert diese Prozedur intern so, dass sie das
     Erstellungssystem des PAKETs verändert, damit es die ausgewählte
     TOOLCHAIN statt der vorgegebenen benutzt. Siehe *note
     Erstellungssysteme:: für weitere Informationen zu
     Erstellungssystemen.


File: guix.de.info,  Node: „origin“-Referenz,  Prev: „package“-Referenz,  Up: Pakete definieren

9.2.2 ‘origin’-Referenz
-----------------------

In diesem Abschnitt werden Paketursprünge – englisch “Origins” –
beschrieben. Eine ‘origin’-Deklaration legt Daten fest, die „produziert“
werden müssen – normalerweise heißt das heruntergeladen. Die
Hash-Prüfsumme von deren Inhalt muss dabei im Voraus bekannt sein.
Ursprünge werden in erster Linie benutzt, um den Quellcode von Paketen
zu repräsentieren (siehe *note Pakete definieren::). Aus diesem Grund
können Sie mit der ‘origin’-Form Patches angeben, die auf den
ursprünglichen Quellcode angewandt werden sollen, oder auch Schnipsel
von Code, der Veränderungen daran vornimmt.

 -- Datentyp: origin
     Mit diesem Datentyp wird ein Ursprung, von dem Quellcode geladen
     werden kann, beschrieben.

     ‘uri’
          Ein Objekt, was die URI des Quellcodes enthält. Der Objekttyp
          hängt von der ‘Methode’ ab (siehe unten). Zum Beispiel sind,
          wenn die URL-FETCH-Methode aus ‘(guix download)’ benutzt wird,
          die gültigen Werte für ‘uri’: eine URL dargestellt als
          Zeichenkette oder eine Liste solcher URLs.

     ‘method’
          Eine monadische Prozedur, um die angegebene URL zu benutzen.
          Die Prozedur muss mindestens drei Argumente akzeptieren: den
          Wert des ‘uri’-Feldes, den Hash-Algorithmus und den Hash-Wert,
          der im ‘hash’-Feld angegeben wird. Sie muss ein Store-Objekt
          oder eine Ableitung in der Store-Monade liefern (siehe *note
          Die Store-Monade::). Die meisten Methoden liefern eine
          Ableitung mit fester Ausgabe (siehe *note Ableitungen::).

          Zu den häufig benutzten Methoden gehören ‘url-fetch’, das
          Daten von einer URL lädt, und ‘git-fetch’, das Daten aus einem
          Git-Repository lädt (siehe unten).

     ‘sha256’
          Ein Byte-Vektor mit dem SHA-256-Hash des Quellcodes. Seine
          Funktion ist dieselbe wie das Angeben eines
          ‘content-hash’-SHA256-Objekts im weiter unten beschriebenen
          ‘hash’-Feld.

     ‘hash’
          Das ‘content-hash’-Objekt des Quellcodes. Siehe unten für eine
          Erklärung, wie Sie ‘content-hash’ benutzen.

          Diese Informationen liefert Ihnen der Befehl ‘guix download’
          (siehe *note Aufruf von guix download::) oder ‘guix hash’
          (siehe *note Aufruf von guix hash::).

     ‘file-name’ (Vorgabe: ‘#f’)
          Der Dateiname, unter dem der Quellcode abgespeichert werden
          soll. Wenn er auf ‘#f’ steht, wird ein vernünftiger Name
          automatisch gewählt. Falls der Quellcode von einer URL geladen
          wird, wird der Dateiname aus der URL genommen. Wenn der
          Quellcode von einem Versionskontrollsystem bezogen wird,
          empfiehlt es sich, den Dateinamen ausdrücklich anzugeben, weil
          dann keine sprechende Benennung automatisch gefunden werden
          kann.

     ‘patches’ (Vorgabe: ‘'()’)
          Eine Liste von Dateinamen, Ursprüngen oder dateiähnlichen
          Objekten (siehe *note dateiartige Objekte: G-Ausdrücke.) mit
          Patches, welche auf den Quellcode anzuwenden sind.

          Die Liste von Patches kann nicht von Parametern der Erstellung
          abhängen. Insbesondere kann sie nicht vom Wert von
          ‘%current-system’ oder ‘%current-target-system’ abḧängen.

     ‘snippet’ (Vorgabe: ‘#f’)
          Ein im Quellcode-Verzeichnis auszuführender G-Ausdruck (siehe
          *note G-Ausdrücke::) oder S-Ausdruck. Hiermit kann der
          Quellcode bequem modifiziert werden, manchmal ist dies
          bequemer als mit einem Patch.

     ‘patch-flags’ (Vorgabe: ‘'("-p1")’)
          Eine Liste der Befehlszeilenoptionen, die dem ‘patch’-Befehl
          übergeben werden sollen.

     ‘patch-inputs’ (Vorgabe: ‘#f’)
          Eingabepakete oder -ableitungen für den Patch-Prozess. Bei
          ‘#f’ werden die üblichen Patcheingaben wie GNU Patch
          bereitgestellt.

     ‘modules’ (Vorgabe: ‘'()’)
          Eine Liste von Guile-Modulen, die während des Patch-Prozesses
          und während der Ausführung des ‘snippet’-Felds geladen sein
          sollen.

     ‘patch-guile’ (Vorgabe: ‘#f’)
          Welches Guile-Paket für den Patch-Prozess benutzt werden soll.
          Bei ‘#f’ wird ein vernünftiger Vorgabewert angenommen.

 -- Datentyp: content-hash WERT [ALGORITHMUS]
     Erzeugt ein Inhaltshash-Objekt für den gegebenen ALGORITHMUS und
     benutzt dabei den WERT als dessen Hashwert. Wenn kein ALGORITHMUS
     angegeben wird, wird ‘sha256’ angenommen.

     Als WERT kann ein Zeichenketten-Literal, was base32-dekodiert wird,
     oder ein Byte-Vektor angegeben werden.

     Folgende Formen sind äquivalent:

          (content-hash "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj")
          (content-hash "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj"
                        sha256)
          (content-hash (base32
                         "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj"))
          (content-hash (base64 "kkb+RPaP7uyMZmu4eXPVkM4BN8yhRd8BTHLslb6f/Rc=")
                        sha256)

     Als interne Implementierung wird für ‘content-hash’ derzeit ein
     Makro benutzt. Es überprüft, wenn möglich, zum Zeitpunkt der
     Makroumschreibung, ob die Angaben in Ordnung sind, z.B. ob der WERT
     die richtige Größe für den angegebenen ALGORITHMUS hat.

   Wie wir oben gesehen haben, hängt es von der im ‘method’-Feld
angegebenen Methode ab, wie die in einem Paketursprung verwiesenen Daten
geladen werden. Das Modul ‘(guix download)’ stellt die am häufigsten
benutzte Methode zur Verfügung, nämlich ‘url-fetch’, die im Folgenden
beschrieben wird.

 -- Scheme-Prozedur: url-fetch URL HASH-ALGO HASH [name] [#:executable?
          #f] Liefert eine Ableitung mit fester Ausgabe, die
     Daten von der URL lädt (einer Zeichenkette oder Liste von
     Zeichenketten für alternativ mögliche URLs). Es wird erwartet, dass
     die Daten HASH als Prüfsumme haben, gemäß dem Algorithmus, der in
     HASH-ALGO (einem Symbol) angegebenen wurde. Nach Vorgabe ergibt
     sich der Dateiname aus dem Basisnamen der URL; optional kann in
     NAME ein anderslautender Name festgelegt werden. Wenn EXECUTABLE?
     wahr ist, wird die heruntergeladene Datei als ausführbar markiert.

     Wenn eine der URL mit ‘mirror://’ beginnt, wird der „Host Part“ an
     deren Anfang als Name eines Spiegelserver-Schemas aufgefasst, wie
     es in ‘%mirror-file’ steht.

     Alternativ wird, wenn die URL mit ‘file://’ beginnt, der zugehörige
     Dateiname in den Store eingefügt und zurückgeliefert.

   Ebenso ist im Modul ‘(guix git-download)’ die ‘git-fetch’-Methode für
Paketursprünge definiert. Sie lädt Daten aus einem Repository des
Versionskontrollsystems Git. Der Datentyp ‘git-reference’ beschreibt
dabei das Repository und den daraus zu ladenden Commit.

 -- Scheme-Prozedur: git-fetch REF HASH-ALGO HASH
     Liefert eine Ableitung mit fester Ausgabe, die REF lädt, ein
     ‘<git-reference>’-Objekt. Es wird erwartet, dass die Ausgabe
     rekursiv die Prüfsumme HASH aufweist (ein „rekursiver Hash“) gemäß
     dem Typ HASH-ALGO (einem Symbol). Als Dateiname wird NAME
     verwendet, oder ein generischer Name, falls NAME ‘#f’ ist.

 -- Datentyp: git-reference
     Dieser Datentyp steht für eine Git-Referenz, die ‘git-fetch’ laden
     soll.

     ‘url’
          Die URL des zu klonenden Git-Repositorys.

     ‘commit’
          Diese Zeichenkette gibt entweder den zu ladenden Commit an
          (als Zeichenkette aus Hexadezimalzeichen) oder sie entspricht
          dem zu ladenden Tag. Sie können auch eine „kurze“
          Commit-Zeichenkette oder einen Bezeichner wie von ‘git
          describe’, z.B. ‘v1.0.1-10-g58d7909c97’, verwenden.

     ‘recursive?’ (Vorgabe: ‘#f’)
          Dieser boolesche Wert gibt an, ob Git-Submodule rekursiv
          geladen werden sollen.

     Im folgenden Beispiel wird der Tag ‘v2.10’ des Repositorys für
     GNU Hello bezeichnet:

          (git-reference
            (url "https://git.savannah.gnu.org/git/hello.git")
            (commit "v2.10"))

     Das ist äquivalent zu folgender Referenz, wo der Commit
     ausdrücklich benannt wird:

          (git-reference
            (url "https://git.savannah.gnu.org/git/hello.git")
            (commit "dc7dc56a00e48fe6f231a58f6537139fe2908fb9"))

   Bei Mercurial-Repositorys finden Sie im Modul ‘(guix hg-download)’
Definitionen für die Methode ‘hg-fetch’ für Paketursprünge sowie den
Datentyp ‘hg-reference’. Mit ihnen wird das Versionskontrollsystem
Mercurial unterstützt.

 -- Scheme-Prozedur: hg-fetch REF HASH-ALGO HASH [Name] Liefert eine
          Ableitung mit fester Ausgabe, die REF lädt, ein
     ‘<hg-reference>’-Objekt. Es wird erwartet, dass die Ausgabe
     rekursiv die Prüfsumme HASH aufweist (ein „rekursiver Hash“) gemäß
     dem Typ HASH-ALGO (einem Symbol). Als Dateiname wird NAME
     verwendet, oder ein generischer Name, falls NAME ‘#false’ ist.


File: guix.de.info,  Node: Paketvarianten definieren,  Next: Manifeste verfassen,  Prev: Pakete definieren,  Up: Programmierschnittstelle

9.3 Paketvarianten definieren
=============================

Eine der schönen Sachen an Guix ist, dass Sie aus einer Paketdefinition
leicht Varianten desselben Pakets _ableiten_ können – solche, die vom
Anbieter eine andere Paketversion nehmen, als im Guix-Repository
angegeben, solche mit anderen Abhängigkeiten, anders gearteten
Compiler-Optionen und mehr. Manche dieser eigenen Pakete lassen sich
direkt aus der Befehlszeile definieren (siehe *note
Paketumwandlungsoptionen::). Dieser Abschnitt beschreibt, wie man
Paketvarianten mit Code definiert. Das kann in „Manifesten“ nützlich
sein (siehe *note Manifeste verfassen::) und in Ihrer eigenen
Paketsammlung (siehe *note Einen Kanal erstellen::), unter anderem!

   Wie zuvor erörtert, sind Pakete Objekte erster Klasse in der
Scheme-Sprache. Das Modul ‘(guix packages)’ stellt das
‘package’-Konstrukt zur Verfügung, mit dem neue Paketobjekte definiert
werden können (siehe *note „package“-Referenz::). Am einfachsten ist es,
eine Paketvariante zu definieren, indem Sie das ‘inherit’-Schlüsselwort
mit einem ‘package’-Objekt verwenden. Dadurch können Sie die Felder
einer Paketdefinition erben lassen, aber die Felder selbst festlegen,
die Sie festlegen möchten.

   Betrachten wir zum Beispiel die Variable ‘hello’, die eine Definition
für die aktuelle Version von GNU Hello enthält. So können Sie eine
Variante für Version 2.2 definieren (welche 2006 veröffentlicht wurde –
ein guter Jahrgang!):

     (use-modules (gnu packages base))    ;für „hello“

     (define hello-2.2
       (package
         (inherit hello)
         (version "2.2")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0lappv4slgb5spyqbh6yl5r013zv72yqg2pcl30mginf3wdqd8k9"))))))

   Das obige Beispiel entspricht dem, was Sie mit der
Paketumwandlungsoption ‘--with-source’ erreichen können. Im Kern erhält
‘hello-2.2’ alle Felder von ‘hello’ mit Ausnahme von ‘version’ und
‘source’, die ersetzt werden (die beiden unterliegen einem „Override“).
Beachten Sie, dass es die ursprüngliche ‘hello’-Variable weiterhin gibt,
sie bleibt unverändert in dem Modul ‘(gnu packages base)’. Wenn Sie auf
diese Weise ein eigenes Paket definieren, fügen Sie tatsächlich eine
neue Paketdefinition hinzu; das Original bleibt erhalten.

   Genauso gut können Sie Varianten mit einer anderen Menge von
Abhängigkeiten als im ursprünglichen Paket definieren. Zum Beispiel
hängt das vorgegebene ‘gdb’-Paket von ‘guile’ ab, aber weil es eine
optionale Abhängigkeit ist, können Sie eine Variante definieren, die
jene Abhängigkeit entfernt, etwa so:

     (use-modules (gnu packages gdb))   ;für „gdb“

     (define gdb-sans-guile
       (package
         (inherit gdb)
         (inputs (modify-inputs (package-inputs gdb)
                   (delete "guile")))))

   Mit obiger ‘modify-inputs’-Form wird das ‘"guile"’-Paket aus den
Eingaben im ‘inputs’-Feld von ‘gdb’ entfernt. Das ‘modify-inputs’-Makro
hilft Ihnen, wann immer Sie etwas aus den Paketeingaben entfernen,
hinzufügen oder ersetzen möchten.

 -- Scheme-Syntax: modify-inputs EINGABEN KLAUSELN
     Ändert die übergebenen Paketeingaben, die ‘package-inputs’ & Co.
     liefern können, entsprechend der angegebenen Klauseln. Jede Klausel
     muss eine der folgenden Formen aufweisen:

     ‘(delete NAME…)’
          Die Pakete mit den angegebenen NAMEn (als Zeichenketten) aus
          den Eingaben entfernen.

     ‘(prepend PAKET…)’
          Jedes PAKET vorne an die Eingabenliste anstellen.

     ‘(append PAKET…)’
          Jedes PAKET am Ende der Eingabenliste anhängen.

     Mit folgendem Beispiel werden die Eingaben GMP und ACL unter denen
     von Coreutils weggelassen und libcap wird an dem Anfang
     hinzugefügt:

          (modify-inputs (package-inputs coreutils)
            (delete "gmp" "acl")
            (prepend libcap))

     Mit folgendem Beispiel wird das ‘guile’-Paket unter den Eingaben
     von ‘guile-redis’ weggelassen und stattdessen wird ‘guile-2.2’
     verwendet:

          (modify-inputs (package-inputs guile-redis)
            (replace "guile" guile-2.2))

     Die letzte Art Klausel ist ‘append’, was bedeutet, dass Eingaben
     hinten an die Liste angehängt werden.

   Manchmal bietet es sich an, Funktionen (also „Prozeduren“, wie
Scheme-Anwender sagen) zu schreiben, die ein Paket abhängig von
bestimmten Parametern zurückliefern. Als Beispiel betrachten wir die
‘luasocket’-Bibliothek für die Programmiersprache Lua. Wir möchten
‘luasocket’-Pakete für die hauptsächlichen Versionen von Lua verfügbar
machen. Eine Möglichkeit, das zu erreichen, ist, eine Prozedur zu
definieren, die ein Lua-Paket nimmt und ein von diesem abhängiges
‘luasocket’-Paket liefert.

     (define (make-lua-socket name lua)
       ;; Liefert ein luasocket-Paket, das mit LUA erstellt wird.
       (package
         (name name)
         (version "3.0")
         ;; hier würden noch ein paar Felder stehen
         (inputs (list lua))
         (synopsis "Socket library for Lua")))

     (define-public lua5.1-socket
       (make-lua-socket "lua5.1-socket" lua-5.1))

     (define-public lua5.2-socket
       (make-lua-socket "lua5.2-socket" lua-5.2))

   Damit haben wir Pakete ‘lua5.1-socket’ und ‘lua5.2-socket’ definiert,
indem wir ‘make-lua-socket’ mit verschiedenen Argumenten aufgerufen
haben. Siehe *note (guile)Procedures:: für mehr Informationen über
Prozeduren. Weil wir mit ‘define-public’ öffentlich sichtbare
Definitionen auf oberster Ebene („top-level“) für diese beiden Pakete
angegeben haben, kann man sie von der Befehlszeile aus benutzen (siehe
*note Paketmodule::).

   Bei diesen handelt es sich um sehr einfache Paketvarianten. Bequemer
ist es dann, mit dem Modul ‘(guix transformations)’ eine hochsprachliche
Schnittstelle einzusetzen, die auf die komplexeren
Paketumwandlungsoptionen direkt abbildet (siehe *note
Paketumwandlungsoptionen::):

 -- Scheme-Prozedur: options->transformation OPTIONEN
     Liefert eine Prozedur, die gegeben ein zu erstellendes Objekt (ein
     Paket, eine Ableitung oder Ähnliches) die durch OPTIONEN
     festgelegten Umwandlungen daran umsetzt und die sich ergebenden
     Objekte zurückliefert. OPTIONEN muss eine Liste von Paaren aus
     Symbol und Zeichenkette sein wie:

          ((with-branch . "guile-gcrypt=master")
           (without-tests . "libgcrypt"))

     Jedes Symbol benennt eine Umwandlung. Die entsprechende
     Zeichenkette ist ein Argument an diese Umwandlung.

   Zum Beispiel wäre ein gleichwertiges Manifest zu diesem Befehl:

     guix build guix \
       --with-branch=guile-gcrypt=master \
       --with-debug-info=zlib

… dieses hier:

     (use-modules (guix transformations))

     (define transform
       ;; Die Prozedur zur Paketumwandlung.
       (options->transformation
        '((with-branch . "guile-gcrypt=master")
          (with-debug-info . "zlib"))))

     (packages->manifest
      (list (transform (specification->package "guix"))))

   Die Prozedur ‘options->transformation’ lässt sich einfach benutzen,
ist aber vielleicht nicht so flexibel, wie Sie es sich wünschen. Wie
sieht ihre Implementierung aus? Aufmerksamen Lesern mag aufgefallen
sein, dass die meisten Paketumwandlungen die oberflächlichen Änderungen
aus den ersten Beispielen in diesem Abschnitt übersteigen: Sie
“schreiben Eingaben um”, was im Abhängigkeitsgraphen bestimmte Eingaben
durch andere ersetzt.

   Das Umschreiben des Abhängigkeitsgraphen, damit Pakete im Graphen
ausgetauscht werden, ist in der Prozedur ‘package-input-rewriting’ aus
‘(guix packages)’ implementiert.

 -- Scheme-Prozedur: package-input-rewriting ERSETZUNGEN
          [UMGESCHRIEBENER-NAME] [#:deep? #t] Eine Prozedur liefern, die
          für ein
     ihr übergebenes Paket dessen direkte und indirekte Abhängigkeit
     gemäß den ERSETZUNGEN umschreibt, einschließlich ihrer impliziten
     Eingaben, wenn DEEP? wahr ist. ERSETZUNGEN ist eine Liste von
     Paketpaaren; das erste Element eines Paares ist das zu ersetzende
     Paket und das zweite ist, wodurch es ersetzt werden soll.

     Optional kann als UMGESCHRIEBENER-NAME eine ein Argument nehmende
     Prozedur angegeben werden, die einen Paketnamen nimmt und den Namen
     nach dem Umschreiben zurückliefert.

Betrachten Sie dieses Beispiel:

     (define libressl-statt-openssl
       ;; Dies ist eine Prozedur, mit der OPENSSL durch LIBRESSL
       ;; rekursiv ersetzt wird.
       (package-input-rewriting `((,openssl . ,libressl))))

     (define git-mit-libressl
       (libressl-statt-openssl git))

Hier definieren wir zuerst eine Umschreibeprozedur, die OPENSSL durch
LIBRESSL ersetzt. Dann definieren wir damit eine “Variante” des
GIT-Pakets, die LIBRESSL statt OPENSSL benutzt. Das ist genau, was auch
die Befehlszeilenoption ‘--with-input’ tut (siehe *note ‘--with-input’:
Paketumwandlungsoptionen.).

   Die folgende Variante von ‘package-input-rewriting’ kann für die
Ersetzung passende Pakete anhand ihres Namens finden, statt zu prüfen,
ob der Wert identisch ist.

 -- Scheme-Prozedur: package-input-rewriting/spec ERSETZUNGEN [#:deep?
          #t]
     Liefert eine Prozedur, die für ein gegebenes Paket die angegebenen
     ERSETZUNGEN auf dessen gesamten Paketgraphen anwendet
     (einschließlich impliziter Eingaben, außer wenn DEEP? falsch ist).
     ERSETZUNGEN muss dabei eine Liste von Paaren aus je einer
     Spezifikation und Prozedur sein. Dabei ist jede Spezifikation eine
     Paketspezifikation wie ‘"gcc"’ oder ‘"guile@2"’ und jede Prozedur
     nimmt ein passendes Paket und liefert dafür einen Ersatz für das
     Paket.

   Das obige Beispiel könnte auch so geschrieben werden:

     (define libressl-statt-openssl
       ;; Rekursiv alle Pakete namens "openssl" durch LibreSSL ersetzen.
       (package-input-rewriting/spec `(("openssl" . ,(const libressl)))))

   Der Hauptunterschied ist hier, dass diesmal Pakete zur Spezifikation
passen müssen und nicht deren Wert identisch sein muss, damit sie
ersetzt werden. Mit anderen Worten wird jedes Paket im Graphen ersetzt,
das ‘openssl’ heißt.

   Eine allgemeiner anwendbare Prozedur, um den Abhängigkeitsgraphen
eines Pakets umzuschreiben, ist ‘package-mapping’. Sie unterstützt
beliebige Änderungen an den Knoten des Graphen.

 -- Scheme-Prozedur: package-mapping PROZEDUR [SCHNITT?] [#:deep? #f]
     Liefert eine Prozedur, die, wenn ihr ein Paket übergeben wird, die
     an ‘package-mapping’ übergebene PROZEDUR auf alle vom Paket
     abhängigen Pakete anwendet. Die Prozedur liefert das resultierende
     Paket. Wenn SCHNITT? für ein Paket davon einen wahren Wert liefert,
     findet kein rekursiver Abstieg in dessen Abhängigkeiten statt.
     Steht DEEP? auf wahr, wird die PROZEDUR auch auf implizite Eingaben
     angewandt.


File: guix.de.info,  Node: Manifeste verfassen,  Next: Erstellungssysteme,  Prev: Paketvarianten definieren,  Up: Programmierschnittstelle

9.4 Manifeste verfassen
=======================

Sie können die Paketlisten für ‘guix’-Befehle auf der Befehlszeile
angeben. Das ist bequem, bis die Paketlisten länger und weniger trivial
werden. Dann nämlich wird es bald bequemer, die Paketliste in einer Form
zu haben, die wir ein “Manifest” nennen. Neudeutsch kann man ein
Manifest wie eine „Bill of Materials“, eine Stückliste oder Güterliste
auffassen, womit ein Satz von Paketen festgelegt wird. Im Normalfall
denken Sie sich ein Code-Schnipsel aus, mit dem das Manifest erstellt
wird, bringen den Code in einer Datei unter, sagen wir ‘manifest.scm’,
und übergeben diese Datei mit der Befehlszeilenoption ‘-m’ (oder
‘--manifest’), die von vielen ‘guix’-Befehlen unterstützt wird. Zum
Beispiel könnte so ein Manifest für einen einfachen Satz Pakete
aussehen:

     ;; Manifest dreier Pakete.
     (specifications->manifest '("gcc-toolchain" "make" "git"))

   Sobald Sie das Manifest haben, können Sie es an z.B. ‘guix package’
übergeben, was dann nur genau diese drei Pakete in Ihr Profil
installiert (siehe *note die Befehlszeilenoption ‘-m’ von ‘guix
package’: profile-manifest.):

     guix package -m manifest.scm

… oder Sie übergeben das Manifest an ‘guix shell’ (siehe *note die
Befehlszeilenoption ‘-m’ von ‘guix shell’: shell-manifest.) und richten
sich so eine vergängliche Umgebung ein:

     guix shell -m manifest.scm

… oder Sie übergeben das Manifest an ‘guix pack’, was ziemlich genauso
geht (siehe *note die Befehlszeilenoption ‘-m’ von ‘guix pack’:
pack-manifest.). Ein Manifest können Sie unter Versionskontrolle stellen
oder es mit anderen Teilen, um deren System schnell auf den gleichen
Stand zu bringen, und vieles mehr.

   Doch wie schreibt man eigentlich sein erstes Manifest? Für den Anfang
möchten Sie vielleicht ein Manifest, das dem nachempfunden ist, was Sie
schon in einem Ihrer Profile haben. Statt bei null anzufangen, können
Sie sich mit ‘guix package’ ein Manifest generieren lassen (siehe *note
‘guix package --export-manifest’: export-manifest.):

     # Wir schreiben in 'manifest.scm' ein Manifest, das dem
     # Standardprofil ~/.guix-profile entspricht.
     guix package --export-manifest > manifest.scm

   Oder vielleicht möchten Sie die Argumente von der Befehlszeile in ein
Manifest übertragen. Dabei kann ‘guix shell’ helfen (siehe *note ‘guix
shell --export-manifest’: shell-export-manifest.):

     # Wir schreiben ein Manifest für die auf der Befehlszeile
     # angegebenen Pakete.
     guix shell --export-manifest gcc-toolchain make git > manifest.scm

   In beiden Fällen werden bei der Befehlszeilenoption
‘--export-manifest’ etliche Feinheiten berücksichtigt, um ein
originalgetreues Manifest zu erzeugen. Insbesondere werden
Paketumwandlungsoptionen wiedergegeben (siehe *note
Paketumwandlungsoptionen::).

     Anmerkung: Manifeste sind _symbolisch_: Sie beziehen sich auf die
     Pakete, die in den _aktuell verwendeten_ Kanälen enthalten sind
     (siehe *note Kanäle::). Im obigen Beispiel bezieht sich
     ‘gcc-toolchain’ heute vielleicht auf Version 11, aber in zwei
     Jahren kann es Version 13 heißen.

     Wenn Sie wollen, dass immer dieselben Paketversionen und -varianten
     in Ihre Software-Umgebung aufgenommen werden, sind mehr
     Informationen nötig, nämlich welche Kanalversionen zur Zeit in
     Benutzung sind. Das sagt uns ‘guix describe’. Siehe *note Guix
     nachbilden:: für weitere Informationen.

   Sobald Sie sich Ihr erstes Manifest beschafft haben, möchten Sie
vielleicht Anpassungen daran vornehmen. Da es sich beim Manifest um Code
handelt, stehen Ihnen alle Guix-Programmierschnittstellen zur Verfügung!

   Nehmen wir an, Sie hätten gerne ein Manifest, um eine angepasste
Variante von GDB, dem GNU-Debugger, einzusetzen, die von Guile _nicht_
abhängt, zusammen mit noch einem anderen Paket. Um auf dem Beispiel aus
dem vorigen Abschnitt aufzubauen (siehe *note Paketvarianten
definieren::), können Sie das Manifest z.B. folgendermaßen schreiben:

     (use-modules (guix packages)
                  (gnu packages gdb)               ;für 'gdb'
                  (gnu packages version-control))  ;für 'git'

     ;; Eine Variante von GDB ohne Abhängigkeit von Guile definieren.
     (define gdb-sans-guile
       (package
         (inherit gdb)
         (inputs (modify-inputs (package-inputs gdb)
                   (delete "guile")))))

     ;; Liefert ein Manifest mit diesem Paket und außerdem Git.
     (packages->manifest (list gdb-sans-guile git))

   Beachten Sie, in diesem Beispiel nimmt das Manifest direkt Bezug auf
die Variablen ‘gdb’ und ‘git’, die an je ein Paketobjekt vom Typ
‘package’ gebunden sind (siehe *note „package“-Referenz::), statt wie
zuvor ‘specifications->manifest’ aufzurufen und damit die Pakete anhand
deren Namens zu finden. Die ‘use-modules’-Form am Dateianfang gibt uns
Zugriff auf den Kern der Paketschnittstelle (siehe *note Pakete
definieren::) und die Module, in denen ‘gdb’ und ‘git’ definiert sind
(siehe *note Paketmodule::). Nahtlos können wir all dies miteinander
verknüpfen – grenzenlose Möglichkeiten eröffnen sich; lassen Sie Ihrer
Kreativität freien Lauf!

   Der Datentyp für Manifeste sowie Prozeduren, um mit ihm umzugehen,
sind definiert im Modul ‘(guix profiles)’. In Code, den Sie mit ‘-m’
übergeben, wird es automatisch verfügbar gemacht. Nun folgt die Referenz
dazu.

 -- Datentyp: manifest
     Der Datentyp, der ein Manifest repräsentiert.

     Zurzeit gibt es darin ein Feld:

     ‘entries’
          Dies muss eine Liste von ‘manifest-entry’-Verbundsobjekten
          sein, wie hier beschrieben.

 -- Datentyp: manifest-entry
     Der Datentyp steht für einen Eintrag im Manifest. Zu so einem
     Manifesteintrag gehören im Wesentlichen Metadaten: der Name und die
     Version als Zeichenkette, das Objekt selbst (meistens ein Paket),
     welche Ausgabe man davon haben will (siehe *note Pakete mit
     mehreren Ausgaben.::) und noch ein paar optionale Informationen,
     wie wir im Folgenden näher ausführen.

     Die meiste Zeit basteln Sie sich die Manifesteinträge nicht selber
     zusammen, sondern Sie übergeben ein Paket an
     ‘package->manifest-entry’, siehe unten. Aber es könnte Ihnen ein
     außergewöhnlicher Fall unterkommen, wo Sie einen Manifesteintrag
     für etwas erzeugen wollen, das _kein_ Paket ist, wie in diesem
     Beispiel:

          ;; Für ein Nicht-Paketobjekt einen einzelnen Manifesteintrag von Hand schreiben.
          (let ((hello (program-file "hello" #~(display "Hi!"))))
            (manifest-entry
              (name "foo")
              (version "42")
              (item
               (computed-file "verzeichnis-mit-hello"
                               #~(let ((bin (string-append #$output "/bin")))
                                   (mkdir #$output) (mkdir bin)
                                    (symlink #$hello
                                             (string-append bin "/hello")))))))

     Diese Felder stehen zur Verfügung:

     ‘name’
     ‘version’
          Name und Version für diesen Eintrag als Zeichenkette.

     ‘item’
          Ein Paket oder anderes dateiartiges Objekt (siehe *note
          dateiartige Objekte: G-Ausdrücke.).

     ‘output’ (Vorgabe: ‘"out"’)
          Welche der Ausgaben von ‘item’ genommen werden soll, sofern
          ‘item’ mehrere Ausgaben umfasst (siehe *note Pakete mit
          mehreren Ausgaben.::).

     ‘dependencies’ (Vorgabe: ‘'()’)
          Die Liste der Manifesteinträge, von denen dieser Eintrag
          abhängt. Wenn ein Profil erstellt wird, werden die
          aufgeführten Abhängigkeiten zum Profil hinzugefügt.

          In der Regel landen die propagierten Eingaben eines Pakets
          (siehe *note ‘propagated-inputs’: „package“-Referenz.) in je
          einem Manifesteintrag unter den Abhängigkeiten des
          Manifesteintrags des Pakets.

     ‘search-paths’ (Vorgabe: ‘'()’)
          Die Liste der Suchpfadspezifikationen, die für diesen Eintrag
          beachtet werden (siehe *note Suchpfade::).

     ‘properties’ (Vorgabe: ‘'()’)
          Eine Liste von Paaren aus jeweils einem Symbol und dem Wert
          dazu. Beim Erstellen eines Profils werden die Eigenschaften
          serialisiert.

          So kann man den Paketen zusätzliche Metadaten aufschnallen wie
          z.B. welche Umwandlungsoptionen darauf angewendet wurden
          (siehe *note Paketumwandlungsoptionen::).

     ‘parent’ (Vorgabe: ‘(delay #f)’)
          Ein Versprechen (unter englischsprechenden Schemern bekannt
          als „Promise“), das auf den übergeordneten Manifesteintrag
          zeigt.

          Es wird benutzt, um in auf Manifesteinträge in ‘dependencies’
          bezogenen Fehlermeldungen Hinweise auf den Kontext zu geben.

 -- Scheme-Prozedur: concatenate-manifests LISTE
     Fasst die Manifeste in der LISTE zu einem zusammen und liefert es
     zurück.

 -- Scheme-Prozedur: package->manifest-entry PAKET [AUSGABE]
          [#:properties] Liefert einen Manifesteintrag für die
     AUSGABE von PAKET, wobei AUSGABE als Vorgabewert ‘"out"’ hat. Als
     Eigenschaften werden die PROPERTIES benutzt; vorgegeben ist die
     leere Liste oder, wenn eine oder mehrere Paketumwandlungen auf das
     PAKET angewendet wurden, eine assoziative Liste mit diesen
     Umwandlungen, die als Argument an ‘options->transformation’ gegeben
     werden kann (siehe *note ‘options->transformation’: Paketvarianten
     definieren.).

     Mit folgendem Code-Schnipsel wird ein Manifest mit einem Eintrag
     für die Standardausgabe sowie die Ausgabe namens ‘send-email’ des
     Pakets ‘git’ erstellt:

          (use-modules (gnu packages version-control))

          (manifest (list (package->manifest-entry git)
                          (package->manifest-entry git "send-email")))

 -- Scheme-Prozedur: packages->manifest PAKETE
     Liefert eine Liste von Manifesteinträgen, jeweils einer für jedes
     Listenelement in PAKETE. In PAKETE können Paketobjekte oder Tupel
     aus Paket und Zeichenkette stehen, wobei die Zeichenkette die
     Paketausgabe angibt.

     Mithilfe dieser Prozedur kann man das obige Manifest auch kürzer
     aufschreiben:

          (use-modules (gnu packages version-control))

          (packages->manifest (list git `(,git "send-email")))

 -- Scheme-Prozedur: package->development-manifest PAKET [SYSTEM]
          [#:target] Liefert ein Manifest mit den
     “Entwicklungseingaben” des PAKETS für SYSTEM. Optional kann mit
     TARGET das Zielsystem zum Cross-Kompilieren angegeben werden. Zu
     den Entwicklungseingaben gehören die expliziten und impliziten
     Eingaben vom PAKET.

     Genau wie bei der Option ‘-D’ für ‘guix shell’ (siehe *note ‘guix
     shell -D’: shell-development-option.) beschreibt das sich daraus
     ergebende Manifest die Umgebung, um am PAKET als Entwickler
     mitzuarbeiten. Wenn Sie zum Beispiel eine Entwicklungsumgebung für
     Inkscape aufsetzen wollen und darin auch Git für die
     Versionskontrolle zur Verfügung haben möchten, geben Sie diese
     Bestandteilliste mit folgendem Manifest wieder:

          (use-modules (gnu packages inkscape)          ;für 'inkscape'
                       (gnu packages version-control))  ;für 'git'

          (concatenate-manifests
           (list (package->development-manifest inkscape)
                 (packages->manifest (list git))))

     Dieses Beispiel zeigt, wie ‘package->development-manifest’ ein
     Entwicklungsmanifest mit einem Compiler (GCC), den vielen benutzten
     Bibliotheken (Boost, GLib, GTK, etc.) und noch ein paar
     zusätzlichen Entwicklungswerkzeugen liefert – das sagen uns die von
     ‘guix show inkscape’ aufgeführten Abhängigkeiten.

   Zum Schluss sind im Modul ‘(gnu packages)’ noch Abstraktionen
enthalten, um Manifeste anzufertigen. Dazu gehört, Pakete anhand ihres
Namens zu finden – siehe unten.

 -- Scheme-Prozedur: specifications->manifest SPEZIFIKATIONEN
     Liefert ein Manifest für die SPEZIFIKATIONEN, einer Liste von
     Spezifikationen wie ‘"emacs@25.2"’ oder ‘"guile:debug"’. Das Format
     für die Spezifikationen ist dasselbe wie bei den
     Befehlszeilenwerkzeugen ‘guix install’, ‘guix package’ und so
     weiter (siehe *note Aufruf von guix package::).

     Ein Beispiel wäre diese Möglichkeit, das zuvor gezeigte
     Git-Manifest anders zu formulieren wie hier:

          (specifications->manifest '("git" "git:send-email"))

     Man bemerke, dass wir uns nicht um ‘use-modules’ kümmern müssen, um
     die richtige Auswahl von Modulen zu importieren und die richtigen
     Variablen zu referenzieren. Stattdessen nehmen wir auf Pakete
     direkt auf die Weise Bezug, die wir von der Befehlszeile kennen.
     Wie praktisch!


File: guix.de.info,  Node: Erstellungssysteme,  Next: Erstellungsphasen,  Prev: Manifeste verfassen,  Up: Programmierschnittstelle

9.5 Erstellungssysteme
======================

Jede Paketdefinition legt ein “Erstellungssystem” („build system“) sowie
dessen Argumente fest (siehe *note Pakete definieren::). Das
‘build-system’-Feld steht für die Erstellungsprozedur des Pakets sowie
für weitere implizite Eingaben für die Erstellungsprozedur.

   Erstellungssysteme sind ‘<build-system>’-Objekte. Die Schnittstelle,
um solche zu erzeugen und zu verändern, ist im Modul ‘(guix
build-system)’ zu finden, und die eigentlichen Erstellungssysteme werden
jeweils von ihren eigenen Modulen exportiert.

   Intern funktionieren Erstellungssysteme, indem erst Paketobjekte zu
“Bags” kompiliert werden. Eine Bag (deutsch: Beutel, Sack) ist wie ein
Paket, aber mit weniger Zierrat – anders gesagt ist eine Bag eine
systemnähere Darstellung eines Pakets, die sämtliche Eingaben des Pakets
einschließlich vom Erstellungssystem hinzugefügter Eingaben enthält.
Diese Zwischendarstellung wird dann zur eigentlichen Ableitung
kompiliert (siehe *note Ableitungen::). Die Prozedur
‘package-with-c-toolchain’ ist zum Beispiel eine Möglichkeit, wie die
durch das Erstellungssystem hinzugenommenen impliziten Eingaben
abgeändert werden können (siehe *note ‘package-with-c-toolchain’:
„package“-Referenz.).

   Erstellungssysteme akzeptieren optional eine Liste von “Argumenten”.
In Paketdefinitionen werden diese über das ‘arguments’-Feld übergeben
(siehe *note Pakete definieren::). Sie sind in der Regel
Schlüsselwort-Argumente (siehe *note Schlüsselwort-Argumente in Guile:
(guile)Optional Arguments.). Der Wert dieser Argumente wird
normalerweise vom Erstellungssystem in der “Erstellungsschicht”
ausgewertet, d.h. von einem durch den Daemon gestarteten Guile-Prozess
(siehe *note Ableitungen::).

   Das häufigste Erstellungssystem ist ‘gnu-build-system’, was die
übliche Erstellungsprozedur für GNU-Pakete und viele andere Pakete
darstellt. Es wird vom Modul ‘(guix build-system gnu)’ bereitgestellt.

 -- Scheme-Variable: gnu-build-system
     ‘gnu-build-system’ steht für das GNU-Erstellungssystem und
     Varianten desselben (siehe *note Konfiguration und
     Makefile-Konventionen: (standards)Configuration.).

     Kurz gefasst werden Pakete, die es benutzen, konfiguriert, erstellt
     und installiert mit der üblichen Befehlsfolge ‘./configure && make
     && make check && make install’. In der Praxis braucht man oft noch
     ein paar weitere Schritte. Alle Schritte sind in voneinander
     getrennte “Phasen” unterteilt. Siehe *note Erstellungsphasen:: für
     mehr Informationen zu Erstellungsphasen und wie man sie anpassen
     kann.

     Zusätzlich stellt dieses Erstellungssystem sicher, dass die
     „Standard“-Umgebung für GNU-Pakete zur Verfügung steht. Diese
     umfasst Werkzeuge wie GCC, libc, Coreutils, Bash, Make, Diffutils,
     grep und sed (siehe das Modul ‘(guix build-system gnu)’ für eine
     vollständige Liste). Wir bezeichnen sie als “implizite Eingaben”
     eines Pakets, weil Paketdefinitionen sie nicht aufführen müssen.

     Dieses Erstellungssystem unterstützt eine Reihe von
     Schlüsselwortargumenten, die über das ‘arguments’-Feld eines Pakets
     übergeben werden können. Hier sind einige der wichtigen Parameter:

     ‘#:phases’
          Mit diesem Argument wird erstellungsseitiger Code angegeben,
          der zu einer assoziativen Liste von Erstellungsphasen
          ausgewertet wird. Siehe *note Erstellungsphasen:: für nähere
          Informationen.

     ‘#:configure-flags’
          Diese Liste von Befehlszeilenoptionen (als Zeichenketten)
          werden dem ‘configure’-Skript übergeben. Siehe *note Pakete
          definieren:: für ein Beispiel.

     ‘#:make-flags’
          Diese Zeichenkettenliste enthält Befehlszeilenoptionen, die
          als Argumente an ‘make’-Aufrufe in den Phasen ‘build’, ‘check’
          und ‘install’ übergeben werden.

     ‘#:out-of-source?’
          Dieser Boolesche Ausdruck, nach Vorgabe steht er auf ‘#f’,
          zeigt an, ob Erstellungen in einem gesonderten
          Erstellungsverzeichnis abseits des Quellbaums ausgeführt
          werden sollen.

          Wenn es auf wahr steht, wird in der ‘configure’-Phase eigens
          ein Erstellungsverzeichnis angelegt, dorthin gewechselt und
          das ‘configure’-Skript von dort ausgeführt. Das ist nützlich
          bei Paketen, die so etwas voraussetzen, wie ‘glibc’.

     ‘#:tests?’
          Dieser Boolesche Ausdruck, nach Vorgabe steht er auf ‘#t’,
          zeigt an, ob in der ‘check’-Phase der Testkatalog des Pakets
          ausgeführt werden soll.

     ‘#:test-target’
          In dieser Zeichenkette, nach Vorgabe ‘"check"’, wird der Name
          des Makefile-Ziels angegeben, das die ‘check’-Phase benutzt.

     ‘#:parallel-build?’
     ‘#:parallel-tests?’
          Mit diesen Booleschen Werten wird festgelegt, ob die
          Erstellung respektive der Testkatalog parallel ausgeführt
          werden soll, indem die Befehlszeilenoption ‘-j’ an ‘make’
          übergeben wird. Wenn die Werte wahr sind, wird an ‘make’ die
          Option ‘-jN’ übergeben, wobei N die Zahl ist, die in der
          ‘--cores’-Befehlszeilenoption an ‘guix-daemon’ oder an den
          ‘guix’-Clientbefehl übergeben wurde (siehe *note ‘--cores’:
          Gemeinsame Erstellungsoptionen.).

     ‘#:validate-runpath?’
          Dieser Boolesche Ausdruck, nach Vorgabe ‘#t’, bestimmt, ob der
          in ELF-Binärdateien, die in der ‘install’-Phase installiert
          worden sind, eingetragene ‘RUNPATH’ „validiert“ werden soll.
          ELF-Binärdateien sind gemeinsame Bibliotheken („Shared
          Libraries“ mit Dateiendung ‘.so’) sowie ausführbare Dateien.
          Siehe *note die Phase ‘validate-runpath’:
          phase-validate-runpath. für die Details.

     ‘#:substitutable?’
          Dieser Boolesche Ausdruck, nach Vorgabe ‘#t’, sagt aus, ob
          Paketausgaben substituierbar sein sollen, d.h. ob Benutzer
          Substitute dafür beziehen können sollen, statt sie lokal
          erstellen zu müssen (siehe *note Substitute::).

     ‘#:allowed-references’
     ‘#:disallowed-references’
          Wenn für diese Argumente ein wahrer Wert angegeben wird, muss
          er einer Liste von Abhängigkeiten entsprechen, die _nicht_
          unter den Referenzen der Erstellungsergebnisse vorkommen
          dürfen. Wenn nach dem Ende der Erstellung eine solche Referenz
          noch vorhanden ist, schlägt der Erstellungsvorgang fehl.

          Sie eignen sich, um zu garantieren, dass ein Paket nicht
          fälschlich seine Abhängigkeiten aus der Erstellungszeit weiter
          referenziert, wenn das, zum Beispiel, die Größe unnötig in die
          Höhe treiben würde.

     Auch die meisten anderen Erstellungssysteme unterstützen diese
     Schlüsselwortargumente.

   Andere ‘<build-system>’-Objekte werden definiert, um andere
Konventionen und Werkzeuge von Paketen für freie Software zu
unterstützen. Die anderen Erstellungssysteme erben den Großteil vom
‘gnu-build-system’ und unterscheiden sich hauptsächlich darin, welche
Eingaben dem Erstellungsprozess implizit hinzugefügt werden und welche
Liste von Phasen durchlaufen wird. Manche dieser Erstellungssysteme sind
im Folgenden aufgeführt.

 -- Scheme-Variable: ant-build-system
     Diese Variable wird vom Modul ‘(guix build-system ant)’ exportiert.
     Sie implementiert die Erstellungsprozedur für Java-Pakete, die mit
     dem Ant build tool (https://ant.apache.org/) erstellt werden
     können.

     Sowohl ‘ant’ als auch der “Java Development Kit” (JDK), wie er vom
     Paket ‘icedtea’ bereitgestellt wird, werden zu den Eingaben
     hinzugefügt. Wenn andere Pakete dafür benutzt werden sollen, können
     sie jeweils mit den Parametern ‘#:ant’ und ‘#:jdk’ festgelegt
     werden.

     Falls das ursprüngliche Paket über keine nutzbare
     Ant-Erstellungsdatei („Ant-Buildfile“) verfügt, kann aus der Angabe
     im Parameter ‘#:jar-name’ eine minimale Ant-Erstellungsdatei
     ‘build.xml’ erzeugt werden, in der die für die Erstellung
     durchzuführenden Aufgaben (Tasks) für die Erstellung des
     angegebenen Jar-Archivs stehen. In diesem Fall kann der Parameter
     ‘#:source-dir’ benutzt werden, um das Unterverzeichnis mit dem
     Quellcode anzugeben; sein Vorgabewert ist „src“.

     Der Parameter ‘#:main-class’ kann mit einer minimalen
     Ant-Erstellungsdatei benutzt werden, um die Hauptklasse des
     resultierenden Jar-Archivs anzugeben. Dies ist nötig, wenn die
     Jar-Datei ausführbar sein soll. Mit dem Parameter ‘#:test-include’
     kann eine Liste angegeben werden, welche Junit-Tests auszuführen
     sind. Der Vorgabewert ist ‘(list "**/*Test.java")’. Mit
     ‘#:test-exclude’ kann ein Teil der Testdateien ignoriert werden.
     Der Vorgabewert ist ‘(list "**/Abstract*.java")’, weil abstrakte
     Klassen keine ausführbaren Tests enthalten können.

     Der Parameter ‘#:build-target’ kann benutzt werden, um die
     Ant-Aufgabe (Task) anzugeben, die während der ‘build’-Phase
     ausgeführt werden soll. Vorgabe ist, dass die Aufgabe (Task) „jar“
     ausgeführt wird.

 -- Scheme-Variable: android-ndk-build-system
     Diese Variable wird von ‘(guix build-system android-ndk)’
     exportiert. Sie implementiert eine Erstellungsprozedur für das
     Android NDK (Native Development Kit) benutzende Pakete mit einem
     Guix-spezifischen Erstellungsprozess.

     Für das Erstellungssystem wird angenommen, dass Pakete die zu ihrer
     öffentlichen Schnittstelle gehörenden Header-Dateien im
     Unterverzeichnis ‘include’ der Ausgabe ‘out’ und ihre Bibliotheken
     im Unterverzeichnis ‘lib’ der Ausgabe ‘out’ platzieren.

     Ebenso wird angenommen, dass es keine im Konflikt stehenden Dateien
     unter der Vereinigung aller Abhängigkeiten gibt.

     Derzeit wird Cross-Kompilieren hierfür nicht unterstützt, also wird
     dabei vorausgesetzt, dass Bibliotheken und Header-Dateien dieselben
     wie im Wirtssystem sind.

 -- Scheme-Variable: asdf-build-system/source
 -- Scheme-Variable: asdf-build-system/sbcl
 -- Scheme-Variable: asdf-build-system/ecl

     Diese Variablen, die vom Modul ‘(guix build-system asdf)’
     exportiert werden, implementieren Erstellungsprozeduren für
     Common-Lisp-Pakete, welche „ASDF“
     (https://common-lisp.net/project/asdf/) benutzen. ASDF dient der
     Systemdefinition für Common-Lisp-Programme und -Bibliotheken.

     Das Erstellungssystem ‘asdf-build-system/source’ installiert die
     Pakete in Quellcode-Form und kann via ASDF mit jeder
     Common-Lisp-Implementierung geladen werden. Die anderen
     Erstellungssysteme wie ‘asdf-build-system/sbcl’ installieren binäre
     Systeme in dem Format, das von einer bestimmten Implementierung
     verstanden wird. Diese Erstellungssysteme können auch benutzt
     werden, um ausführbare Programme zu erzeugen oder um Lisp-Abbilder
     mit einem vorab geladenen Satz von Paketen zu erzeugen.

     Das Erstellungssystem benutzt gewisse Namenskonventionen. Bei
     Binärpaketen sollte dem Paketnamen die Lispimplementierung als
     Präfix vorangehen, z.B. ‘sbcl-’ für ‘asdf-build-system/sbcl’.

     Zudem sollte das entsprechende Quellcode-Paket mit der Konvention
     wie bei Python-Paketen (siehe *note Python-Module::) ein ‘cl-’ als
     Präfix bekommen.

     Um ausführbare Programme und Abbilder zu erzeugen, können die
     erstellungsseitigen Prozeduren ‘build-program’ und ‘build-image’
     benutzt werden. Sie sollten in einer Erstellungsphase nach der
     ‘create-asdf-configuration’-Phase aufgerufen werden, damit das
     gerade erstellte System Teil des resultierenden Abbilds sein kann.
     An ‘build-program’ muss eine Liste von Common-Lisp-Ausdrücken über
     das Argument ‘#:entry-program’ übergeben werden.

     Vorgegeben ist, alle ‘.asd’-Dateien im Quellverzeichnis zu lesen,
     um zu ermitteln, welche Systeme definiert sind. Mit dem Parameter
     ‘#:asd-files’ kann die Liste zu lesender ‘.asd’-Dateien festgelegt
     werden. Außerdem wird bei Paketen, für deren Tests ein System in
     einer separaten Datei definiert wurde, dieses System geladen, bevor
     die Tests ablaufen, wenn es im Parameter ‘#:test-asd-file’ steht.
     Ist dafür kein Wert gesetzt, werden die Dateien
     ‘<system>-tests.asd’, ‘<system>-test.asd’, ‘tests.asd’ und
     ‘test.asd’ durchsucht, wenn sie existieren.

     Wenn aus irgendeinem Grund der Paketname nicht den
     Namenskonventionen folgen kann oder wenn mehrere Systeme kompiliert
     werden, kann der Parameter ‘#:asd-systems’ benutzt werden, um die
     Liste der Systemnamen anzugeben.

 -- Scheme-Variable: cargo-build-system
     Diese Variable wird vom Modul ‘(guix build-system cargo)’
     exportiert. Damit können Pakete mit Cargo erstellt werden, dem
     Erstellungswerkzeug der Rust-Programmiersprache
     (https://www.rust-lang.org).

     Das Erstellungssystem fügt ‘rustc’ und ‘cargo’ zu den Eingaben
     hinzu. Ein anderes Rust-Paket kann mit dem Parameter ‘#:rust’
     angegeben werden.

     Normale cargo-Abhängigkeiten sollten so wie bei anderen Paketen in
     die Paketdefinition eingetragen werden; wenn sie nur zur
     Erstellungszeit gebraucht werden, gehören sie in ‘native-inputs’,
     sonst in ‘inputs’. Wenn die Abhängigkeiten Crates sind, die nur als
     Quellcode vorliegen, sollten sie zusätzlich über den Parameter
     ‘#:cargo-inputs’ als eine Liste von Paaren aus Name und
     Spezifikation hinzugefügt, wobei als Spezifikation ein Paket oder
     eine Quellcode-Definition angegeben werden kann. Beachten Sie, dass
     die Spezifikation zu einem mit gzip komprimierten Tarball
     ausgewertet werden muss, der eine Datei ‘Cargo.toml’ in seinem
     Wurzelverzeichnis enthält, ansonsten wird sie ignoriert. Analog
     sollten solche Abhängigkeiten, die in cargo als „dev-dependencies“
     deklariert werden, zur Paketdefinition über den Parameter
     ‘#:cargo-development-inputs’ hinzugefügt werden.

     In seiner ‘configure’-Phase sorgt dieses Erstellungssystem dafür,
     dass cargo alle Quellcodeeingaben zur Verfügung stehen, die in den
     Parametern ‘#:cargo-inputs’ und ‘#:cargo-development-inputs’
     angegeben wurden. Außerdem wird eine enthaltene ‘Cargo.lock’-Datei
     entfernt, damit ‘cargo’ selbige während der ‘build’-Phase neu
     erzeugt. Die ‘package’-Phase führt ‘cargo package’ aus, um eine
     Quellcode-Crate zur späteren Nutzung zu erzeugen. Die
     ‘install’-Phase installiert die in der Crate definierten
     Binärdateien. Wenn _nicht_ ‘install-source? #f’ definiert ist,
     werden auch ein Verzeichnis mit dem eigenen Quellcode in einer
     Crate und auch der unverpackte Quellcode installiert, damit es
     leichter ist, später an Rust-Paketen zu hacken.

 -- Scheme-Variable: chicken-build-system
     Diese Variable wird von ‘(guix build-system chicken)’ exportiert.
     Mit ihr werden Module von CHICKEN Scheme (https://call-cc.org/)
     kompiliert. Sie sind auch bekannt als „Eggs“ oder als
     „Erweiterungen“. CHICKEN erzeugt C-Quellcode, der dann von einem
     C-Compiler kompiliert wird; in diesem Fall vom GCC.

     Dieses Erstellungssystem fügt ‘chicken’ neben den Paketen des
     ‘gnu-build-system’ zu den Paketeingaben hinzu.

     Das Erstellungssystem kann den Namen des Eggs (noch) nicht
     automatisch herausfinden, also müssen Sie, ähnlich wie beim
     ‘#:import-path’ des ‘go-build-system’, im ‘arguments’-Feld des
     Pakets den ‘#:egg-name’ festlegen.

     Zum Beispiel würden Sie so vorgehen, um ein Paket für das Egg
     ‘srfi-1’ zu schreiben:

          (arguments '(#:egg-name "srfi-1"))

     Abhängigkeiten von Eggs müssen in ‘propagated-inputs’ genannt
     werden und _nicht_ in ‘inputs’, weil CHICKEN keine absoluten
     Referenzen in kompilierte Eggs einbettet. Abhängigkeiten für Tests
     sollten wie üblich in ‘native-inputs’ stehen.

 -- Scheme-Variable: copy-build-system
     Diese Variable wird vom Modul ‘(guix build-system copy)’
     exportiert. Damit können einfache Pakete erstellt werden, für die
     nur wenig kompiliert werden muss, sondern in erster Linie Dateien
     kopiert werden.

     Dadurch wird ein Großteil der ‘gnu-build-system’ zur Menge der
     Paketeingaben hinzugefügt. Deswegen kann man bei Nutzung des
     ‘copy-build-system’ auf große Teile des Codes verzichten, der beim
     ‘trivial-build-system’ anfallen würde.

     Um den Dateiinstallationsvorgang weiter zu vereinfachen, wird ein
     Argument ‘#:install-plan’ zur Verfügung gestellt, mit dem der
     Paketautor angeben kann, welche Dateien wohin gehören. Der
     Installationsplan ist eine Liste aus ‘(QUELLE ZIEL [FILTER])’. Die
     FILTER sind optional.

        • Wenn die QUELLE einer Datei oder einem Verzeichnis ohne
          Schrägstrich am Ende entspricht, wird sie nach ZIEL
          installiert.
             • Hat das ZIEL einen Schrägstrich am Ende, wird mit dem
               Basisnamen der QUELLE innerhalb von ZIEL installiert.
             • Andernfalls wird die QUELLE als ZIEL installiert.

        • Falls es sich bei der QUELLE um ein Verzeichnis mit
          Schrägstrich am Ende handelt oder wenn FILTER benutzt werden,
          so ist der Schrägstrich am Ende von ZIEL mit der Bedeutung wie
          oben implizit.
             • Ohne Angabe von FILTERn wird der gesamte _Inhalt_ der
               QUELLE nach ZIEL installiert.
             • Werden FILTER als ‘#:include’, ‘#:include-regexp’,
               ‘#:exclude’ oder ‘#:exclude-regexp’ aufgeführt, werden je
               nach Filter nur die ausgewählten Dateien installiert.
               Jeder Filter wird als Liste von Zeichenketten angegeben.
                  • Bei ‘#:include’ werden all die Dateien installiert,
                    deren Pfad als Suffix zu mindestens einem der
                    Elemente der angegebenen Liste passt.
                  • Bei ‘#:include-regexp’ werden all die Dateien
                    installiert, deren Unterpfad zu mindestens einem der
                    regulären Ausdrücke in der angegebenen Liste passt.
                  • Die Filter ‘#:exclude’ und ‘#:exclude-regexp’
                    bewirken das Gegenteil ihrer Include-Entsprechungen.
                    Ohne ‘#:include’-Angaben werden alle Dateien außer
                    den zu den Exclude-Filtern passenden installiert.
                    Werden sowohl ‘#:include’ als auch ‘#:exclude’
                    angegeben, werden zuerst die ‘#:include’-Angaben
                    beachtet und danach wird durch ‘#:exclude’
                    gefiltert.
          In jedem Fall bleiben die Pfade relativ zur QUELLE innerhalb
          des ZIELs erhalten.

     Beispiele:

        • ‘("foo/bar" "share/my-app/")’: Installiert ‘bar’ nach
          ‘share/my-app/bar’.
        • ‘("foo/bar" "share/my-app/baz")’: Installiert ‘bar’ nach
          ‘share/my-app/baz’.
        • ‘("foo/" "share/my-app")’: Installiert den Inhalt von ‘foo’
          innerhalb von ‘share/my-app’. Zum Beispiel wird
          ‘foo/sub/datei’ nach ‘share/my-app/sub/datei’ installiert.
        • ‘("foo/" "share/my-app" #:include ("sub/datei"))’: Installiert
          nur ‘foo/sub/datei’ nach ‘share/my-app/sub/datei’.
        • ‘("foo/sub" "share/my-app" #:include ("datei"))’: Installiert
          ‘foo/sub/datei’ nach ‘share/my-app/datei’.

 -- Scheme-Variable: clojure-build-system
     Diese Variable wird durch das Modul ‘(guix build-system clojure)’
     exportiert. Sie implementiert eine einfache Erstellungsprozedur für
     in Clojure (https://clojure.org/) geschriebene Pakete mit dem guten
     alten ‘compile’ in Clojure. Cross-Kompilieren wird noch nicht
     unterstützt.

     Das Erstellungssystem fügt ‘clojure’, ‘icedtea’ und ‘zip’ zu den
     Eingaben hinzu. Sollen stattdessen andere Pakete benutzt werden,
     können diese jeweils mit den Parametern ‘#:clojure’, ‘#:jdk’ und
     ‘#:zip’ spezifiziert werden.

     Eine Liste der Quellcode-Verzeichnisse, Test-Verzeichnisse und
     Namen der Jar-Dateien können jeweils über die Parameter
     ‘#:source-dirs’, ‘#:test-dirs’ und ‘#:jar-names’ angegeben werden.
     Das Verzeichnis, in das kompiliert wird, sowie die Hauptklasse
     können jeweils mit den Parametern ‘#:compile-dir’ und
     ‘#:main-class’ angegeben werden. Andere Parameter sind im Folgenden
     dokumentiert.

     Dieses Erstellungssystem ist eine Erweiterung des
     ‘ant-build-system’, bei der aber die folgenden Phasen geändert
     wurden:

     ‘build’
          Diese Phase ruft ‘compile’ in Clojure auf, um Quelldateien zu
          kompilieren, und führt ‘jar’ aus, um Jar-Dateien aus sowohl
          Quelldateien als auch kompilierten Dateien zu erzeugen,
          entsprechend der jeweils in ‘#:aot-include’ und
          ‘#:aot-exclude’ festgelegten Listen aus in der Menge der
          Quelldateien eingeschlossenen und ausgeschlossenen
          Bibliotheken. Die Ausschlussliste hat Vorrang vor der
          Einschlussliste. Diese Listen setzen sich aus Symbolen
          zusammen, die für Clojure-Bibliotheken stehen oder dem
          Schlüsselwort ‘#:all’ entsprechen, was für alle im
          Quellverzeichis gefundenen Clojure-Bibliotheken steht. Der
          Parameter ‘#:omit-source?’ entscheidet, ob Quelldateien in die
          Jar-Archive aufgenommen werden sollen.

     ‘check’
          In dieser Phase werden Tests auf die durch Einschluss- und
          Ausschlussliste ‘#:test-include’ bzw. ‘#:test-exclude’
          angegebenen Dateien ausgeführt. Deren Bedeutung ist analog zu
          ‘#:aot-include’ und ‘#:aot-exclude’, außer dass das besondere
          Schlüsselwort ‘#:all’ jetzt für alle Clojure-Bibliotheken in
          den Test-Verzeichnissen steht. Der Parameter ‘#:tests?’
          entscheidet, ob Tests ausgeführt werden sollen.

     ‘install’
          In dieser Phase werden alle zuvor erstellten Jar-Dateien
          installiert.

     Zusätzlich zu den bereits angegebenen enthält dieses
     Erstellungssystem noch eine weitere Phase.

     ‘install-doc’
          Diese Phase installiert alle Dateien auf oberster Ebene, deren
          Basisnamen ohne Verzeichnisangabe zu ‘%doc-regex’ passen. Ein
          anderer regulärer Ausdruck kann mit dem Parameter
          ‘#:doc-regex’ verwendet werden. All die so gefundenen oder
          (rekursiv) in den mit ‘#:doc-dirs’ angegebenen
          Dokumentationsverzeichnissen liegenden Dateien werden
          installiert.

 -- Scheme-Variable: cmake-build-system
     Diese Variable wird von ‘(guix build-system cmake)’ exportiert. Sie
     implementiert die Erstellungsprozedur für Pakete, die das
     CMake-Erstellungswerkzeug (https://www.cmake.org) benutzen.

     Das Erstellungssystem fügt automatisch das Paket ‘cmake’ zu den
     Eingaben hinzu. Welches Paket benutzt wird, kann mit dem Parameter
     ‘#:cmake’ geändert werden.

     Der Parameter ‘#:configure-flags’ wird als Liste von
     Befehlszeilenoptionen aufgefasst, die an den Befehl ‘cmake’
     übergeben werden. Der Parameter ‘#:build-type’ abstrahiert, welche
     Befehlszeilenoptionen dem Compiler übergeben werden; der
     Vorgabewert ist ‘"RelWithDebInfo"’ (kurz für „release mode with
     debugging information“), d.h. kompiliert wird für eine
     Produktionsumgebung und Informationen zur Fehlerbehebung liegen
     bei, was ungefähr ‘-O2 -g’ entspricht, wie bei der Vorgabe für
     Autoconf-basierte Pakete.

 -- Scheme-Variable: dune-build-system
     Diese Variable wird vom Modul ‘(guix build-system dune)’
     exportiert. Sie unterstützt es, Pakete mit Dune
     (https://dune.build/) zu erstellen, einem Erstellungswerkzeug für
     die Programmiersprache OCaml, und ist als Erweiterung des unten
     beschriebenen OCaml-Erstellungssystems ‘ocaml-build-system’
     implementiert. Als solche können auch die Parameter ‘#:ocaml’ und
     ‘#:findlib’ an dieses Erstellungssystem übergeben werden.

     Das Erstellungssystem fügt automatisch das Paket ‘dune’ zu den
     Eingaben hinzu. Welches Paket benutzt wird, kann mit dem Parameter
     ‘#:dune’ geändert werden.

     Es gibt keine ‘configure’-Phase, weil dune-Pakete typischerweise
     nicht konfiguriert werden müssen. Vom Parameter ‘#:build-flags’
     wird erwartet, dass es sich um eine Liste von Befehlszeilenoptionen
     handelt, die zur Erstellung an den ‘dune’-Befehl übergeben werden.

     Der Parameter ‘#:jbuild?’ kann übergeben werden, um den Befehl
     ‘jbuild’ anstelle des neueren ‘dune’-Befehls aufzurufen, um das
     Paket zu erstellen. Der Vorgabewert ist ‘#f’.

     Mit dem Parameter ‘#:package’ kann ein Paketname angegeben werden,
     wenn im Paket mehrere Pakete enthalten sind und nur eines davon
     erstellt werden soll. Es ist äquivalent dazu, die
     Befehlszeilenoption ‘-p’ an ‘dune’ zu übergeben.

 -- Scheme-Variable: elm-build-system
     Diese Variable wird von ‘(guix build-system elm)’ exportiert. Sie
     implementiert eine Erstellungsprozedur für Elm-Pakete
     (https://elm-lang.org) ähnlich wie ‘elm install’.

     Mit dem Erstellungssystem wird ein Elm-Compiler-Paket zu der Menge
     der Eingaben hinzugefügt. Anstelle des vorgegebenen Compiler-Pakets
     (derzeit ist es ‘elm-sans-reactor’) kann das stattdessen zu
     verwendende Compiler-Paket im Argument ‘#:elm’ angegeben werden.
     Zudem werden Elm-Pakete, die vom Erstellungssystem selbst
     vorausgesetzt werden, als implizite Eingaben hinzugefügt, wenn sie
     noch keine sind; wenn Sie das verhindern möchten, übergeben Sie das
     Argument ‘#:implicit-elm-package-inputs?’, was in erster Linie zum
     Bootstrapping gebraucht wird.

     Die Einträge für ‘"dependencies"’ und ‘"test-dependencies"’ in der
     Datei ‘elm.json’ eines Elm-Pakets werden jeweils mit
     ‘propagated-inputs’ bzw. ‘inputs’ wiedergegeben.

     In Elm wird von Paketnamen eine bestimmte Struktur verlangt. Siehe
     *note Elm-Pakete:: für mehr Details auch zu den Werkzeugen in
     ‘(guix build-system elm)’, um damit umzugehen.

     Derzeit gelten für ‘elm-build-system’ ein paar nennenswerte
     Einschränkungen:

        • Der Fokus für das Erstellungssystem liegt auf dem, was in Elm
          “Pakete” genannt wird, also auf “Projekten in Elm”, für die ‘{
          "type": "package" }’ in deren ‘elm.json’-Dateien deklariert
          wurde. Wenn jemand mit ‘elm-build-system’ “Elm-Anwendungen”
          erstellen möchte (für die ‘{ "type": "application" }’
          deklariert wurde), ist das möglich, aber es müssen eigens
          Änderungen an den Erstellungsphasen vorgenommen werden.
          Beispiele sind in den Definitionen der Beispielanwendung
          ‘elm-todomvc’ und im ‘elm’-Paket selbst zu finden (weil die
          Web-Oberfläche des Befehls ‘elm reactor’ eine Elm-Anwendung
          ist).

        • In Elm können mehrere Versionen desselben Pakets nebeneinander
          unter ‘ELM_HOME’ vorkommen, aber mit ‘elm-build-system’ klappt
          das noch nicht so gut. Diese Einschränkung gilt vor allem für
          Elm-Anwendungen, weil dort die Versionen ihrer Abhängigkeiten
          genau festgelegt werden, während Elm-Pakete mit einem Bereich
          von Versionen umgehen können. Ein Ausweg wird in der oben
          genannten Beispielanwendung genommen, nämlich benutzt sie die
          Prozedur ‘patch-application-dependencies’ aus ‘(guix build
          elm-build-system)’, um die ‘elm.json’-Dateien umzuschreiben,
          damit sie sich stattdessen auf die Paketversionen beziehen,
          die es in der Erstellungsumgebung tatsächlich gibt. Alternativ
          könnte man auch auf Guix-Paketumwandlungen zurückgreifen
          (siehe *note Paketvarianten definieren::), um den gesamten
          Abhängigkeitsgraphen einer Anwendung umzuschreiben.

        • Wir sind noch nicht so weit, dass wir den Testkatalog für
          Elm-Projekte durchlaufen lassen könnten, weil es in Guix weder
          ein Paket für ‘elm-test-rs’
          (https://github.com/mpizenberg/elm-test-rs) noch für den
          Node.js-basierten ‘elm-test’
          (https://github.com/rtfeldman/node-test-runner) gibt, um
          Testläufe durchzuführen.

 -- Scheme-Variable: go-build-system
     Diese Variable wird vom Modul ‘(guix build-system go)’ exportiert.
     Mit ihr ist eine Erstellungsprozedur für Go-Pakete implementiert,
     die dem normalen Go-Erstellungsmechanismus
     (https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies)
     entspricht.

     Beim Aufruf wird ein Wert für den Schlüssel ‘#:import-path’ und
     manchmal auch für ‘#:unpack-path’ erwartet. Der „import path“
     (https://golang.org/doc/code.html#ImportPaths) entspricht dem
     Dateisystempfad, den die Erstellungsskripts des Pakets und darauf
     Bezug nehmende Pakete erwarten; durch ihn wird ein Go-Paket
     eindeutig bezeichnet. Typischerweise setzt er sich aus einer
     Kombination der entfernten URI des Paketquellcodes und der
     Dateisystemhierarchie zusammen. Manchmal ist es nötig, den
     Paketquellcode in ein anderes als das vom „import path“ bezeichnete
     Verzeichnis zu entpacken; diese andere Verzeichnisstruktur sollte
     dann als ‘#:unpack-path’ angegeben werden.

     Pakete, die Go-Bibliotheken zur Verfügung stellen, sollten ihren
     Quellcode auch in die Erstellungsausgabe installieren. Der
     Schlüssel ‘#:install-source?’, sein Vorgabewert ist ‘#t’, steuert,
     ob Quellcode installiert wird. Bei Paketen, die nur ausführbare
     Dateien liefern, kann der Wert auf ‘#f’ gesetzt werden.

     Cross-Erstellungen von Paketen sind möglich. Wenn für eine
     bestimmte Architektur oder ein bestimmtes Betriebssystem erstellt
     werden muss, kann man mit den Schlüsselwörtern ‘#:goarch’ und
     ‘#:goos’ erzwingen, dass das Paket für diese Architektur und dieses
     Betriebssystem erstellt wird. Die für Go nutzbaren Kombinationen
     sind in der Go-Dokumentation
     ("https://golang.org/doc/install/source#environment") nachlesbar.

 -- Scheme-Variable: glib-or-gtk-build-system
     Diese Variable wird vom Modul ‘(guix build-system glib-or-gtk)’
     exportiert. Sie ist für Pakete gedacht, die GLib oder GTK benutzen.

     Dieses Erstellungssystem fügt die folgenden zwei Phasen zu denen
     von ‘gnu-build-system’ hinzu:

     ‘glib-or-gtk-wrap’
          Die Phase ‘glib-or-gtk-wrap’ stellt sicher, dass Programme in
          ‘bin/’ in der Lage sind, GLib-„Schemata“ und GTK-Module
          (https://developer.gnome.org/gtk3/stable/gtk-running.html) zu
          finden. Dazu wird für das Programm ein Wrapper-Skript erzeugt,
          dass das eigentliche Programm mit den richtigen Werten für die
          Umgebungsvariablen ‘XDG_DATA_DIRS’ und ‘GTK_PATH’ aufruft.

          Es ist möglich, bestimmte Paketausgaben von diesem
          Wrapping-Prozess auszunehmen, indem Sie eine Liste ihrer Namen
          im Parameter ‘#:glib-or-gtk-wrap-excluded-outputs’ angeben.
          Das ist nützlich, wenn man von einer Ausgabe weiß, dass sie
          keine Binärdateien enthält, die GLib oder GTK benutzen, und
          diese Ausgabe durch das Wrappen ohne Not eine weitere
          Abhängigkeit von GLib und GTK bekäme.

     ‘glib-or-gtk-compile-schemas’
          Mit der Phase ‘glib-or-gtk-compile-schemas’ wird
          sichergestellt, dass alle GSettings-Schemata
          (https://developer.gnome.org/gio/stable/glib-compile-schemas.html)
          für GLib kompiliert werden. Dazu wird das Programm
          ‘glib-compile-schemas’ ausgeführt. Es kommt aus dem Paket
          ‘glib:bin’, was automatisch vom Erstellungssystem importiert
          wird. Welches ‘glib’-Paket dieses ‘glib-compile-schemas’
          bereitstellt, kann mit dem Parameter ‘#:glib’ spezifiziert
          werden.

     Beide Phasen finden nach der ‘install’-Phase statt.

 -- Scheme-Variable: guile-build-system
     Dieses Erstellungssystem ist für Guile-Pakete gedacht, die nur aus
     Scheme-Code bestehen und so schlicht sind, dass sie nicht einmal
     ein Makefile und erst recht keinen ‘configure’-Skript enthalten.
     Hierzu wird Scheme-Code mit ‘guild compile’ kompiliert (siehe *note
     (guile)Compilation::) und die ‘.scm’- und ‘.go’-Dateien an den
     richtigen Pfad installiert. Auch Dokumentation wird installiert.

     Das Erstellungssystem unterstützt Cross-Kompilieren durch die
     Befehlszeilenoption ‘--target’ für ‘guild compile’.

     Mit ‘guile-build-system’ erstellte Pakete müssen ein Guile-Paket in
     ihrem ‘native-inputs’-Feld aufführen.

 -- Scheme-Variable: julia-build-system
     Diese Variable wird vom Modul ‘(guix build-system julia)’
     exportiert. Sie entspricht einer Implementierung der durch
     Julia-Pakete (https://julialang.org/) genutzten Erstellungsprozedur
     und verhält sich im Prinzip so, wie wenn man ‘julia -e 'using Pkg;
     Pkg.add(paket)'’ in einer Umgebung ausführt, in der die
     Umgebungsvariable ‘JULIA_LOAD_PATH’ die Pfade aller Julia-Pakete
     unter den Paketeingaben enthält. Tests werden durch Aufruf von
     ‘/test/runtests.jl’ ausgeführt.

     Der Name des Julia-Pakets und seine UUID werden aus der Datei
     ‘Project.toml’ ausgelesen. Durch Angabe des Arguments
     ‘#:julia-package-name’ (die Groß-/Kleinschreibung muss stimmen)
     bzw. durch ‘#:julia-package-uuid’ können andere Werte verwendet
     werden.

     Julia-Pakete verwalten ihre Abhängigkeiten zu Binärdateien für
     gewöhnlich mittels ‘JLLWrappers.jl’, einem Julia-Paket, das ein
     Modul erzeugt (benannt nach der Bibliothek, die zugänglich gemacht
     wird, gefolgt von ‘_jll.jl’).

     Um die ‘_jll.jl’-Pakete mit den Pfaden zu Binärdateien
     hinzuzufügen, müssen Sie die Dateien in ‘src/wrappers/’ patchen, um
     dem Aufruf an das Makro ‘JLLWrappers.@generate_wrapper_header’ noch
     ein zweites Argument mit dem Store-Pfad der Binärdatei mitzugeben.

     Zum Beispiel fügen wir für das MbedTLS-Julia-Paket eine
     Erstellungsphase hinzu (siehe *note Erstellungsphasen::), in der
     der absolute Dateiname des zugänglich gemachten MbedTLS-Pakets
     hinzugefügt wird:

          (add-after 'unpack 'override-binary-path
            (lambda* (#:key inputs #:allow-other-keys)
              (for-each (lambda (wrapper)
                          (substitute* wrapper
                            (("generate_wrapper_header.*")
                             (string-append
                              "generate_wrapper_header(\"MbedTLS\", \""
                              (assoc-ref inputs "mbedtls-apache") "\")\n"))))
                        ;; Es gibt eine Julia-Datei für jede Plattform,
                        ;; wir ändern sie alle.
                        (find-files "src/wrappers/" "\\.jl$"))))

     Für manche ältere Pakete, die noch keine ‘Project.toml’ benutzen,
     muss auch diese Datei erstellt werden. Das geht intern vonstatten,
     sofern die Argumente ‘#:julia-package-name’ und
     ‘#:julia-package-uuid’ übergeben werden.

 -- Scheme-Variable: maven-build-system
     Diese Variable wird vom Modul ‘(guix build-system maven)’
     exportiert. Darin wird eine Erstellungsprozedur für Maven-Pakete
     (https://maven.apache.org) implementiert. Maven ist ein Werkzeug
     zur Verwaltung der Abhängigkeiten und des „Lebenszyklus“ eines
     Java-Projekts. Um Maven zu benutzen, werden Abhängigkeiten und
     Plugins in einer Datei ‘pom.xml’ angegeben, die Maven ausliest.
     Wenn Maven Abhängigkeiten oder Plugins fehlen, lädt es sie herunter
     und erstellt damit das Paket.

     Durch Guix’ Maven-Erstellungssystem wird gewährleistet, dass Maven
     im Offline-Modus läuft und somit nicht versucht, Abhängigkeiten
     herunterzuladen. Maven wird in einen Fehler laufen, wenn eine
     Abhängigkeit fehlt. Bevor Maven ausgeführt wird, wird der Inhalt
     der ‘pom.xml’ (auch in Unterprojekten) so verändert, dass darin die
     diejenige Version von Abhängigkeiten und Plugins aufgeführt wird,
     die in Guix’ Erstellungsumgebung vorliegt. Abhängigkeiten und
     Plugins müssen in das vorgetäuschte Maven-Repository unter ‘lib/m2’
     installiert werden; bevor Maven ausgeführt wird, werden symbolische
     Verknüpfungen in ein echtes Repository hergestellt. Maven wird
     angewiesen, dieses Repository für die Erstellung zu verwenden und
     installiert erstellte Artefakte dorthin. Geänderte Dateien werden
     ins Verzeichnis ‘lib/m2’ der Paketausgabe kopiert.

     Sie können eine ‘pom.xml’-Datei über das Argument ‘#:pom-file’
     festlegen oder die vom Erstellungssystem vorgegebene
     ‘pom.xml’-Datei im Quellverzeichnis verwenden lassen.

     Sollten Sie die Version einer Abhängigkeit manuell angeben müssen,
     können Sie dafür das Argument ‘#:local-packages’ benutzen. Es nimmt
     eine assoziative Liste entgegen, deren Schlüssel jeweils die
     ‘groupId’ des Pakets und deren Wert eine assoziative Liste ist,
     deren Schlüssel wiederum die ‘artifactId’ des Pakets und deren Wert
     die einzusetzende Version in ‘pom.xml’ ist.

     Manche Pakete haben Abhängigkeiten oder Plugins, die weder zur
     Laufzeit noch zur Erstellungszeit in Guix sinnvoll sind. Sie können
     sie entfernen, indem Sie das ‘#:exclude’-Argument verwenden, um die
     ‘pom.xml’-Datei zu bearbeiten. Sein Wert ist eine assoziative
     Liste, deren Schlüssel die ‘groupId’ des Plugins oder der
     Abhängigkeit ist, die Sie entfernen möchten, und deren Wert eine
     Liste von zu entfernenden ‘artifactId’-Vorkommen angibt.

     Sie können statt der vorgegebenen ‘jdk’- und ‘maven’-Pakete andere
     Pakete mit dem entsprechenden Argument, ‘#:jdk’ bzw. ‘#:maven’,
     verwenden.

     Mit dem Argument ‘#:maven-plugins’ geben Sie eine Liste von
     Maven-Plugins zur Nutzung während der Erstellung an, im gleichen
     Format wie das ‘inputs’-Feld der Paketdeklaration. Der Vorgabewert
     ist ‘(default-maven-plugins)’; diese Variable wird exportiert,
     falls Sie sie benutzen möchten.

 -- Scheme-Variable: minetest-mod-build-system
     Diese Variable wird vom Modul ‘(guix build-system minetest)’
     exportiert. Mit ihr ist ein Erstellungssystem für Mods für Minetest
     (https://www.minetest.net) implementiert, was bedeutet, Lua-Code,
     Bilder und andere Ressourcen an den Ort zu kopieren, wo Minetest
     nach Mods sucht. Das Erstellungssystem verkleinert auch PNG-Bilder
     und prüft, dass Minetest die Mod fehlerfrei laden kann.

 -- Scheme-Variable: minify-build-system
     Diese Variable wird vom Modul ‘(guix build-system minify)’
     exportiert. Sie implementiert eine Prozedur zur Minifikation
     einfacher JavaScript-Pakete.

     Es fügt ‘uglify-js’ zur Menge der Eingaben hinzu und komprimiert
     damit alle JavaScript-Dateien im ‘src’-Verzeichnis. Ein anderes
     Programm zur Minifikation kann verwendet werden, indem es mit dem
     Parameter ‘#:uglify-js’ angegeben wird; es wird erwartet, dass das
     angegebene Paket den minifizierten Code auf der Standardausgabe
     ausgibt.

     Wenn die Eingabe-JavaScript-Dateien nicht alle im ‘src’-Verzeichnis
     liegen, kann mit dem Parameter ‘#:javascript-files’ eine Liste der
     Dateinamen übergeben werden, auf die das Minifikationsprogramm
     aufgerufen wird.

 -- Scheme-Variable: ocaml-build-system
     Diese Variable wird vom Modul ‘(guix build-system ocaml)’
     exportiert. Mit ihr ist ein Erstellungssystem für OCaml-Pakete
     (https://ocaml.org) implementiert, was bedeutet, dass es die
     richtigen auszuführenden Befehle für das jeweilige Paket auswählt.
     OCaml-Pakete können sehr unterschiedliche Befehle erwarten. Dieses
     Erstellungssystem probiert manche davon durch.

     Wenn im Paket eine Datei ‘setup.ml’ auf oberster Ebene vorhanden
     ist, wird ‘ocaml setup.ml -configure’, ‘ocaml setup.ml -build’ und
     ‘ocaml setup.ml -install’ ausgeführt. Das Erstellungssystem wird
     annehmen, dass die Datei durch OASIS
     (http://oasis.forge.ocamlcore.org/) erzeugt wurde, und wird das
     Präfix setzen und Tests aktivieren, wenn diese nicht abgeschaltet
     wurden. Sie können Befehlszeilenoptionen zum Konfigurieren und
     Erstellen mit den Parametern ‘#:configure-flags’ und
     ‘#:build-flags’ übergeben. Der Schlüssel ‘#:test-flags’ kann
     übergeben werden, um die Befehlszeilenoptionen zu ändern, mit denen
     die Tests aktiviert werden. Mit dem Parameter ‘#:use-make?’ kann
     dieses Erstellungssystem für die build- und install-Phasen
     abgeschaltet werden.

     Verfügt das Paket über eine ‘configure’-Datei, wird angenommen,
     dass diese von Hand geschrieben wurde mit einem anderen Format für
     Argumente als bei einem Skript des ‘gnu-build-system’. Sie können
     weitere Befehlszeilenoptionen mit dem Schlüssel ‘#:configure-flags’
     hinzufügen.

     Falls dem Paket ein ‘Makefile’ beiliegt (oder ‘#:use-make?’ auf
     ‘#t’ gesetzt wurde), wird dieses benutzt und weitere
     Befehlszeilenoptionen können mit dem Schlüssel ‘#:make-flags’ zu
     den build- und install-Phasen hinzugefügt werden.

     Letztlich gibt es in manchen Pakete keine solchen Dateien, sie
     halten sich aber an bestimmte Konventionen, wo ihr eigenes
     Erstellungssystem zu finden ist. In diesem Fall führt Guix’
     OCaml-Erstellungssystem ‘ocaml pkg/pkg.ml’ oder ‘ocaml
     pkg/build.ml’ aus und kümmert sich darum, dass der Pfad zu dem
     benötigten findlib-Modul passt. Weitere Befehlszeilenoptionen
     können über den Schlüssel ‘#:build-flags’ übergeben werden. Um die
     Installation kümmert sich ‘opam-installer’. In diesem Fall muss das
     ‘opam’-Paket im ‘native-inputs’-Feld der Paketdefinition stehen.

     Beachten Sie, dass die meisten OCaml-Pakete davon ausgehen, dass
     sie in dasselbe Verzeichnis wie OCaml selbst installiert werden,
     was wir in Guix aber nicht so haben wollen. Solche Pakete
     installieren ihre ‘.so’-Dateien in das Verzeichnis ihres Moduls,
     was für die meisten anderen Einrichtungen funktioniert, weil es im
     OCaml-Compilerverzeichnis liegt. Jedoch können so in Guix die
     Bibliotheken nicht gefunden werden, deswegen benutzen wir
     ‘CAML_LD_LIBRARY_PATH’. Diese Umgebungsvariable zeigt auf
     ‘lib/ocaml/site-lib/stubslibs’ und dorthin sollten
     ‘.so’-Bibliotheken installiert werden.

 -- Scheme-Variable: python-build-system
     Diese Variable wird vom Modul ‘(guix build-system python)’
     exportiert. Sie implementiert mehr oder weniger die konventionelle
     Erstellungsprozedur, wie sie für Python-Pakete üblich ist, d.h.
     erst wird ‘python setup.py build’ ausgeführt und dann ‘python
     setup.py install --prefix=/gnu/store/…’.

     Für Pakete, die eigenständige Python-Programme nach ‘bin/’
     installieren, sorgt dieses Erstellungssystem dafür, dass die
     Programme in ein Wrapper-Skript verpackt werden, welches die
     eigentlichen Programme mit einer Umgebungsvariablen
     ‘GUIX_PYTHONPATH’ aufruft, die alle Python-Bibliotheken auflistet,
     von denen die Programme abhängen.

     Welches Python-Paket benutzt wird, um die Erstellung durchzuführen,
     kann mit dem Parameter ‘#:python’ bestimmt werden. Das ist
     nützlich, wenn wir erzwingen wollen, dass ein Paket mit einer
     bestimmten Version des Python-Interpretierers arbeitet. Das kann
     nötig sein, wenn das Programm nur mit einer einzigen
     Interpretiererversion kompatibel ist.

     Standardmäßig ruft Guix ‘setup.py’ auf, was zu ‘setuptools’ gehört,
     ähnlich wie es auch ‘pip’ tut. Manche Pakete sind mit setuptools
     (und pip) inkompatibel, deswegen können Sie diese Einstellung
     abschalten, indem Sie den Parameter ‘#:use-setuptools?’ auf ‘#f’
     setzen.

     Wenn eine der Ausgaben ‘"python"’ heißt, wird das Paket dort hinein
     installiert und _nicht_ in die vorgegebene Ausgabe ‘"out"’. Das ist
     für Pakete gedacht, bei denen ein Python-Paket nur einen Teil der
     Software ausmacht, man also die Phasen des ‘python-build-system’
     mit einem anderen Erstellungssystem zusammen verwenden wollen
     könnte. Oft kann man das bei Anbindungen für Python gebrauchen.

 -- Scheme-Variable: pyproject-build-system
     Diese Variable wird vom Modul ‘guix build-system pyproject’
     exportiert. Es basiert auf PYTHON-BUILD-SYSTEM und fügt
     Unterstützung für ‘pyproject.toml’ und PEP 517
     (https://peps.python.org/pep-0517/) hinzu. Auch kommt Unterstützung
     für verschiedene Build Backends und Testrahmen hinzu.

     Die Programmierschnittstelle unterscheidet sich leicht von
     PYTHON-BUILD-SYSTEM:
        • ‘#:use-setuptools?’ und ‘#:test-target’ wurden entfernt.
        • ‘#:build-backend’ ist neu. Die Vorgabe dafür ist ‘#false’, so
          dass das richtige Backend wenn möglich aufgrund von
          ‘pyproject.toml’ bestimmt wird.
        • ‘#:test-backend’ ist neu. Die Vorgabe dafür ist ‘#false’, so
          dass das richtige Test-Backend wenn möglich aufgrund der
          Paketeingaben gewählt wird.
        • ‘#:test-flags’ ist neu. Vorgegeben ist ‘'()’. Die Optionen
          darin werden als Befehlszeilenargumente an den Test-Befehl
          übermittelt. Beachten Sie, dass ausführliche Ausgaben immer
          aktiviert werden, falls dies für das Backend implementiert
          ist.

     Wir stufen es als „experimentell“ ein, weil die Details der
     Implementierung noch _nicht_ in Stein gemeißelt sind. Dennoch
     würden wir es begrüßen, wenn Sie es für neue Python-Projekte
     verwenden (auch für solche, die ‘setup.py’ haben). Die
     Programmierschnittstelle wird sich noch ändern, aber wir werden uns
     um im Guix-Kanal aufkommende Probleme kümmern.

     Schlussendlich wird dieses Erstellungssystem für veraltet erklärt
     werden und in PYTHON-BUILD-SYSTEM aufgehen, wahrscheinlich
     irgendwann im Jahr 2024.

 -- Scheme-Variable: perl-build-system
     Diese Variable wird vom Modul ‘(guix build-system perl)’
     exportiert. Mit ihr wird die Standard-Erstellungsprozedur für
     Perl-Pakete implementiert, welche entweder darin besteht, ‘perl
     Build.PL --prefix=/gnu/store/…’ gefolgt von ‘Build’ und ‘Build
     install’ auszuführen, oder ‘perl Makefile.PL PREFIX=/gnu/store/…’
     gefolgt von ‘make’ und ‘make install’ auszuführen, je nachdem, ob
     eine Datei ‘Build.PL’ oder eine Datei ‘Makefile.PL’ in der
     Paketdistribution vorliegt. Den Vorrang hat erstere, wenn sowohl
     ‘Build.PL’ als auch ‘Makefile.PL’ in der Paketdistribution
     existieren. Der Vorrang kann umgekehrt werden, indem ‘#t’ für den
     Parameter ‘#:make-maker?’ angegeben wird.

     Der erste Aufruf von ‘perl Makefile.PL’ oder ‘perl Build.PL’
     übergibt die im Parameter ‘#:make-maker-flags’ bzw.
     ‘#:module-build-flags’ angegebenen Befehlszeilenoptionen, je
     nachdem, was verwendet wird.

     Welches Perl-Paket dafür benutzt wird, kann mit ‘#:perl’ angegeben
     werden.

 -- Scheme-Variable: renpy-build-system
     Diese Variable wird vom Modul ‘(guix build-system renpy)’
     exportiert. Sie implementiert mehr oder weniger die herkömmliche
     Erstellungsprozedur, die für Ren’py-Spiele benutzt wird. Das
     bedeutet, das ‘#:game’ wird einmal geladen, wodurch Bytecode dafür
     erzeugt wird.

     Des Weiteren wird ein Wrapper-Skript in ‘bin/’ und eine
     *.desktop-Datei in ‘share/applications’ erzeugt. Mit beiden davon
     kann man das Spiel starten.

     Welches Ren’py-Paket benutzt wird, gibt man mit ‘#:renpy’ an.
     Spiele können auch in andere Ausgaben als in „out“ installiert
     werden, indem man ‘#:output’ benutzt.

 -- Scheme-Variable: qt-build-system
     Diese Variable wird vom Modul ‘(guix build-system qt)’ exportiert.
     Sie ist für Anwendungen gedacht, die Qt oder KDE benutzen.

     Dieses Erstellungssystem fügt die folgenden zwei Phasen zu denen
     von ‘cmake-build-system’ hinzu:

     ‘check-setup’
          Die Phase ‘check-setup’ bereitet die Umgebung für
          Überprüfungen vor, wie sie von Qt-Test-Programmen
          üblicherweise benutzt werden. Zurzeit werden nur manche
          Umgebungsvariable gesetzt: ‘QT_QPA_PLATFORM=offscreen’,
          ‘DBUS_FATAL_WARNINGS=0’ und ‘CTEST_OUTPUT_ON_FAILURE=1’.

          Diese Phase wird vor der ‘check’-Phase hinzugefügt. Es handelt
          sich um eine eigene Phase, die nach Bedarf angepasst werden
          kann.

     ‘qt-wrap’
          In der Phase ‘qt-wrap’ wird nach Qt5-Plugin-Pfaden, QML-Pfaden
          und manchen XDG-Daten in den Ein- und Ausgaben gesucht. Wenn
          solch ein Pfad gefunden wird, werden für alle Programme in den
          Verzeichnissen ‘bin/’, ‘sbin/’, ‘libexec/’ und ‘lib/libexec/’
          in der Ausgabe Wrapper-Skripte erzeugt, die die nötigen
          Umgebungsvariablen definieren.

          Es ist möglich, bestimmte Paketausgaben von diesem
          Wrapping-Prozess auszunehmen, indem Sie eine Liste ihrer Namen
          im Parameter ‘#:qt-wrap-excluded-outputs’ angeben. Das ist
          nützlich, wenn man von einer Ausgabe weiß, dass sie keine
          Qt-Binärdateien enthält, und diese Ausgabe durch das Wrappen
          ohne Not eine weitere Abhängigkeit von Qt, KDE oder Ähnlichem
          bekäme.

          Diese Phase wird nach der ‘install’-Phase hinzugefügt.

 -- Scheme-Variable: r-build-system
     Diese Variable wird vom Modul ‘(guix build-system r)’ exportiert.
     Sie entspricht einer Implementierung der durch R-Pakete
     (https://r-project.org) genutzten Erstellungsprozedur, die wenig
     mehr tut, als ‘R CMD INSTALL --library=/gnu/store/…’ in einer
     Umgebung auszuführen, in der die Umgebungsvariable ‘R_LIBS_SITE’
     die Pfade aller R-Pakete unter den Paketeingaben enthält. Tests
     werden nach der Installation mit der R-Funktion
     ‘tools::testInstalledPackage’ ausgeführt.

 -- Scheme-Variable: rakudo-build-system
     Diese Variable wird vom Modul ‘(guix build-system rakudo)’
     exportiert. Sie implementiert die Erstellungsprozedur, die von
     Rakudo (https://rakudo.org/) für Perl6-Pakete (https://perl6.org/)
     benutzt wird. Pakete werden ins Verzeichnis
     ‘/gnu/store/…/NAME-VERSION/share/perl6’ abgelegt und Binärdateien,
     Bibliotheksdateien und Ressourcen werden installiert, zudem werden
     die Dateien im Verzeichnis ‘bin/’ in Wrapper-Skripte verpackt.
     Tests können übersprungen werden, indem man ‘#f’ im Parameter
     ‘tests?’ übergibt.

     Welches rakudo-Paket benutzt werden soll, kann mit dem Parameter
     ‘rakudo’ angegeben werden. Das perl6-tap-harness-Paket, das für die
     Tests benutzt wird, kann mit ‘#:prove6’ ausgewählt werden; es kann
     auch entfernt werden, indem man ‘#f’ für den Parameter
     ‘with-prove6?’ übergibt. Welches perl6-zef-Paket für Tests und
     Installation verwendet wird, kann mit dem Parameter ‘#:zef’
     angegeben werden; es kann auch entfernt werden, indem man ‘#f’ für
     den Parameter ‘with-zef?’ übergibt.

 -- Scheme-Variable: rebar-build-system
     Diese Variable wird von ‘(guix build-system rebar)’ exportiert. Sie
     implementiert eine Erstellungsprozedur, die auf rebar3
     (https://rebar3.org) aufbaut, einem Erstellungssystem für
     Programme, die in der Sprache Erlang geschrieben sind.

     Das Erstellungssystem fügt sowohl ‘rebar3’ als auch ‘erlang’ zu den
     Eingaben hinzu. Sollen stattdessen andere Pakete benutzt werden,
     können diese jeweils mit den Parametern ‘#:rebar’ und ‘#:erlang’
     spezifiziert werden.

     Dieses Erstellungssystem basiert auf ‘gnu-build-system’, bei dem
     aber die folgenden Phasen geändert wurden:

     ‘unpack’
          Diese Phase entpackt die Quelle wie es auch das
          ‘gnu-build-system’ tut, schaut nach einer Datei
          ‘contents.tar.gz’ auf der obersten Ebene des Quellbaumes und
          wenn diese existiert, wird auch sie entpackt. Das erleichtert
          den Umgang mit Paketen, die auf <https://hex.pm/>, der
          Paketsammlung für Erlang und Elixir, angeboten werden.

     ‘bootstrap’
     ‘configure’
          Die Phasen ‘bootstrap’ und ‘configure’ fehlen, weil
          Erlang-Pakete normalerweise nicht konfiguriert werden müssen.

     ‘build’
          In dieser Phase wird ‘rebar3 compile’ mit den
          Befehlszeilenoptionen aus ‘#:rebar-flags’ ausgeführt.

     ‘check’
          Sofern _nicht_ ‘#:tests? #f’ übergeben wird, wird in dieser
          Phase ‘rebar3 eunit’ ausgeführt oder das Gleiche auf ein
          anderes bei ‘#:test-target’ angegebenes Ziel. Dabei werden die
          Befehlszeilenoptionen aus ‘#:rebar-flags’ übergeben.

     ‘install’
          Hier werden die im standardmäßigen Profil default erzeugten
          Dateien installiert oder die aus einem mit ‘#:install-profile’
          angegebenen anderen Profil.

 -- Scheme-Variable: texlive-build-system
     Diese Variable wird vom Modul ‘(guix build-system texlive)’
     exportiert. Mit ihr werden TeX-Pakete in Stapelverarbeitung („batch
     mode“) mit der angegebenen Engine erstellt. Das Erstellungssystem
     setzt die Variable ‘TEXINPUTS’ so, dass alle TeX-Quelldateien unter
     den Eingaben gefunden werden können.

     Standardmäßig wird ‘luatex’ auf allen Dateien mit der Dateiendung
     ‘ins’ ausgeführt. Eine andere Engine oder ein anderes Format kann
     mit dem Argument ‘#:tex-format’ angegeben werden. Verschiedene
     Erstellungsziele können mit dem Argument ‘#:build-targets’
     festgelegt werden, das eine Liste von Dateinamen erwartet. Das
     Erstellungssystem fügt nur ‘texlive-bin’ und ‘texlive-latex-base’
     zu den Eingaben hinzu (beide kommen aus dem Modul ‘(gnu packages
     tex’). Für beide kann das zu benutzende Paket jeweils mit den
     Argumenten ‘#:texlive-bin’ oder ‘#:texlive-latex-base’ geändert
     werden.

     Der Parameter ‘#:tex-directory’ sagt dem Erstellungssystem, wohin
     die installierten Dateien im texmf-Verzeichnisbaum installiert
     werden sollen.

 -- Scheme-Variable: ruby-build-system
     Diese Variable wird vom Modul ‘(guix build-system ruby)’
     exportiert. Sie steht für eine Implementierung der
     RubyGems-Erstellungsprozedur, die für Ruby-Pakete benutzt wird,
     wobei ‘gem build’ gefolgt von ‘gem install’ ausgeführt wird.

     Das ‘source’-Feld eines Pakets, das dieses Erstellungssystem
     benutzt, verweist typischerweise auf ein Gem-Archiv, weil
     Ruby-Entwickler dieses Format benutzen, wenn sie ihre Software
     veröffentlichen. Das Erstellungssystem entpackt das Gem-Archiv,
     spielt eventuell Patches für den Quellcode ein, führt die Tests
     aus, verpackt alles wieder in ein Gem-Archiv und installiert
     dieses. Neben Gem-Archiven darf das Feld auch auf Verzeichnisse und
     Tarballs verweisen, damit es auch möglich ist, unveröffentlichte
     Gems aus einem Git-Repository oder traditionelle
     Quellcode-Veröffentlichungen zu benutzen.

     Welches Ruby-Paket benutzt werden soll, kann mit dem Parameter
     ‘#:ruby’ festgelegt werden. Eine Liste zusätzlicher
     Befehlszeilenoptionen für den Aufruf des ‘gem’-Befehls kann mit dem
     Parameter ‘#:gem-flags’ angegeben werden.

 -- Scheme-Variable: waf-build-system
     Diese Variable wird durch das Modul ‘(guix build-system waf)’
     exportiert. Damit ist eine Erstellungsprozedur rund um das
     ‘waf’-Skript implementiert. Die üblichen Phasen – ‘configure’,
     ‘build’ und ‘install’ – sind implementiert, indem deren Namen als
     Argumente an das ‘waf’-Skript übergeben werden.

     Das ‘waf’-Skript wird vom Python-Interpetierer ausgeführt. Mit
     welchem Python-Paket das Skript ausgeführt werden soll, kann mit
     dem Parameter ‘#:python’ angegeben werden.

 -- Scheme-Variable: scons-build-system
     Diese Variable wird vom Modul ‘(guix build-system scons)’
     exportiert. Sie steht für eine Implementierung der
     Erstellungsprozedur, die das SCons-Softwarekonstruktionswerkzeug
     („software construction tool“) benutzt. Das Erstellungssystem führt
     ‘scons’ aus, um das Paket zu erstellen, führt mit ‘scons test’
     Tests aus und benutzt ‘scons install’, um das Paket zu
     installieren.

     Zusätzliche Optionen, die an ‘scons’ übergeben werden sollen,
     können mit dem Parameter ‘#:scons-flags’ angegeben werden. Die
     voreingestellten Erstellungs- und Installationsziele können jeweils
     durch ‘#:build-targets’ und ‘#:install-targets’ ersetzt werden. Die
     Python-Version, die benutzt werden soll, um SCons auszuführen, kann
     festgelegt werden, indem das passende SCons-Paket mit dem Parameter
     ‘#:scons’ ausgewählt wird.

 -- Scheme-Variable: haskell-build-system
     Diese Variable wird vom Modul ‘(guix build-system haskell)’
     exportiert. Sie bietet Zugang zur Cabal-Erstellungsprozedur, die
     von Haskell-Paketen benutzt wird, was bedeutet, ‘runhaskell
     Setup.hs configure --prefix=/gnu/store/…’ und ‘runhaskell Setup.hs
     build’ auszuführen. Statt das Paket mit dem Befehl ‘runhaskell
     Setup.hs install’ zu installieren, benutzt das Erstellungssystem
     ‘runhaskell Setup.hs copy’ gefolgt von ‘runhaskell Setup.hs
     register’, um keine Bibliotheken im Store-Verzeichnis des Compilers
     zu speichern, auf dem keine Schreibberechtigung besteht. Zusätzlich
     generiert das Erstellungssystem Dokumentation durch Ausführen von
     ‘runhaskell Setup.hs haddock’, außer ‘#:haddock? #f’ wurde
     übergeben. Optional können an Haddock Parameter mit Hilfe des
     Parameters ‘#:haddock-flags’ übergeben werden. Wird die Datei
     ‘Setup.hs’ nicht gefunden, sucht das Erstellungssystem stattdessen
     nach ‘Setup.lhs’.

     Welcher Haskell-Compiler benutzt werden soll, kann über den
     ‘#:haskell’-Parameter angegeben werden. Als Vorgabewert verwendet
     er ‘ghc’.

 -- Scheme-Variable: dub-build-system
     Diese Variable wird vom Modul ‘(guix build-system dub)’ exportiert.
     Sie verweist auf eine Implementierung des Dub-Erstellungssystems,
     das von D-Paketen benutzt wird. Dabei werden ‘dub build’ und ‘dub
     run’ ausgeführt. Die Installation wird durch manuelles Kopieren der
     Dateien durchgeführt.

     Welcher D-Compiler benutzt wird, kann mit dem Parameter ‘#:ldc’
     festgelegt werden, was als Vorgabewert ‘ldc’ benutzt.

 -- Scheme-Variable: emacs-build-system
     Diese Variable wird vom Modul ‘(guix build-system emacs)’
     exportiert. Darin wird eine Installationsprozedur ähnlich der des
     Paketsystems von Emacs selbst implementiert (siehe *note
     (emacs)Packages::).

     Zunächst wird eine Datei ‘Paket-autoloads.el’ erzeugt, dann werden
     alle Emacs-Lisp-Dateien zu Bytecode kompiliert. Anders als beim
     Emacs-Paketsystem werden die Info-Dokumentationsdateien in das
     Standardverzeichnis für Dokumentation verschoben und die Datei
     ‘dir’ gelöscht. Die Dateien des Elisp-Pakets werden direkt in
     ‘share/emacs/site-lisp’ installiert.

 -- Scheme-Variable: font-build-system
     Diese Variable wird vom Modul ‘(guix build-system font)’
     exportiert. Mit ihr steht eine Installationsprozedur für
     Schriftarten-Pakete zur Verfügung für vom Anbieter vorkompilierte
     TrueType-, OpenType- und andere Schriftartendateien, die nur an die
     richtige Stelle kopiert werden müssen. Dieses Erstellungssystem
     kopiert die Schriftartendateien an den Konventionen folgende Orte
     im Ausgabeverzeichnis.

 -- Scheme-Variable: meson-build-system
     Diese Variable wird vom Modul ‘(guix build-system meson)’
     exportiert. Sie enthält die Erstellungsprozedur für Pakete, die
     Meson (https://mesonbuild.com) als ihr Erstellungssystem benutzen.

     Mit ihr werden sowohl Meson als auch Ninja
     (https://ninja-build.org/) zur Menge der Eingaben hinzugefügt; die
     Pakete dafür können mit den Parametern ‘#:meson’ und ‘#:ninja’
     geändert werden, wenn nötig.

     Dieses Erstellungssystem ist eine Erweiterung für das
     ‘gnu-build-system’, aber mit Änderungen an den folgenden Phasen,
     die Meson-spezifisch sind:

     ‘configure’
          Diese Phase führt den ‘meson’-Befehl mit den in
          ‘#:configure-flags’ angegebenen Befehlszeilenoptionen aus. Die
          Befehlszeilenoption ‘--build-type’ wird immer auf
          ‘debugoptimized’ gesetzt, solange nichts anderes mit dem
          Parameter ‘#:build-type’ angegeben wurde.

     ‘build’
          Diese Phase ruft ‘ninja’ auf, um das Paket standardmäßig
          parallel zu erstellen. Die Vorgabeeinstellung, dass parallel
          erstellt wird, kann verändert werden durch Setzen von
          ‘#:parallel-build?’.

     ‘check’
          Die Phase führt ‘meson test’ mit einer unveränderlichen
          Grundmenge von Optionen aus. Diese Grundmenge können Sie mit
          dem Argument ‘#:test-options’ erweitern, um zum Beispiel einen
          bestimmten Testkatalog auszuwählen oder zu überspringen.

     ‘install’
          Diese Phase führt ‘ninja install’ aus und kann nicht verändert
          werden.

     Dazu fügt das Erstellungssystem noch folgende neue Phasen:

     ‘fix-runpath’
          In dieser Phase wird sichergestellt, dass alle Binärdateien
          die von ihnen benötigten Bibliotheken finden können. Die
          benötigten Bibliotheken werden in den Unterverzeichnissen des
          Pakets, das erstellt wird, gesucht, und zum ‘RUNPATH’
          hinzugefügt, wann immer es nötig ist. Auch werden diejenigen
          Referenzen zu Bibliotheken aus der Erstellungsphase wieder
          entfernt, die bei ‘meson’ hinzugefügt wurden, aber eigentlich
          zur Laufzeit nicht gebraucht werden, wie Abhängigkeiten nur
          für Tests.

     ‘glib-or-gtk-wrap’
          Diese Phase ist dieselbe, die auch im
          ‘glib-or-gtk-build-system’ zur Verfügung gestellt wird, und
          mit Vorgabeeinstellungen wird sie nicht durchlaufen. Wenn sie
          gebraucht wird, kann sie mit dem Parameter ‘#:glib-or-gtk?’
          aktiviert werden.

     ‘glib-or-gtk-compile-schemas’
          Diese Phase ist dieselbe, die auch im
          ‘glib-or-gtk-build-system’ zur Verfügung gestellt wird, und
          mit Vorgabeeinstellungen wird sie nicht durchlaufen. Wenn sie
          gebraucht wird, kann sie mit dem Parameter ‘#:glib-or-gtk?’
          aktiviert werden.

 -- Scheme-Variable: linux-module-build-system
     Mit ‘linux-module-build-system’ können Linux-Kernelmodule erstellt
     werden.

     Dieses Erstellungssystem ist eine Erweiterung des
     ‘gnu-build-system’, bei der aber die folgenden Phasen geändert
     wurden:

     ‘configure’
          Diese Phase konfiguriert die Umgebung so, dass das externe
          Kernel-Modul durch das Makefile des Linux-Kernels erstellt
          werden kann.

     ‘build’
          Diese Phase benutzt das Makefile des Linux-Kernels, um das
          externe Kernel-Modul zu erstellen.

     ‘install’
          Diese Phase benutzt das Makefile des Linux-Kernels zur
          Installation des externen Kernel-Moduls.

     Es ist möglich und hilfreich, den für die Erstellung des Moduls zu
     benutzenden Linux-Kernel anzugeben (in der ‘arguments’-Form eines
     Pakets, dass das ‘linux-module-build-system’ als Erstellungssystem
     benutzt, wird dazu der Schlüssel ‘#:linux’ benutzt).

 -- Scheme-Variable: node-build-system
     Diese Variable wird vom Modul ‘(guix build-system node)’
     exportiert. Sie stellt eine Implementierung der Erstellungsprozedur
     von Node.js (https://nodejs.org) dar, die annäherungsweise der
     Funktion des Befehls ‘npm install’ gefolgt vom Befehl ‘npm test’
     entspricht.

     Welches Node.js-Paket zur Interpretation der ‘npm’-Befehle benutzt
     wird, kann mit dem Parameter ‘#:node’ angegeben werden. Dessen
     Vorgabewert ist ‘node’.

   Letztlich gibt es für die Pakete, die bei weitem nichts so komplexes
brauchen, ein „triviales“ Erstellungssystem. Es ist in dem Sinn trivial,
dass es praktisch keine Hilfestellungen gibt: Es fügt keine impliziten
Eingaben hinzu und hat kein Konzept von Erstellungsphasen.

 -- Scheme-Variable: trivial-build-system
     Diese Variable wird vom Modul ‘(guix build-system trivial)’
     exportiert.

     Diesem Erstellungssystem muss im Argument ‘#:builder’ ein
     Scheme-Ausdruck übergeben werden, der die Paketausgabe(n)
     erstellt – wie bei ‘build-expression->derivation’ (siehe *note
     ‘build-expression->derivation’: Ableitungen.).

 -- Scheme-Variable: channel-build-system
     Diese Variable wird vom Modul ‘(guix build-system channel)’
     exportiert.

     Dieses Erstellungssystem ist in erster Linie auf interne Nutzung
     ausgelegt. Ein Paket mit diesem Erstellungssystem muss im
     ‘source’-Feld eine Kanalspezifikation stehen haben (siehe *note
     Kanäle::); alternativ kann für ‘source’ der Name eines
     Verzeichnisses angegeben werden, dann muss aber ein Argument
     ‘#:commit’ mit dem gewünschten Commit (einer hexadezimalen
     Zeichenkette) übergeben werden, so dass dieser erstellt wird.

     Damit ergit sich ein Paket mit einer Guix-Instanz des angegebenen
     Kanals, ähnlich der, die ‘guix time-machine’ erstellen würde.


File: guix.de.info,  Node: Erstellungsphasen,  Next: Werkzeuge zur Erstellung,  Prev: Erstellungssysteme,  Up: Programmierschnittstelle

9.6 Erstellungsphasen
=====================

Fast alle Erstellungssysteme für Pakete implementieren ein Konzept von
“Erstellungsphasen”: einer Abfolge von Aktionen, die vom
Erstellungssystem ausgeführt werden, wenn Sie das Paket erstellen. Dabei
fallen in den Store installierte Nebenerzeugnisse an. Eine Ausnahme ist
der Erwähnung wert: das magere ‘trivial-build-system’ (siehe *note
Erstellungssysteme::).

   Wie im letzten Abschnitt erläutert, stellen diese Erstellungssysteme
eine standardisierte Liste von Phasen zur Verfügung. Für
‘gnu-build-system’ sind dies die hauptsächlichen Erstellungsphasen:

‘set-paths’
     Suchpfade in Umgebungsvariablen definieren. Dies geschieht für alle
     Eingabepakete. ‘PATH’ wird so auch festgelegt. Siehe *note
     Suchpfade::.

‘unpack’
     Den Quell-Tarball entpacken und das Arbeitsverzeichnis wechseln in
     den entpackten Quellbaum. Wenn die Quelle bereits ein Verzeichnis
     ist, wird es in den Quellbaum kopiert und dorthin gewechselt.

‘patch-source-shebangs’
     „Shebangs“ in Quelldateien beheben, damit Sie sich auf die
     richtigen Store-Dateipfade beziehen. Zum Beispiel könnte
     ‘#!/bin/sh’ zu ‘#!/gnu/store/…-bash-4.3/bin/sh’ geändert werden.

‘configure’
     Das Skript ‘configure’ mit einigen vorgegebenen
     Befehlszeilenoptionen ausführen, wie z.B. mit
     ‘--prefix=/gnu/store/…’, sowie mit den im
     ‘#:configure-flags’-Argument angegebenen Optionen.

‘build’
     ‘make’ ausführen mit den Optionen aus der Liste in ‘#:make-flags’.
     Wenn das Argument ‘#:parallel-build?’ auf wahr gesetzt ist (was der
     Vorgabewert ist), wird ‘make -j’ zum Erstellen ausgeführt.

‘check’
     ‘make check’ (oder statt ‘check’ ein anderes bei ‘#:test-target’
     angegebenes Ziel) ausführen, außer falls ‘#:tests? #f’ gesetzt ist.
     Wenn das Argument ‘#:parallel-tests?’ auf wahr gesetzt ist (der
     Vorgabewert), führe ‘make check -j’ aus.

‘install’
     ‘make install’ mit den in ‘#:make-flags’ aufgelisteten Optionen
     ausführen.

‘patch-shebangs’
     Shebangs in den installierten ausführbaren Dateien beheben.

‘strip’
     Symbole zur Fehlerbehebung aus ELF-Dateien entfernen (außer
     ‘#:strip-binaries?’ ist auf falsch gesetzt) und in die
     ‘debug’-Ausgabe kopieren, falls diese verfügbar ist (siehe *note
     Dateien zur Fehlersuche installieren::).

‘validate-runpath’
     Den ‘RUNPATH’ von ELF-Binärdateien validieren, sofern
     ‘#:validate-runpath?’ falsch ist (siehe *note
     Erstellungssysteme::).

     Die Validierung besteht darin, sicherzustellen, dass jede
     gemeinsame Bibliothek, die von einer ELF-Binärdatei gebraucht wird
     (sie sind in ‘DT_NEEDED’-Einträgen im ‘PT_DYNAMIC’-Segment der
     ELF-Datei aufgeführt), im ‘DT_RUNPATH’-Eintrag der Datei gefunden
     wird. Mit anderen Worten wird gewährleistet, dass es beim Ausführen
     oder Benutzen einer solchen Binärdatei nicht zur Laufzeit zu einem
     Fehler kommt, eine Datei würde nicht gefunden. Siehe *note
     ‘-rpath’: (ld)Options. für mehr Informationen zum ‘RUNPATH’.

   Andere Erstellungssysteme haben ähnliche, aber etwas unterschiedliche
Phasen. Zum Beispiel hat das ‘cmake-build-system’ gleichnamige Phasen,
aber seine ‘configure’-Phase führt ‘cmake’ statt ‘./configure’ aus.
Andere Erstellungssysteme wie z.B. ‘python-build-system’ haben eine
völlig andere Liste von Standardphasen. Dieser gesamte Code läuft
“erstellungsseitig”: Er wird dann ausgewertet, wenn Sie das Paket
wirklich erstellen, in einem eigenen Erstellungprozess nur dafür, den
der Erstellungs-Daemon erzeugt (siehe *note Aufruf des guix-daemon::).

   Erstellungsphasen werden durch assoziative Listen (kurz „Alists“)
repräsentiert (siehe *note (guile)Association Lists::) wo jeder
Schlüssel ein Symbol für den Namen der Phase ist und der assoziierte
Wert eine Prozedur ist, die eine beliebige Anzahl von Argumenten nimmt.
Nach Konvention empfangen diese Prozeduren dadurch Informationen über
die Erstellung in Form von “Schlüsselwort-Parametern”, die darin benutzt
oder ignoriert werden können.

   Zum Beispiel werden die ‘%standard-phases’, das ist die Variable mit
der Alist der Erstellungsphasen, in ‘(guix build gnu-build-system)’ so
definiert(1):

     ;; Die Erstellungsphasen von 'gnu-build-system'.

     (define* (unpack #:key source #:allow-other-keys)
       ;; Quelltarball extrahieren.
       (invoke "tar" "xvf" source))

     (define* (configure #:key outputs #:allow-other-keys)
       ;; 'configure'-Skript ausführen. In Ausgabe "out" installieren.
       (let ((out (assoc-ref outputs "out")))
         (invoke "./configure"
                 (string-append "--prefix=" out))))

     (define* (build #:allow-other-keys)
       ;; Kompilieren.
       (invoke "make"))

     (define* (check #:key (test-target "check") (tests? #true)
                     #:allow-other-keys)
       ;; Testkatalog ausführen.
       (if tests?
           (invoke "make" test-target)
           (display "test suite not run\n")))

     (define* (install #:allow-other-keys)
       ;; Dateien ins bei 'configure' festgelegte Präfix installieren.
       (invoke "make" "install"))

     (define %standard-phases
       ;; Die Liste der Standardphasen (der Kürze halber lassen wir einige
       ;; aus). Jedes Element ist ein Paar aus Symbol und Prozedur.
       (list (cons 'unpack unpack)
             (cons 'configure configure)
             (cons 'build build)
             (cons 'check check)
             (cons 'install install)))

   Hier sieht man wie ‘%standard-phases’ als eine Liste von Paaren aus
Symbol und Prozedur (siehe *note (guile)Pairs::) definiert ist. Das
erste Paar assoziiert die ‘unpack’-Prozedur mit dem ‘unpack’-Symbol – es
gibt einen Namen an. Das zweite Paar definiert die ‘configure’-Phase auf
ähnliche Weise, ebenso die anderen. Wenn ein Paket erstellt wird, das
‘gnu-build-system’ benutzt, werden diese Phasen der Reihe nach
ausgeführt. Sie können beim Erstellen von Paketen im
Erstellungsprotokoll den Namen jeder gestarteten und abgeschlossenen
Phase sehen.

   Schauen wir uns jetzt die Prozeduren selbst an. Jede davon wird mit
‘define*’ definiert, dadurch können bei ‘#:key’ die
Schlüsselwortparameter aufgelistet werden, die die Prozedur annimmt,
wenn gewünscht auch zusammen mit einem Vorgabewert, und durch
‘#:allow-other-keys’ wird veranlasst, dass andere Schlüsselwortparameter
ignoriert werden (siehe *note (guile)Optional Arguments::).

   Die ‘unpack’-Prozedur berücksichtigt den ‘source’-Parameter; das
Erstellungssystem benutzt ihn, um den Dateinamen des Quell-Tarballs
(oder des Checkouts aus einer Versionskontrolle) zu finden. Die anderen
Parameter ignoriert sie. Die ‘configure’-Phase interessiert sich nur für
den ‘outputs’-Parameter, eine Alist, die die Namen von Paketausgaben auf
ihre Dateinamen im Store abbildet (siehe *note Pakete mit mehreren
Ausgaben.::). Sie extrahiert den Dateinamen für ‘out’, die
Standardausgabe, und gibt ihn an ‘./configure’ als das
Installationspräfix weiter, wodurch ‘make install’ zum Schluss alle
Dateien in dieses Verzeichnis kopieren wird (siehe *note configuration
and makefile conventions: (standards)Configuration.). ‘build’ und
‘install’ ignorieren all ihre Argumente. ‘check’ berücksichtigt das
Argument ‘test-target’, worin der Name des Makefile-Ziels angegeben
wird, um die Tests auszuführen. Es wird stattdessen eine Nachricht
angezeigt und die Tests übersprungen, wenn ‘tests?’ falsch ist.

   Die Liste der Phasen, die für ein bestimmtes Paket benutzt werden,
kann über den ‘#:phases’-Parameter an das Erstellungssystem geändert
werden. Das Ändern des Satzes von Erstellungsphasen funktioniert so,
dass eine neue Alist von Phasen aus der oben beschriebenen
‘%standard-phases’-Alist heraus erzeugt wird. Dazu können die
Standardprozeduren zur Bearbeitung von assoziativen Listen wie
‘alist-delete’ benutzt werden (siehe *note (guile)SRFI-1 Association
Lists::), aber es ist bequemer, dafür die Prozedur ‘modify-phases’ zu
benutzen (siehe *note ‘modify-phases’: Werkzeuge zur Erstellung.).

   Hier ist ein Beispiel für eine Paketdefinition, die die
‘configure’-Phase aus ‘%standard-phases’ entfernt und eine neue Phase
vor der ‘build’-Phase namens ‘set-prefix-in-makefile’ einfügt:

     (define-public beispiel
       (package
         (name "beispiel")
         ;; wir lassen die anderen Felder aus
         (build-system gnu-build-system)
         (arguments
          '(#:phases (modify-phases %standard-phases
                       (delete 'configure)
                       (add-before 'build 'set-prefix-in-makefile
                         (lambda* (#:key outputs #:allow-other-keys)
                           ;; Makefile anpassen, damit die 'PREFIX'-
                           ;; Variable auf "out" verweist.
                           (let ((out (assoc-ref outputs "out")))
                             (substitute* "Makefile"
                               (("PREFIX =.*")
                                (string-append "PREFIX = "
                                               out "\n")))))))))))

   Die neu eingefügte Phase wurde als anonyme Prozedur geschrieben.
Solche namenlosen Prozeduren schreibt man mit ‘lambda*’. Oben
berücksichtigt sie den ‘outputs’-Parameter, den wir zuvor gesehen haben.
Siehe *note Werkzeuge zur Erstellung:: für mehr Informationen über die
in dieser Phase benutzten Hilfsmittel und für mehr Beispiele zu
‘modify-phases’.

   Sie sollten im Kopf behalten, dass Erstellungsphasen aus Code
bestehen, der erst dann ausgewertet wird, wenn das Paket erstellt wird.
Das ist der Grund, warum der gesamte ‘modify-phases’-Ausdruck oben
quotiert wird. Quotiert heißt, er steht nach einem ‘'’ oder
Apostrophenzeichen: Er wird nicht sofort als Code ausgewertet, sondern
nur zur späteren Ausführung vorgemerkt (wir sagen “staged”, siehe *note
G-Ausdrücke:: für eine Erläuterung von Code-Staging und den beteiligten
“Code-Schichten” (oder „Strata“).

   ---------- Footnotes ----------

   (1) Wir stellen hier nur eine vereinfachte Sicht auf diese
Erstellungsphasen vor. Wenn Sie alle Details wollen, schauen Sie sich
‘(guix build gnu-build-system)’ an!


File: guix.de.info,  Node: Werkzeuge zur Erstellung,  Next: Suchpfade,  Prev: Erstellungsphasen,  Up: Programmierschnittstelle

9.7 Werkzeuge zur Erstellung
============================

Sobald Sie anfangen, nichttriviale Paketdefinitionen (siehe *note Pakete
definieren::) oder andere Erstellungsaktionen (siehe *note
G-Ausdrücke::) zu schreiben, würden Sie sich wahrscheinlich darüber
freuen, Helferlein für „Shell-artige“ Aktionen vordefiniert zu bekommen,
also Code, den Sie benutzen können, um Verzeichnisse anzulegen, Dateien
rekursiv zu kopieren oder zu löschen, Erstellungsphasen anzupassen und
Ähnliches. Das Modul ‘(guix build utils)’ macht solche nützlichen
Werkzeugprozeduren verfügbar.

   Die meisten Erstellungssysteme laden ‘(guix build utils)’ (siehe
*note Erstellungssysteme::). Wenn Sie also eigene Erstellungsphasen für
Ihre Paketdefinitionen schreiben, können Sie in den meisten Fällen
annehmen, dass diese Prozeduren bei der Auswertung sichtbar sein werden.

   Beim Schreiben von G-Ausdrücken können Sie auf der „Erstellungsseite“
‘(guix build utils)’ mit ‘with-imported-modules’ importieren und
anschließend mit der ‘use-modules’-Form sichtbar machen (siehe *note
(guile)Using Guile Modules::):

     (with-imported-modules '((guix build utils))  ;importieren
       (computed-file "leerer-verzeichnisbaum"
                      #~(begin
                          ;; Sichtbar machen.
                          (use-modules (guix build utils))

                          ;; Jetzt kann man problemlos 'mkdir-p' nutzen.
                          (mkdir-p (string-append #$output "/a/b/c")))))

   Der Rest dieses Abschnitts stellt eine Referenz der meisten
Werkzeugprozeduren dar, die ‘(guix build utils)’ anbietet.

9.7.1 Umgehen mit Store-Dateinamen
----------------------------------

Dieser Abschnitt dokumentiert Prozeduren, die sich mit Dateinamen von
Store-Objekten befassen.

 -- Scheme-Prozedur: %store-directory
     Liefert den Verzeichnisnamen des Stores.

 -- Scheme-Prozedur: store-file-name? DATEI
     Liefert wahr zurück, wenn sich DATEI innerhalb des Stores befindet.

 -- Scheme-Prozedur: strip-store-file-name DATEI
     Liefert den Namen der DATEI, die im Store liegt, ohne den Anfang
     ‘/gnu/store’ und ohne die Prüfsumme am Namensanfang. Als Ergebnis
     ergibt sich typischerweise eine Zeichenkette aus ‘"PAKET-VERSION"’.

 -- Scheme-Prozedur: package-name->name+version NAME
     Liefert für den Paket-NAMEn (so etwas wie ‘"foo-0.9.1b"’) zwei
     Werte zurück: zum einen ‘"foo"’ und zum anderen ‘"0.9.1b"’. Wenn
     der Teil mit der Version fehlt, werden der NAME und ‘#f’
     zurückgeliefert. Am ersten Bindestrich, auf den eine Ziffer folgt,
     wird der Versionsteil abgetrennt.

9.7.2 Dateitypen
----------------

Bei den folgenden Prozeduren geht es um Dateien und Dateitypen.

 -- Scheme-Prozedur: directory-exists? VERZEICHNIS
     Liefert ‘#t’, wenn das VERZEICHNIS existiert und ein Verzeichnis
     ist.

 -- Scheme-Prozedur: executable-file? DATEI
     Liefert ‘#t’, wenn die DATEI existiert und ausführbar ist.

 -- Scheme-Prozedur: symbolic-link? DATEI
     Liefert ‘#t’, wenn die DATEI eine symbolische Verknüpfung ist (auch
     bekannt als „Symlink“).

 -- Scheme-Prozedur: elf-file? DATEI
 -- Scheme-Prozedur: ar-file? DATEI
 -- Scheme-Prozedur: gzip-file? DATEI
     Liefert ‘#t’, wenn die DATEI jeweils eine ELF-Datei, ein
     ‘ar’-Archiv (etwa eine statische Bibliothek mit ‘.a’) oder eine
     gzip-Datei ist.

 -- Scheme-Prozedur: reset-gzip-timestamp DATEI [#:keep-mtime? #t]
     Wenn die DATEI eine gzip-Datei ist, wird ihr eingebetteter
     Zeitstempel zurückgesetzt (wie bei ‘gzip --no-name’) und wahr
     geliefert. Ansonsten wird ‘#f’ geliefert. Wenn KEEP-MTIME? wahr
     ist, wird der Zeitstempel der letzten Modifikation von DATEI
     beibehalten.

9.7.3 Änderungen an Dateien
---------------------------

Die folgenden Prozeduren und Makros helfen beim Erstellen, Ändern und
Löschen von Dateien. Sie machen Funktionen ähnlich zu Shell-Werkzeugen
wie ‘mkdir -p’, ‘cp -r’, ‘rm -r’ und ‘sed’ verfügbar. Sie ergänzen
Guiles ausgiebige aber kleinschrittige Dateisystemschnittstelle (siehe
*note (guile)POSIX::).

 -- Scheme-Syntax: with-directory-excursion VERZEICHNIS RUMPF…
     Den RUMPF ausführen mit dem VERZEICHNIS als aktuellem Verzeichnis
     des Prozesses.

     Im Grunde ändert das Makro das aktuelle Arbeitsverzeichnis auf
     VERZEICHNIS bevor der RUMPF ausgewertet wird, mittels ‘chdir’
     (siehe *note (guile)Processes::). Wenn der dynamische Bereich von
     RUMPF wieder verlassen wird, wechselt es wieder ins anfängliche
     Verzeichnis zurück, egal ob der RUMPF durch normales Zurückliefern
     eines Ergebnisses oder durch einen nichtlokalen Sprung wie etwa
     eine Ausnahme verlassen wurde.

 -- Scheme-Prozedur: mkdir-p VERZEICHNIS
     Das VERZEICHNIS und all seine Vorgänger erstellen.

 -- Scheme-Prozedur: install-file DATEI VERZEICHNIS
     VERZEICHNIS erstellen, wenn es noch nicht existiert, und die DATEI
     mit ihrem Namen dorthin kopieren.

 -- Scheme-Prozedur: make-file-writable DATEI
     Dem Besitzer der DATEI Schreibberechtigung darauf erteilen.

 -- Scheme-Prozedur: copy-recursively QUELLE ZIELORT [#:log
          (current-output-port)] [#:follow-symlinks? #f]  [#:copy-file
     copy-file] [#:keep-mtime? #f] [#:keep-permissions? #t] Das
     Verzeichnis QUELLE rekursiv an den ZIELORT kopieren. Wenn
     FOLLOW-SYMLINKS? wahr ist, folgt die Rekursion symbolischen
     Verknüpfungen, ansonsten werden die Verknüpfungen als solche
     beibehalten. Zum Kopieren regulärer Dateien wird COPY-FILE
     aufgerufen. Wenn KEEP-MTIME? wahr ist, bleibt der Zeitstempel der
     letzten Änderung an den Dateien in QUELLE dabei bei denen am
     ZIELORT erhalten. Wenn KEEP-PERMISSIONS? wahr ist, bleiben
     Dateiberechtigungen erhalten. Ein ausführliches Protokoll wird in
     den bei LOG angegebenen Port geschrieben.

 -- Scheme-Prozedur: delete-file-recursively VERZEICHNIS
          [#:follow-mounts? #f] Das VERZEICHNIS rekursiv löschen, wie
          bei
     ‘rm -rf’, ohne symbolischen Verknüpfungen zu folgen. Auch
     Einhängepunkten wird _nicht_ gefolgt, außer falls FOLLOW-MOUNTS?
     wahr ist. Fehler dabei werden angezeigt aber ignoriert.

 -- Scheme-Syntax: substitute* DATEI ((REGEXP MUSTER-VARIABLE...)
          RUMPF…) … Den regulären
     Ausdruck REGEXP in der DATEI durch die durch RUMPF berechnete
     Zeichenkette ersetzen. Bei der Auswertung von RUMPF wird jede
     MUSTER-VARIABLE an den Teilausdruck an der entsprechenden Position
     der Regexp gebunden. Zum Beispiel:

          (substitute* file
            (("Hallo")
             "Guten Morgen\n")
            (("foo([a-z]+)bar(.*)$" alles Buchstaben Ende)
             (string-append "baz" Buchstaben Ende)))

     Jedes Mal, wenn eine Zeile in der DATEI den Text ‘Hallo’ enthält,
     wird dieser durch ‘Guten Morgen’ ersetzt. Jedes Mal, wenn eine
     Zeile zum zweiten regulären Ausdruck passt, wird ‘alles’ an die
     vollständige Übereinstimmung gebunden, ‘Buchstaben’ wird an den
     ersten Teilausdruck gebunden und ‘Ende’ an den letzten.

     Wird für eine MUSTER-VARIABLE nur ‘_’ geschrieben, so wird keine
     Variable an die Teilzeichenkette an der entsprechenden Position im
     Muster gebunden.

     Alternativ kann statt einer DATEI auch eine Liste von Dateinamen
     angegeben werden. In diesem Fall wird jede davon den Substitutionen
     unterzogen.

     Seien Sie vorsichtig bei der Nutzung von ‘$’, um auf das Ende einer
     Zeile zu passen. ‘$’ passt nämlich _nicht_ auf den Zeilenumbruch am
     Ende einer Zeile.

9.7.4 Dateien suchen
--------------------

Dieser Abschnitt beschreibt Prozeduren, um Dateien zu suchen und zu
filtern.

 -- Scheme-Prozedur: file-name-predicate REGEXP
     Liefert ein Prädikat, das gegeben einen Dateinamen, dessen
     Basisnamen auf REGEXP passt, wahr liefert.

 -- Scheme-Prozedur: find-files VERZEICHNIS [PRÄDIKAT] [#:stat lstat]
          [#:directories? #f] [#:fail-on-error? #f] Liefert die
     lexikografisch sortierte Liste der Dateien innerhalb VERZEICHNIS,
     für die das PRÄDIKAT wahr liefert. An PRÄDIKAT werden zwei
     Argumente übergeben: Der absolute Dateiname und der zugehörige
     Stat-Puffer. Das vorgegebene Prädikat liefert immer wahr. Als
     PRÄDIKAT kann auch ein regulärer Ausdruck benutzt werden; in diesem
     Fall ist er äquivalent zu ‘(file-name-predicate PRÄDIKAT)’. Mit
     STAT werden Informationen über die Datei ermittelt; wenn dafür
     ‘lstat’ benutzt wird, bedeutet das, dass symbolische Verknüpfungen
     nicht verfolgt werden. Wenn DIRECTORIES? wahr ist, dann werden auch
     Verzeichnisse aufgezählt. Wenn FAIL-ON-ERROR? wahr ist, dann wird
     bei einem Fehler eine Ausnahme ausgelöst.

   Nun folgen ein paar Beispiele, wobei wir annehmen, dass das aktuelle
Verzeichnis der Wurzel des Guix-Quellbaums entspricht.

     ;; Alle regulären Dateien im aktuellen Verzeichnis auflisten.
     (find-files ".")
     ⇒ ("./.dir-locals.el" "./.gitignore" …)

     ;; Alle .scm-Dateien unter gnu/services auflisten.
     (find-files "gnu/services" "\\.scm$")
     ⇒ ("gnu/services/admin.scm" "gnu/services/audio.scm" …)

     ;; ar-Dateien im aktuellen Verzeichnis auflisten.
     (find-files "." (lambda (file stat) (ar-file? file)))
     ⇒ ("./libformat.a" "./libstore.a" …)

 -- Scheme-Prozedur: which PROGRAMM
     Liefert den vollständigen Dateinamen für das PROGRAMM, der in
     ‘$PATH’ gesucht wird, oder ‘#f’, wenn das PROGRAMM nicht gefunden
     werden konnte.

 -- Scheme-Prozedur: search-input-file EINGABEN NAME
 -- Scheme-Prozedur: search-input-directory EINGABEN NAME
     Liefert den vollständigen Dateinamen von NAME, das in allen
     EINGABEN gesucht wird. ‘search-input-file’ sucht nach einer
     regulären Datei, während ‘search-input-directory’ nach einem
     Verzeichnis sucht. Wenn der NAME nicht vorkommt, wird eine Ausnahme
     ausgelöst.

     Hierbei muss für EINGABEN eine assoziative Liste wie ‘inputs’ oder
     ‘native-inputs’ übergeben werden, die für Erstellungsphasen zur
     Verfügung steht (siehe *note Erstellungsphasen::).

   Hier ist ein (vereinfachtes) Beispiel, wie ‘search-input-file’ in
einer Erstellungsphase des ‘wireguard-tools’-Pakets benutzt wird:

     (add-after 'install 'wrap-wg-quick
       (lambda* (#:key inputs outputs #:allow-other-keys)
         (let ((coreutils (string-append (assoc-ref inputs "coreutils")
                                         "/bin")))
           (wrap-program (search-input-file outputs "bin/wg-quick")
             #:sh (search-input-file inputs "bin/bash")
             `("PATH" ":" prefix ,(list coreutils))))))

9.7.5 Programme aufrufen
------------------------

Im Modul finden Sie Prozeduren, die geeignet sind, Prozesse zu erzeugen.
Hauptsächlich handelt es sich um praktische Wrapper für Guiles ‘system*’
(siehe *note ‘system*’: (guile)Processes.).

 -- Scheme-Prozedur: invoke PROGRAMM ARGUMENTE…
     PROGRAMM mit ARGUMENTE aufrufen. Es wird eine
     ‘&invoke-error’-Ausnahme ausgelöst, wenn der Exit-Code ungleich
     null ist, ansonsten wird ‘#t’ zurückgeliefert.

     Der Vorteil gegenüber ‘system*’ ist, dass Sie den Rückgabewert
     nicht zu überprüfen brauchen. So vermeiden Sie umständlichen Code
     in Shell-Skript-haften Schnipseln etwa in Erstellungsphasen von
     Paketen.

 -- Scheme-Prozedur: invoke-error? C
     Liefert wahr, wenn C ein ‘&invoke-error’-Zustand ist.

 -- Scheme-Prozedur: invoke-error-program C
 -- Scheme-Prozedur: invoke-error-arguments C
 -- Scheme-Prozedur: invoke-error-exit-status C
 -- Scheme-Prozedur: invoke-error-term-signal C
 -- Scheme-Prozedur: invoke-error-stop-signal C
     Auf bestimmte Felder von C zugreifen, einem
     ‘&invoke-error’-Zustand.

 -- Scheme-Prozedur: report-invoke-error C [PORT]
     Auf PORT (nach Vorgabe der ‘current-error-port’) eine Meldung für
     C, einem ‘&invoke-error’-Zustand, menschenlesbar ausgeben.

     Normalerweise würden Sie das so benutzen:

          (use-modules (srfi srfi-34) ;für 'guard'
                       (guix build utils))

          (guard (c ((invoke-error? c)
                     (report-invoke-error c)))
            (invoke "date" "--imaginary-option"))

          ⊣ command "date" "--imaginary-option" failed with status 1

 -- Scheme-Prozedur: invoke/quiet PROGRAMM ARGUMENTE…
     PROGRAMM mit ARGUMENTE aufrufen und dabei die Standardausgabe und
     Standardfehlerausgabe von PROGRAMM einfangen. Wenn PROGRAMM
     erfolgreich ausgeführt wird, wird _nichts_ ausgegeben und der
     unbestimmte Wert ‘*unspecified*’ zurückgeliefert. Andernfalls wird
     ein ‘&message’-Fehlerzustand ausgelöst, der den Status-Code und die
     Ausgabe von PROGRAMM enthält.

     Hier ist ein Beispiel:

          (use-modules (srfi srfi-34) ;für 'guard'
                       (srfi srfi-35) ;für 'message-condition?'
                       (guix build utils))

          (guard (c ((message-condition? c)
                     (display (condition-message c))))
            (invoke/quiet "date")  ;alles in Ordnung
            (invoke/quiet "date" "--imaginary-option"))

          ⊣ 'date --imaginary-option' exited with status 1; output follows:

              date: Unbekannte Option »--imaginary-option«
              „date --help“ liefert weitere Informationen.

9.7.6 Erstellungsphasen
-----------------------

‘(guix build utils)’ enthält auch Werkzeuge, um die von
Erstellungssystemen benutzten Erstellungsphasen zu verändern (siehe
*note Erstellungssysteme::). Erstellungsphasen werden durch assoziative
Listen oder „Alists“ repräsentiert (siehe *note (guile)Association
Lists::), wo jeder Schlüssel ein Symbol ist, das den Namen der Phase
angibt, und der assoziierte Wert eine Prozedur ist (siehe *note
Erstellungsphasen::).

   Die zum Kern von Guile („Guile core“) gehörenden Prozeduren und das
Modul ‘(srfi srfi-1)’ stellen beide Werkzeuge zum Bearbeiten von Alists
zur Verfügung. Das Modul ‘(guix build utils)’ ergänzt sie um Werkzeuge,
die speziell für Erstellungsphasen gedacht sind.

 -- Scheme-Syntax: modify-phases PHASEN KLAUSEL…
     Die PHASEN der Reihe nach entsprechend jeder KLAUSEL ändern. Die
     Klauseln dürfen eine der folgenden Formen haben:

          (delete ALTER-PHASENNAME)
          (replace ALTER-PHASENNAME NEUE-PHASE)
          (add-before ALTER-PHASENNAME NEUER-PHASENNAME NEUE-PHASE)
          (add-after ALTER-PHASENNAME NEUER-PHASENNAME NEUE-PHASE)

     Jeder PHASENNAME oben ist ein Ausdruck, der zu einem Symbol
     auswertet, und NEUE-PHASE ist ein Ausdruck, der zu einer Prozedur
     auswertet.

   Folgendes Beispiel stammt aus der Definition des ‘grep’-Pakets. Es
fügt eine neue Phase namens ‘egrep-und-fgrep-korrigieren’ hinzu, die auf
die ‘install’-Phase folgen soll. Diese Phase ist eine Prozedur
(‘lambda*’ bedeutet, sie ist eine Prozedur ohne eigenen Namen), die ein
Schlüsselwort ‘#:outputs’ bekommt und die restlichen
Schlüsselwortargumente ignoriert (siehe *note (guile)Optional
Arguments:: für mehr Informationen zu ‘lambda*’ und optionalen sowie
Schlüsselwort-Argumenten). In der Phase wird ‘substitute*’ benutzt, um
die installierten Skripte ‘egrep’ und ‘fgrep’ so zu verändern, dass sie
‘grep’ anhand seines absoluten Dateinamens aufrufen:

     (modify-phases %standard-phases
       (add-after 'install 'egrep-und-fgrep-korrigieren
         ;; 'egrep' und 'fgrep' patchen, damit diese 'grep' über den
         ;; absoluten Dateinamen ausführen, statt es in $PATH zu suchen.
         (lambda* (#:key outputs #:allow-other-keys)
           (let* ((out (assoc-ref outputs "out"))
                  (bin (string-append out "/bin")))
             (substitute* (list (string-append bin "/egrep")
                                (string-append bin "/fgrep"))
               (("^exec grep")
                (string-append "exec " bin "/grep")))))))

   In dem Beispiel, das nun folgt, werden Phasen auf zweierlei Art
geändert: Die Standard-‘configure’-Phase wird gelöscht, meistens weil
das Paket über kein ‘configure’-Skript oder etwas Ähnliches verfügt, und
die vorgegebene ‘install’-Phase wird durch eine ersetzt, in der die zu
installierenden ausführbaren Dateien manuell kopiert werden.

     (modify-phases %standard-phases
       (delete 'configure)      ;kein 'configure'-Skript
       (replace 'install
         (lambda* (#:key outputs #:allow-other-keys)
           ;; Das Makefile im Paket enthält kein "install"-Ziel,
           ;; also müssen wir es selber machen.
           (let ((bin (string-append (assoc-ref outputs "out")
                                     "/bin")))
             (install-file "footswitch" bin)
             (install-file "scythe" bin)))))

9.7.7 Wrapper
-------------

Es kommt vor, dass Befehle nur richtig funktionieren, wenn bestimmte
Umgebungsvariable festgelegt sind. Meistens geht es dabei um Suchpfade
(siehe *note Suchpfade::). Wenn man sie nicht zuweist, finden die
Programme vielleicht benötigte Dateien oder andere Befehle _nicht_ oder
sie nehmen die „falschen“, je nachdem, in welcher Umgebung man sie
ausführt. Einige Beispiele:

   • ein Shell-Skript, wo erwartet wird, dass die darin benutzten
     Befehle in ‘PATH’ zu finden sind,

   • ein Guile-Programm, wo erwartet wird, dass dessen Module in
     ‘GUILE_LOAD_PATH’ und ‘GUILE_LOAD_COMPILED_PATH’ liegen,

   • eine Qt-Anwendung, für die bestimmte Plugins in ‘QT_PLUGIN_PATH’
     erwartet werden.

   Das Ziel einer Paketautorin ist, dass Befehle immer auf gleiche Weise
funktionieren statt von externen Einstellungen abhängig zu sein. Eine
Möglichkeit, das zu bewerkstelligen, ist, Befehle in ein dünnes
“Wrapper”-Skript einzukleiden, welches diese Umgebungsvariablen festlegt
und so dafür sorgt, dass solche Laufzeitabhängigkeiten sicherlich
gefunden werden. Der Wrapper würde in den obigen Beispielen also
benutzt, um ‘PATH’, ‘GUILE_LOAD_PATH’ oder ‘QT_PLUGIN_PATH’ festzulegen.

   Das Wrappen wird erleichtert durch ein paar Hilfsprozeduren im Modul
‘(guix build utils)’, mit denen Sie Befehle wrappen können.

 -- Scheme-Prozedur: wrap-program PROGRAMM [#:sh SH] [#:rest VARIABLE]
          Einen Wrapper für PROGRAMM
     anlegen. Die Liste VARIABLE sollte so aussehen:

          '(VARIABLE TRENNZEICHEN POSITION LISTE-VON-VERZEICHNISSEN)

     Das TRENNZEICHEN ist optional. Wenn Sie keines angeben, wird ‘:’
     genommen.

     Zum Beispiel kopiert dieser Aufruf:

          (wrap-program "foo"
                        '("PATH" ":" = ("/gnu/…/bar/bin"))
                        '("CERT_PATH" suffix ("/gnu/…/baz/certs"
                                              "/qux/certs")))

     ‘foo’ nach ‘.foo-real’ und erzeugt die Datei ‘foo’ mit folgendem
     Inhalt:

          #!ort/mit/bin/bash
          export PATH="/gnu/…/bar/bin"
          export CERT_PATH="$CERT_PATH${CERT_PATH:+:}/gnu/…/baz/certs:/qux/certs"
          exec -a $0 ort/mit/.foo-real "$@"

     Wenn PROGRAMM bereits mit ‘wrap-program’ gewrappt wurde, wird sein
     bestehender Wrapper um die Definitionen jeder Variable in der
     VARIABLE-Liste ergänzt. Ansonsten wird ein Wrapper mit SH als
     Interpretierer angelegt.

 -- Scheme-Prozedur: wrap-script PROGRAMM [#:guile GUILE] [#:rest
          VARIABLE] Das Skript PROGRAMM in
     einen Wrapper wickeln, damit VARIABLE vorher festgelegt werden. Das
     Format für VARIABLE ist genau wie bei der Prozedur ‘wrap-program’.
     Der Unterschied zu ‘wrap-program’ ist, dass kein getrenntes
     Shell-Skript erzeugt wird, sondern das PROGRAMM selbst abgeändert
     wird, indem zu Beginn von PROGRAMM ein Guile-Skript platziert wird.
     In der Sprache des Skripts wird das Guile-Skript als Kommentar
     interpretiert.

     Besondere Kommentare zur Kodierung der Datei, wie es sie bei Python
     geben kann, werden auf der zweiten Zeile neu erzeugt.

     Beachten Sie, dass diese Prozedur auf dieselbe Datei nur einmal
     angewandt werden kann, denn sie auf Guile-Skripts loszulassen wird
     _nicht_ unterstützt.


File: guix.de.info,  Node: Suchpfade,  Next: Der Store,  Prev: Werkzeuge zur Erstellung,  Up: Programmierschnittstelle

9.8 Suchpfade
=============

Zahlreiche Programme und Bibliotheken suchen nach Eingabedaten in einem
“Suchpfad”, d.h. einer Liste von Verzeichnissen: Shells wie Bash suchen
ausführbare Dateien im Befehls-Suchpfad, ein C-Compiler sucht
‘.h’-Dateien in seinem Header-Suchpfad, der Python-Interpretierer sucht
‘.py’-Dateien in seinem Suchpfad, der Rechtschreibprüfer hat einen
Suchpfad für Wörterbücher und so weiter.

   Suchpfade kann man für gewöhnlich über Umgebungsvariable festlegen
(siehe *note (libc)Environment Variables::). Zum Beispiel ändern Sie die
oben genannten Suchpfade, indem Sie den Wert der Umgebungsvariablen
‘PATH’, ‘C_INCLUDE_PATH’, ‘PYTHONPATH’ (oder ‘GUIX_PYTHONPATH’) und
‘DICPATH’ festlegen – Sie wissen schon, diese Variablen, die auf ‘PATH’
enden und wenn Sie etwas daran falsch machen, werden Dinge „nicht
gefunden“.

   Vielleicht ist Ihnen auf der Befehlszeile aufgefallen, dass Guix
Bescheid weiß, welche Umgebungsvariablen definiert sein müssen und wie.
Wenn Sie Pakete in Ihr Standardprofil installieren, wird die Datei
‘~/.guix-profile/etc/profile’ angelegt, die Sie mit ‘source’ in Ihre
Shell übernehmen können, damit die Variablen richtig festgelegt sind.
Genauso werden Ihnen, wenn Sie mit ‘guix shell’ eine Umgebung mit Python
und der Python-Bibliothek NumPy erzeugen lassen und die
Befehlszeilenoption ‘--search-paths’ angeben, die Variablen ‘PATH’ und
‘GUIX_PYTHONPATH’ gezeigt (siehe *note Aufruf von guix shell::):

     $ guix shell python python-numpy --pure --search-paths
     export PATH="/gnu/store/...-profile/bin"
     export GUIX_PYTHONPATH="/gnu/store/...-profile/lib/python3.9/site-packages"

   Wenn Sie ‘--search-paths’ weglassen, werden diese Umgebungsvariablen
direkt festgelegt, so dass Python NumPy vorfinden kann:

     $ guix shell python python-numpy -- python3
     Python 3.9.6 (default, Jan  1 1970, 00:00:01)
     [GCC 10.3.0] on linux
     Type "help", "copyright", "credits" or "license" for more information.
     >>> import numpy
     >>> numpy.version.version
     '1.20.3'

   Damit das funktioniert, wurden in der Definition des ‘python’-Pakets
der dafür nötige Suchpfad und die zugehörige Umgebungsvariable
‘GUIX_PYTHONPATH’ _deklariert_. Das sieht so aus:

     (package
       (name "python")
       (version "3.9.9")
       ;; davor stehen andere Felder …
       (native-search-paths
        (list (search-path-specification
               (variable "GUIX_PYTHONPATH")
               (files (list "lib/python/3.9/site-packages"))))))

   Die Aussage hinter dem ‘native-search-paths’-Feld ist, dass wenn das
‘python’-Paket benutzt wird, die Umgebungsvariable ‘GUIX_PYTHONPATH’ so
definiert wird, dass alle Unterverzeichnisse
‘lib/python/3.9/site-packages’ in seiner Umgebung enthalten sind. (Mit
‘native-’ meinen wir, dass in einer Umgebung zur Cross-Kompilierung nur
native Eingaben zum Suchpfad hinzugefügt werden dürfen; siehe *note
‘search-paths’: „package“-Referenz.) In unserem NumPy-Beispiel oben
enthält das Profil, in dem ‘python’ auftaucht, genau ein solches
Unterverzeichnis, auf das ‘GUIX_PYTHONPATH’ festgelegt wird. Wenn es
mehrere ‘lib/python/3.9/site-packages’ gibt – etwa wenn wir über
Erstellungsumgebungen reden –, dann werden alle durch Doppelpunkte (‘:’)
getrennt zu ‘GUIX_PYTHONPATH’ hinzugefügt.

     Anmerkung: Wir weisen darauf hin, dass ‘GUIX_PYTHONPATH’ als Teil
     der Definition des ‘python’-Pakets spezifiziert wird und _nicht_
     als Teil von ‘python-numpy’. Der Grund ist, dass diese
     Umgebungsvariable zu Python „gehört“ und nicht zu NumPy: Python ist
     es, das den Wert der Variablen ausliest und befolgt.

     Daraus folgt, dass wenn Sie ein Profil ohne ‘python’ erzeugen,
     ‘GUIX_PYTHONPATH’ _nicht_ definiert wird, selbst wenn ‘.py’-Dateien
     zum Profil gehören:

          $ guix shell python-numpy --search-paths --pure
          export PATH="/gnu/store/...-profile/bin"

     Das ist logisch, wenn wir das Profil alleine betrachten: Keine
     Software im Profil würde ‘GUIX_PYTHONPATH’ auslesen.

   Selbstverständlich gibt es mehr als nur eine Sorte Suchpfad: Es gibt
Pakete, die mehrere Suchpfade berücksichtigen, solche mit anderen
Trennzeichen als dem Doppelpunkt, solche, die im Suchpfad gleich mehrere
Verzeichnisse aufnehmen, und so weiter. Ein weiterführendes Beispiel ist
der Suchpfad von libxml2: Der Wert der Umgebungsvariablen
‘XML_CATALOG_FILES’ wird durch Leerzeichen getrennt, er muss eine Liste
von ‘catalog.xml’-Dateien (keinen Verzeichnissen) fassen und diese sind
in ‘xml’-Unterverzeichnissen zu finden – ganz schön anspruchsvoll. Die
Suchpfadspezifikation dazu sieht so aus:

     (package
       (name "libxml2")
       ;; davor stehen andere Felder …
       (native-search-paths
        (list (search-path-specification
               (variable "XML_CATALOG_FILES")
               (separator " ")
               (files '("xml"))
               (file-pattern "^catalog\\.xml$")
               (file-type 'regular)))))

   Keine Angst; die meisten Suchpfadspezifikationen sind einfacher.

   Im Modul ‘(guix search-paths)’ wird der Datentyp für
Suchpfadspezifikationen definiert sowie eine Reihe von Hilfsprozeduren.
Es folgt nun die Referenz der Suchpfadspezifikationen.

 -- Datentyp: search-path-specification
     Der Datentyp für Suchpfadspezifikationen.

     ‘variable’
          Welchen Namen die Umgebungsvariable für diesen Suchpfad trägt
          (als Zeichenkette).

     ‘files’
          Eine Liste der Unterverzeichnisse, die zum Suchpfad
          hinzugefügt werden sollen.

     ‘separator’ (Vorgabe: ‘":"’)
          Die Zeichenkette, wodurch Komponenten des Suchpfads
          voneinander getrennt werden.

          Für den Sonderfall, dass für ‘separator’ der Wert ‘#f’ gewählt
          wird, handelt es sich um einen „Suchpfad mit nur einer
          Komponente“, mit anderen Worten einen Suchpfad, der höchstens
          ein Element enthalten darf. Das ist für Fälle gedacht wie die
          ‘SSL_CERT_DIR’-Variable (die OpenSSL, cURL und ein paar andere
          Pakete beachten) oder die ‘ASPELL_DICT_DIR’-Variable (auf die
          das Rechtschreibprüfprogramm GNU Aspell achtet), welche beide
          auf ein einzelnes Verzeichnis zeigen müssen.

     ‘file-type’ (Vorgabe: ‘'directory’)
          Welche Art von Datei passt – hier kann ‘'directory’ (für
          Verzeichnisse) oder ‘'regular’ (für reguläre Dateien)
          angegeben werden, aber auch jedes andere Symbol, was
          ‘stat:type’ zurückliefern kann (siehe *note ‘stat’:
          (guile)File System.).

          Im libxml2-Beispiel oben sind es reguläre Dateien, die wir
          suchen, dagegen würde beim Python-Beispiel nach Verzeichnissen
          gesucht.

     ‘file-pattern’ (Vorgabe: ‘#f’)
          Das hier muss entweder ‘#f’ oder ein regulärer Ausdruck sein,
          der angibt, welche Dateien _innerhalb_ der mit dem Feld
          ‘files’ angegebenen Unterverzeichnisse darauf passen.

          Auch hier sehen Sie im libxml2-Beispiel eine Situation, wo
          dies gebraucht wird.

   Manche Suchpfade sind an mehr als ein Paket gekoppelt. Um sie nicht
doppelt und dreifach zu spezifizieren, sind manche davon vordefiniert in
‘(guix search-paths)’.

 -- Scheme-Variable: $SSL_CERT_DIR
 -- Scheme-Variable: $SSL_CERT_FILE
     Mit diesen beiden Suchpfaden wird angegeben, wo X.509-Zertifikate
     zu finden sind (siehe *note X.509-Zertifikate::).

   Diese vordefinierten Suchpfade kann man wie im folgenden Beispiel
benutzen:

     (package
       (name "curl")
       ;; eigentlich stehen hier noch ein paar Felder …
       (native-search-paths (list $SSL_CERT_DIR $SSL_CERT_FILE)))

   Wie macht man aus Suchpfadspezifikationen einerseits und einem Haufen
Verzeichnisse andererseits nun eine Menge von Definitionen für
Umgebungsvariable? Das ist die Aufgabe von ‘evaluate-search-paths’.

 -- Scheme-Prozedur: evaluate-search-paths SUCHPFADE VERZEICHNISSE
          [GETENV] Die SUCHPFADE auswerten. Sie werden
     als Liste von Suchpfadspezifikationen übergeben und untersucht
     werden VERZEICHNISSE, eine Liste von Verzeichnisnamen. Das Ergebnis
     wird als Liste von Paaren aus Spezifikation und Wert
     zurückgeliefert. Wenn Sie GETENV angeben, werden darüber die
     momentanen Festlegungen erfasst und nur die _nicht_ bereits
     gültigen gemeldet.

   Das Modul ‘(guix profiles)’ enthält eine zugeschnittenere
Hilfsprozedur ‘load-profile’, mit der Umgebungsvariable eines Profils
festgelegt werden.


File: guix.de.info,  Node: Der Store,  Next: Ableitungen,  Prev: Suchpfade,  Up: Programmierschnittstelle

9.9 Der Store
=============

Konzeptionell ist der “Store” der Ort, wo Ableitungen nach erfolgreicher
Erstellung gespeichert werden – standardmäßig finden Sie ihn in
‘/gnu/store’. Unterverzeichnisse im Store werden “Store-Objekte” oder
manchmal auch “Store-Pfade” genannt. Mit dem Store ist eine Datenbank
assoziiert, die Informationen enthält wie zum Beispiel, welche
Store-Pfade jeder Store-Pfad jeweils referenziert, und eine Liste,
welche Store-Objekte _gültig_ sind, also Ergebnisse erfolgreicher
Erstellungen sind. Die Datenbank befindet sich in
‘LOCALSTATEDIR/guix/db’, wobei LOCALSTATEDIR das mit ‘--localstatedir’
bei der Ausführung von „configure“ angegebene Zustandsverzeichnis ist,
normalerweise ‘/var’.

   Auf den Store wird _nur_ durch den Daemon im Auftrag seiner Clients
zugegriffen (siehe *note Aufruf des guix-daemon::). Um den Store zu
verändern, verbinden sich Clients über einen Unix-Socket mit dem Daemon,
senden ihm entsprechende Anfragen und lesen dann dessen Antwort – so
etwas nennt sich entfernter Prozeduraufruf (englisch „Remote Procedure
Call“ oder kurz RPC).

     Anmerkung: Benutzer dürfen _niemals_ Dateien in ‘/gnu/store’ direkt
     verändern, sonst wären diese nicht mehr konsistent und die
     Grundannahmen im funktionalen Modell von Guix, dass die Objekte
     unveränderlich sind, wären dahin (siehe *note Einführung::).

     Siehe *note ‘guix gc --verify’: Aufruf von guix gc. für
     Informationen, wie die Integrität des Stores überprüft und nach
     versehentlichen Veränderungen unter Umständen wiederhergestellt
     werden kann.

   Das Modul ‘(guix store)’ bietet Prozeduren an, um sich mit dem Daemon
zu verbinden und entfernte Prozeduraufrufe durchzuführen. Diese werden
im Folgenden beschrieben. Das vorgegebene Verhalten von
‘open-connection’, und daher allen ‘guix’-Befehlen, ist, sich mit dem
lokalen Daemon oder dem an der in der Umgebungsvariablen
‘GUIX_DAEMON_SOCKET’ angegeben URL zu verbinden.

 -- Umgebungsvariable: GUIX_DAEMON_SOCKET
     Ist diese Variable gesetzt, dann sollte ihr Wert ein Dateipfad oder
     eine URI sein, worüber man sich mit dem Daemon verbinden kann. Ist
     der Wert der Pfad zu einer Datei, bezeichnet dieser einen
     Unix-Socket, mit dem eine Verbindung hergestellt werden soll. Ist
     er eine URI, so werden folgende URI-Schemata unterstützt:

     ‘file’
     ‘unix’
          Für Unix-Sockets. ‘file:///var/guix/daemon-socket/socket’ kann
          gleichbedeutend auch als ‘/var/guix/daemon-socket/socket’
          angegeben werden.

     ‘guix’
          Solche URIs benennen Verbindungen über TCP/IP ohne
          Verschlüsselung oder Authentifizierung des entfernten
          Rechners. Die URI muss den Hostnamen, also den Rechnernamen
          des entfernten Rechners, und optional eine Portnummer angeben
          (sonst wird als Vorgabe der Port 44146 benutzt):

               guix://master.guix.example.org:1234

          Diese Konfiguration ist für lokale Netzwerke wie etwa in
          Rechen-Clustern geeignet, wo sich nur vertrauenswürdige Knoten
          mit dem Erstellungs-Daemon z.B. unter
          ‘master.guix.example.org’ verbinden können.

          Die Befehlszeilenoption ‘--listen’ von ‘guix-daemon’ kann
          benutzt werden, damit er auf TCP-Verbindungen lauscht (siehe
          *note ‘--listen’: Aufruf des guix-daemon.).

     ‘ssh’
          Mit solchen URIs kann eine Verbindung zu einem entfernten
          Daemon über SSH hergestellt werden. Diese Funktionalität setzt
          Guile-SSH voraus (siehe *note Voraussetzungen::) sowie eine
          funktionierende ‘guile’-Binärdatei, deren Ort im ‘PATH’ der
          Zielmaschine eingetragen ist. Authentisierung über einen
          öffentlichen Schlüssel oder GSSAPI ist möglich. Eine typische
          URL sieht so aus:

               ssh://charlie@guix.example.org:22

          Was ‘guix copy’ betrifft, richtet es sich nach den üblichen
          OpenSSH-Client-Konfigurationsdateien (siehe *note Aufruf von
          guix copy::).

     In Zukunft könnten weitere URI-Schemata unterstützt werden.

          Anmerkung: Die Fähigkeit, sich mit entfernten
          Erstellungs-Daemons zu verbinden, sehen wir als experimentell
          an, Stand 1.4.0rc2. Bitte diskutieren Sie mit uns jegliche
          Probleme oder Vorschläge, die Sie haben könnten (siehe *note
          Mitwirken::).

 -- Scheme-Prozedur: open-connection [URI] [#:reserve-space? #t]
     Sich mit dem Daemon über den Unix-Socket an URI verbinden (einer
     Zeichenkette). Wenn RESERVE-SPACE? wahr ist, lässt ihn das etwas
     zusätzlichen Speicher im Dateisystem reservieren, damit der
     Müllsammler auch dann noch funktioniert, wenn die Platte zu voll
     wird. Liefert ein Server-Objekt.

     URI nimmt standardmäßig den Wert von ‘%default-socket-path’ an, was
     dem bei der Installation mit dem Aufruf von ‘configure’
     ausgewählten Vorgabeort entspricht, gemäß den
     Befehlszeilenoptionen, mit denen ‘configure’ aufgerufen wurde.

 -- Scheme-Prozedur: close-connection SERVER
     Die Verbindung zum SERVER trennen.

 -- Scheme-Variable: current-build-output-port
     Diese Variable ist an einen SRFI-39-Parameter gebunden, der auf den
     Scheme-Port verweist, an den vom Daemon empfangene
     Erstellungsprotokolle und Fehlerprotokolle geschrieben werden
     sollen.

   Prozeduren, die entfernte Prozeduraufrufe durchführen, nehmen immer
ein Server-Objekt als ihr erstes Argument.

 -- Scheme-Prozedur: valid-path? SERVER PFAD
     Liefert ‘#t’, wenn der PFAD ein gültiges Store-Objekt benennt, und
     sonst ‘#f’ (ein ungültiges Objekt kann auf der Platte gespeichert
     sein, tatsächlich aber ungültig sein, zum Beispiel weil es das
     Ergebnis einer abgebrochenen oder fehlgeschlagenen Erstellung ist).

     Ein ‘&store-protocol-error’-Fehlerzustand wird ausgelöst, wenn der
     PFAD nicht mit dem Store-Verzeichnis als Präfix beginnt
     (‘/gnu/store’).

 -- Scheme-Prozedur: add-text-to-store SERVER NAME TEXT [REFERENZEN]
     Den TEXT im Store in einer Datei namens NAME ablegen und ihren
     Store-Pfad zurückliefern. REFERENZEN ist die Liste der Store-Pfade,
     die der Store-Pfad dann referenzieren soll.

 -- Scheme-Prozedur: build-derivations STORE ABLEITUNGEN [MODUS] Die
          ABLEITUNGEN erstellen (eine Liste von
     ‘<derivation>’-Objekten, ‘.drv’-Dateinamen oder Paaren aus je
     Ableitung und Ausgabe. Dabei gilt der angegebene MODUS – vorgegeben
     ist ‘(build-mode normal)’.

   Es sei erwähnt, dass im Modul ‘(guix monads)’ eine Monade sowie
monadische Versionen obiger Prozeduren angeboten werden, damit an Code,
der auf den Store zugreift, bequemer gearbeitet werden kann (siehe *note
Die Store-Monade::).

   Dieser Abschnitt ist im Moment noch unvollständig.


File: guix.de.info,  Node: Ableitungen,  Next: Die Store-Monade,  Prev: Der Store,  Up: Programmierschnittstelle

9.10 Ableitungen
================

Systemnahe Erstellungsaktionen sowie die Umgebung, in der selbige
durchzuführen sind, werden durch “Ableitungen” dargestellt. Eine
Ableitung enthält folgende Informationen:

   • Die Ausgaben, die die Ableitung hat. Ableitungen erzeugen
     mindestens eine Datei bzw. ein Verzeichnis im Store, können aber
     auch mehrere erzeugen.

   • Die Eingaben der Ableitung, also Abhängigkeiten zur Zeit ihrer
     Erstellung, die entweder andere Ableitungen oder einfache Dateien
     im Store sind (wie Patches, Erstellungsskripts usw.).

   • Das System, wofür mit der Ableitung erstellt wird, also ihr Ziel –
     z.B. ‘x86_64-linux’.

   • Der Dateiname eines Erstellungsskripts im Store, zusammen mit den
     Argumenten, mit denen es aufgerufen werden soll.

   • Eine Liste zu definierender Umgebungsvariabler.

   Ableitungen ermöglichen es den Clients des Daemons, diesem
Erstellungsaktionen für den Store mitzuteilen. Es gibt davon zwei Arten,
sowohl Darstellungen im Arbeitsspeicher jeweils für Client und Daemon
als auch Dateien im Store, deren Namen auf ‘.drv’ enden – diese Dateien
werden als “Ableitungspfade” bezeichnet. Ableitungspfade können an die
Prozedur ‘build-derivations’ übergeben werden, damit die darin
niedergeschriebenen Erstellungsaktionen durchgeführt werden (siehe *note
Der Store::).

   Operationen wie das Herunterladen von Dateien und Checkouts von unter
Versionskontrolle stehenden Quelldateien, bei denen der Hash des Inhalts
im Voraus bekannt ist, werden als “Ableitungen mit fester Ausgabe”
modelliert. Anders als reguläre Ableitungen sind die Ausgaben von
Ableitungen mit fester Ausgabe unabhängig von ihren Eingaben – z.B.
liefert das Herunterladen desselben Quellcodes dasselbe Ergebnis
unabhängig davon, mit welcher Methode und welchen Werkzeugen er
heruntergeladen wurde.

   Den Ausgaben von Ableitungen – d.h. Erstellungergebnissen – ist eine
Liste von “Referenzen” zugeordnet, die auch der entfernte Prozeduraufruf
‘references’ oder der Befehl ‘guix gc --references’ liefert (siehe *note
Aufruf von guix gc::). Referenzen sind die Menge der
Laufzeitabhängigkeiten von Erstellungsergebnissen. Referenzen sind eine
Teilmenge der Eingaben von Ableitungen; die Teilmenge wird automatisch
ermittelt, indem der Erstellungsdaemon alle Dateien unter den Ausgaben
nach Referenzen durchsucht.

   Das Modul ‘(guix derivations)’ stellt eine Repräsentation von
Ableitungen als Scheme-Objekte zur Verfügung, zusammen mit Prozeduren,
um Ableitungen zu erzeugen und zu manipulieren. Die am wenigsten
abstrahierte Methode, eine Ableitung zu erzeugen, ist mit der Prozedur
‘derivation’:

 -- Scheme-Prozedur: derivation STORE NAME ERSTELLER ARGUMENTE
          [#:outputs '("out")] [#:hash #f] [#:hash-algo #f]
          [#:recursive? #f] [#:inputs '()] [#:env-vars '()]  [#:system
     (%current-system)] [#:references-graphs #f]  [#:allowed-references
     #f] [#:disallowed-references #f]  [#:leaked-env-vars #f]
     [#:local-build? #f]  [#:substitutable? #t] [#:properties ’()] Eine
     Ableitungen mit den ARGUMENTEn erstellen und das resultierende
     ‘<derivation>’-Objekt liefern.

     Wurden HASH und HASH-ALGO angegeben, wird eine “Ableitung mit
     fester Ausgabe” erzeugt – d.h. eine, deren Ausgabe schon im Voraus
     bekannt ist, wie z.B. beim Herunterladen einer Datei. Wenn des
     Weiteren auch RECURSIVE? wahr ist, darf die Ableitung mit fester
     Ausgabe eine ausführbare Datei oder ein Verzeichnis sein und HASH
     muss die Prüfsumme eines Archivs mit dieser Ausgabe sein.

     Ist REFERENCES-GRAPHS wahr, dann muss es eine Liste von Paaren aus
     je einem Dateinamen und einem Store-Pfad sein. In diesem Fall wird
     der Referenzengraph jedes Store-Pfads in einer Datei mit dem
     angegebenen Namen in der Erstellungsumgebung zugänglich gemacht, in
     einem einfachen Text-Format.

     Ist ALLOWED-REFERENCES ein wahr, muss es eine Liste von
     Store-Objekten oder Ausgaben sein, die die Ausgabe der Ableitung
     referenzieren darf. Ebenso muss DISALLOWED-REFERENCES, wenn es auf
     wahr gesetzt ist, eine Liste von Dingen bezeichnen, die die
     Ausgaben _nicht_ referenzieren dürfen.

     Ist LEAKED-ENV-VARS wahr, muss es eine Liste von Zeichenketten
     sein, die Umgebungsvariable benennen, die aus der Umgebung des
     Daemons in die Erstellungsumgebung überlaufen – ein „Leck“,
     englisch „leak“. Dies kann nur in Ableitungen mit fester Ausgabe
     benutzt werden, also wenn HASH wahr ist. So ein Leck kann zum
     Beispiel benutzt werden, um Variable wie ‘http_proxy’ an
     Ableitungen zu übergeben, die darüber Dateien herunterladen.

     Ist LOCAL-BUILD? wahr, wird die Ableitung als schlechter Kandidat
     für das Auslagern deklariert, der besser lokal erstellt werden
     sollte (siehe *note Auslagern des Daemons einrichten::). Dies
     betrifft kleine Ableitungen, wo das Übertragen der Daten
     aufwendiger als ihre Erstellung ist.

     Ist SUBSTITUTABLE? falsch, wird deklariert, dass für die Ausgabe
     der Ableitung keine Substitute benutzt werden sollen (siehe *note
     Substitute::). Das ist nützlich, wenn Pakete erstellt werden, die
     Details über den Prozessorbefehlssatz des Wirtssystems auslesen.

     PROPERTIES muss eine assoziative Liste enthalten, die
     „Eigenschaften“ der Ableitungen beschreibt. Sie wird genau so, wie
     sie ist, in der Ableitung gespeichert.

Hier ist ein Beispiel mit einem Shell-Skript, das als Ersteller benutzt
wird. Es wird angenommen, dass STORE eine offene Verbindung zum Daemon
ist und BASH auf eine ausführbare Bash im Store verweist:

     (use-modules (guix utils)
                  (guix store)
                  (guix derivations))

     (let ((builder   ; das Ersteller-Bash-Skript in den Store einfügen
             (add-text-to-store store "my-builder.sh"
                                "echo Hallo Welt > $out\n" '())))
       (derivation store "foo"
                   bash `("-e" ,builder)
                   #:inputs `((,bash) (,builder))
                   #:env-vars '(("HOME" . "/homeless"))))
     ⇒ #<derivation /gnu/store/…-foo.drv => /gnu/store/…-foo>

   Wie man sehen kann, ist es umständlich, diese grundlegende Methode
direkt zu benutzen. Natürlich ist es besser, Erstellungsskripts in
Scheme zu schreiben! Am besten schreibt man den Erstellungscode als
„G-Ausdruck“ und übergibt ihn an ‘gexp->derivation’. Mehr Informationen
finden Sie im Abschnitt *note G-Ausdrücke::.

   Doch es gab einmal eine Zeit, zu der ‘gexp->derivation’ noch nicht
existiert hatte und wo das Zusammenstellen von Ableitungen mit
Scheme-Erstellungscode noch mit ‘build-expression->derivation’
bewerkstelligt wurde, was im Folgenden beschrieben wird. Diese Prozedur
gilt als veraltet und man sollte nunmehr die viel schönere Prozedur
‘gexp->derivation’ benutzen.

 -- Scheme-Prozedur: build-expression->derivation STORE NAME AUSDRUCK
           [#:system (%current-system)] [#:inputs '()] [#:outputs
          '("out")] [#:hash #f] [#:hash-algo #f]  [#:recursive? #f]
     [#:env-vars ’()] [#:modules ’()]  [#:references-graphs #f]
     [#:allowed-references #f]  [#:disallowed-references #f]
      [#:local-build? #f] [#:substitutable? #t] [#:guile-for-build #f]
     Liefert eine Ableitung, die den Scheme-Ausdruck AUSDRUCK als
     Ersteller einer Ableitung namens NAME ausführt. INPUTS muss die
     Liste der Eingaben enthalten, jeweils als Tupel ‘(Name
     Ableitungspfad Unterableitung)’; wird keine UNTERABLEITUNG
     angegeben, wird ‘"out"’ angenommen. MODULE ist eine Liste der Namen
     von Guile-Modulen im momentanen Suchpfad, die in den Store kopiert,
     kompiliert und zur Verfügung gestellt werden, wenn der AUSDRUCK
     ausgeführt wird – z.B. ‘((guix build utils) (guix build
     gnu-build-system))’.

     Der AUSDRUCK wird in einer Umgebung ausgewertet, in der ‘%outputs’
     an eine Liste von Ausgabe-/Pfad-Paaren gebunden wurde und in der
     ‘%build-inputs’ an eine Liste von Zeichenkette-/Ausgabepfad-Paaren
     gebunden wurde, die aus den INPUTS-Eingaben konstruiert worden ist.
     Optional kann in ENV-VARS eine Liste von Paaren aus Zeichenketten
     stehen, die Name und Wert von für den Ersteller sichtbaren
     Umgebungsvariablen angeben. Der Ersteller terminiert, indem er
     ‘exit’ mit dem Ergebnis des AUSDRUCKs aufruft; wenn also der
     AUSDRUCK den Wert ‘#f’ liefert, wird angenommen, dass die
     Erstellung fehlgeschlagen ist.

     AUSDRUCK wird mit einer Ableitung GUILE-FOR-BUILD erstellt. Wird
     kein GUILE-FOR-BUILD angegeben oder steht es auf ‘#f’, wird
     stattdessen der Wert der Fluiden ‘%guile-for-build’ benutzt.

     Siehe die Erklärungen zur Prozedur ‘derivation’ für die Bedeutung
     von REFERENCES-GRAPHS, ALLOWED-REFERENCES, DISALLOWED-REFERENCES,
     LOCAL-BUILD? und SUBSTITUTABLE?.

Hier ist ein Beispiel einer Ableitung mit nur einer Ausgabe, die ein
Verzeichnis erzeugt, in dem eine einzelne Datei enthalten ist:

     (let ((builder '(let ((out (assoc-ref %outputs "out")))
                       (mkdir out)    ; das Verzeichnis
                                      ; /gnu/store/…-goo erstellen
                       (call-with-output-file (string-append out "/test")
                         (lambda (p)
                           (display '(Hallo Guix) p))))))
       (build-expression->derivation store "goo" builder))

     ⇒ #<derivation /gnu/store/…-goo.drv => …>


File: guix.de.info,  Node: Die Store-Monade,  Next: G-Ausdrücke,  Prev: Ableitungen,  Up: Programmierschnittstelle

9.11 Die Store-Monade
=====================

Die auf dem Store arbeitenden Prozeduren, die in den vorigen Abschnitten
beschrieben wurden, nehmen alle eine offene Verbindung zum
Erstellungs-Daemon als ihr erstes Argument entgegen. Obwohl das ihnen zu
Grunde liegende Modell funktional ist, weisen sie doch alle
Nebenwirkungen auf oder hängen vom momentanen Zustand des Stores ab.

   Ersteres ist umständlich, weil die Verbindung zum Erstellungs-Daemon
zwischen all diesen Funktionen durchgereicht werden muss, so dass eine
Komposition mit Funktionen ohne diesen Parameter unmöglich wird.
Letzteres kann problematisch sein, weil Operationen auf dem Store
Nebenwirkungen und/oder Abhängigkeiten von externem Zustand haben und
ihre Ausführungsreihenfolge deswegen eine Rolle spielt.

   Hier kommt das Modul ‘(guix monads)’ ins Spiel. Im Rahmen dieses
Moduls können “Monaden” benutzt werden und dazu gehört insbesondere eine
für unsere Zwecke sehr nützliche Monade, die “Store-Monade”. Monaden
sind ein Konstrukt, mit dem zwei Dinge möglich sind: eine Assoziation
von Werten mit einem „Kontext“ (in unserem Fall ist das die Verbindung
zum Store) und das Festlegen einer Reihenfolge für Berechnungen (hiermit
sind auch Zugriffe auf den Store gemeint). Werte in einer Monade –
solche, die mit weiterem Kontext assoziiert sind – werden “monadische
Werte” genannt; Prozeduren, die solche Werte liefern, heißen “monadische
Prozeduren”.

   Betrachten Sie folgende „normale“ Prozedur:

     (define (sh-symlink store)
       ;; Eine Ableitung liefern, die mit der ausführbaren Datei „bash“
       ;; symbolisch verknüpft.
       (let* ((drv (package-derivation store bash))
              (out (derivation->output-path drv))
              (sh  (string-append out "/bin/bash")))
         (build-expression->derivation store "sh"
                                       `(symlink ,sh %output))))

   Unter Verwendung von ‘(guix monads)’ und ‘(guix gexp)’ lässt sie sich
als monadische Funktion aufschreiben:

     (define (sh-symlink)
       ;; Ebenso, liefert aber einen monadischen Wert.
       (mlet %store-monad ((drv (package->derivation bash)))
         (gexp->derivation "sh"
                           #~(symlink (string-append #$drv "/bin/bash")
                                      #$output))))

   An der zweiten Version lassen sich mehrere Dinge beobachten: Der
Parameter ‘Store’ ist jetzt implizit geworden und wurde in die Aufrufe
der monadischen Prozeduren ‘package->derivation’ und ‘gexp->derivation’
„eingefädelt“ und der von ‘package->derivation’ gelieferte monadische
Wert wurde mit ‘mlet’ statt einem einfachen ‘let’ “gebunden”.

   Wie sich herausstellt, muss man den Aufruf von ‘package->derivation’
nicht einmal aufschreiben, weil er implizit geschieht, wie wir später
sehen werden (siehe *note G-Ausdrücke::):

     (define (sh-symlink)
       (gexp->derivation "sh"
                         #~(symlink (string-append #$bash "/bin/bash")
                                    #$output)))

   Die monadische ‘sh-symlink’ einfach aufzurufen, bewirkt nichts. Wie
jemand einst sagte: „Mit einer Monade geht man um, wie mit Gefangenen,
gegen die man keine Beweise hat: Man muss sie laufen lassen.“ Um also
aus der Monade auszubrechen und die gewünschte Wirkung zu erzielen, muss
man ‘run-with-store’ benutzen:

     (run-with-store (open-connection) (sh-symlink))
     ⇒ /gnu/store/…-sh-symlink

   Erwähnenswert ist, dass das Modul ‘(guix monad-repl)’ die REPL von
Guile um neue „Befehle“ erweitert, mit denen es leichter ist, mit
monadischen Prozeduren umzugehen: ‘run-in-store’ und ‘enter-store-monad’
(siehe *note Interaktiv mit Guix arbeiten::). Mit Ersterer wird ein
einzelner monadischer Wert durch den Store „laufen gelassen“:

     scheme@(guile-user)> ,run-in-store (package->derivation hello)
     $1 = #<derivation /gnu/store/…-hello-2.9.drv => …>

   Mit Letzterer wird rekursiv eine weitere REPL betreten, in der alle
Rückgabewerte automatisch durch den Store laufen gelassen werden:

     scheme@(guile-user)> ,enter-store-monad
     store-monad@(guile-user) [1]> (package->derivation hello)
     $2 = #<derivation /gnu/store/…-hello-2.9.drv => …>
     store-monad@(guile-user) [1]> (text-file "foo" "Hallo!")
     $3 = "/gnu/store/…-foo"
     store-monad@(guile-user) [1]> ,q
     scheme@(guile-user)>

Beachten Sie, dass in einer ‘store-monad’-REPL keine nicht-monadischen
Werte zurückgeliefert werden können.

   Es gibt noch andere Meta-Befehle auf der REPL, so etwa ‘,build’,
womit ein dateiartiges Objekt erstellt wird (siehe *note Interaktiv mit
Guix arbeiten::).

   Die wichtigsten syntaktischen Formen, um mit Monaden im Allgemeinen
umzugehen, werden im Modul ‘(guix monads)’ bereitgestellt und sind im
Folgenden beschrieben.

 -- Scheme-Syntax: with-monad MONADE RUMPF ...
     Alle ‘>>=’- oder ‘return’-Formen im RUMPF in der MONADE auswerten.

 -- Scheme-Syntax: return WERT
     Einen monadischen Wert liefern, der den übergebenen WERT kapselt.

 -- Scheme-Syntax: >>= MWERT MPROZ ...
     Den monadischen Wert MWERT “binden”, wobei sein „Inhalt“ an die
     monadischen Prozeduren MPROZ… übergeben wird(1). Es kann eine
     einzelne MPROZ oder mehrere davon geben, wie in diesem Beispiel:

          (run-with-state
              (with-monad %state-monad
                (>>= (return 1)
                     (lambda (x) (return (+ 1 x)))
                     (lambda (x) (return (* 2 x)))))
            'irgendein-Zustand)

          ⇒ 4
          ⇒ irgendein-Zustand

 -- Scheme-Syntax: mlet MONADE ((VARIABLE MWERT) ...) RUMPF ...
 -- Scheme-Syntax: mlet* MONADE ((VARIABLE MWERT) ...) RUMPF ... Die
          VARIABLEn an die monadischen Werte MWERT im
     RUMPF binden, der eine Folge von Ausdrücken ist. Wie beim
     bind-Operator kann man es sich vorstellen als „Auspacken“ des
     rohen, nicht-monadischen Werts, der im MWERT steckt, wobei
     anschließend dieser rohe, nicht-monadische Wert im
     Sichtbarkeitsbereich des RUMPFs von der VARIABLEn bezeichnet wird.
     Die Form (VARIABLE -> WERT) bindet die VARIABLE an den „normalen“
     WERT, wie es ‘let’ tun würde. Die Bindungsoperation geschieht in
     der Reihenfolge von links nach rechts. Der letzte Ausdruck des
     RUMPFS muss ein monadischer Ausdruck sein und dessen Ergebnis wird
     das Ergebnis von ‘mlet’ oder ‘mlet*’ werden, wenn es durch die
     MONAD laufen gelassen wurde.

     ‘mlet*’ verhält sich gegenüber ‘mlet’ wie ‘let*’ gegenüber ‘let’
     (siehe *note (guile)Local Bindings::).

 -- Scheme-System: mbegin MONADE MAUSDRUCK ...
     Der Reihe nach den MAUSDRUCK und die nachfolgenden monadischen
     Ausdrücke binden und als Ergebnis das des letzten Ausdrucks
     liefern. Jeder Ausdruck in der Abfolge muss ein monadischer
     Ausdruck sein.

     Dies verhält sich ähnlich wie ‘mlet’, außer dass die Rückgabewerte
     der monadischen Prozeduren ignoriert werden. In diesem Sinn verhält
     es sich analog zu ‘begin’, nur auf monadischen Ausdrücken.

 -- Scheme-System: mwhen BEDINGUNG MAUSDR0 MAUSDR* ...
     Wenn die BEDINGUNG wahr ist, wird die Folge monadischer Ausdrücke
     MAUSDR0..MAUSDR* wie bei ‘mbegin’ ausgewertet. Wenn die BEDINGUNG
     falsch ist, wird ‘*unspecified*’ („unbestimmt“) in der momentanen
     Monade zurückgeliefert. Jeder Ausdruck in der Folge muss ein
     monadischer Ausdruck sein.

 -- Scheme-System: munless BEDINGUNG MAUSDR0 MAUSDR* ...
     Wenn die BEDINGUNG falsch ist, wird die Folge monadischer Ausdrücke
     MAUSDR0..MAUSDR* wie bei ‘mbegin’ ausgewertet. Wenn die BEDINGUNG
     wahr ist, wird ‘*unspecified*’ („unbestimmt“) in der momentanen
     Monade zurückgeliefert. Jeder Ausdruck in der Folge muss ein
     monadischer Ausdruck sein.

   Das Modul ‘(guix monads)’ macht die “Zustandsmonade” (englisch „state
monad“) verfügbar, mit der ein zusätzlicher Wert – der Zustand – durch
die monadischen Prozeduraufrufe _gefädelt_ werden kann.

 -- Scheme-Variable: %state-monad
     Die Zustandsmonade. Prozeduren in der Zustandsmonade können auf den
     gefädelten Zustand zugreifen und ihn verändern.

     Betrachten Sie das folgende Beispiel. Die Prozedur ‘Quadrat’
     liefert einen Wert in der Zustandsmonade zurück. Sie liefert das
     Quadrat ihres Arguments, aber sie inkrementiert auch den momentanen
     Zustandswert:

          (define (Quadrat x)
            (mlet %state-monad ((Anzahl (current-state)))
              (mbegin %state-monad
                (set-current-state (+ 1 Anzahl))
                (return (* x x)))))

          (run-with-state (sequence %state-monad (map Quadrat (iota 3))) 0)
          ⇒ (0 1 4)
          ⇒ 3

     Wird das „durch“ die Zustandsmonade ‘%state-monad’ laufen gelassen,
     erhalten wir jenen zusätzlichen Zustandswert, der der Anzahl der
     Aufrufe von ‘Quadrat’ entspricht.

 -- Monadische Prozedur: current-state
     Liefert den momentanen Zustand als einen monadischen Wert.

 -- Monadische Prozedur: set-current-state WERT
     Setzt den momentanen Zustand auf WERT und liefert den vorherigen
     Zustand als einen monadischen Wert.

 -- Monadische Prozedur: state-push WERT
     Hängt den WERT vorne an den momentanen Zustand an, der eine Liste
     sein muss. Liefert den vorherigen Zustand als monadischen Wert.

 -- Monadische Prozedur: state-pop
     Entfernt einen Wert vorne vom momentanen Zustand und liefert ihn
     als monadischen Wert zurück. Dabei wird angenommen, dass es sich
     beim Zustand um eine Liste handelt.

 -- Scheme-Prozedur: run-with-state MWERT [ZUSTAND]
     Den monadischen Wert MWERT mit ZUSTAND als initialem Zustand laufen
     lassen. Dies liefert zwei Werte: den Ergebniswert und den
     Ergebniszustand.

   Die zentrale Schnittstelle zur Store-Monade, wie sie vom Modul ‘(guix
store)’ angeboten wird, ist die Folgende:

 -- Scheme-Variable: %store-monad
     Die Store-Monade – ein anderer Name für ‘%state-monad’.

     Werte in der Store-Monade kapseln Zugriffe auf den Store. Sobald
     ihre Wirkung gebraucht wird, muss ein Wert der Store-Monade
     „ausgewertet“ werden, indem er an die Prozedur ‘run-with-store’
     übergeben wird (siehe unten).

 -- Scheme-Prozedur: run-with-store STORE MWERT [#:guile-for-build]
          [#:system (%current-system)]
     Den MWERT, einen monadischen Wert in der Store-Monade, in der
     offenen Verbindung STORE laufen lassen.

 -- Monadische Prozedur: text-file NAME TEXT [REFERENZEN]
     Als monadischen Wert den absoluten Dateinamen im Store für eine
     Datei liefern, deren Inhalt der der Zeichenkette TEXT ist.
     REFERENZEN ist dabei eine Liste von Store-Objekten, die die
     Ergebnis-Textdatei referenzieren wird; der Vorgabewert ist die
     leere Liste.

 -- Monadische Prozedur: binary-file NAME DATEN [REFERENZEN]
     Den absoluten Dateinamen im Store als monadischen Wert für eine
     Datei liefern, deren Inhalt der des Byte-Vektors DATEN ist.
     REFERENZEN ist dabei eine Liste von Store-Objekten, die die
     Ergebnis-Binärdatei referenzieren wird; der Vorgabewert ist die
     leere Liste.

 -- Monadische Prozedur: interned-file DATEI [NAME] [#:recursive? #t]
          [#:select? (const #t)] Liefert den Namen der DATEI,
     nachdem sie in den Store interniert wurde. Dabei wird der NAME als
     ihr Store-Name verwendet, oder, wenn kein NAME angegeben wurde, der
     Basisname der DATEI.

     Ist RECURSIVE? wahr, werden in der DATEI enthaltene Dateien
     rekursiv hinzugefügt; ist die DATEI eine flache Datei und
     RECURSIVE? ist wahr, wird ihr Inhalt in den Store eingelagert und
     ihre Berechtigungs-Bits übernommen.

     Steht RECURSIVE? auf wahr, wird ‘(SELECT? DATEI STAT)’ für jeden
     Verzeichniseintrag aufgerufen, wobei DATEI der absolute Dateiname
     und STAT das Ergebnis von ‘lstat’ ist, außer auf den Einträgen, wo
     SELECT? keinen wahren Wert liefert.

     Folgendes Beispiel fügt eine Datei unter zwei verschiedenen Namen
     in den Store ein:

          (run-with-store (open-connection)
            (mlet %store-monad ((a (interned-file "README"))
                                (b (interned-file "README" "LEGU-MIN")))
              (return (list a b))))

          ⇒ ("/gnu/store/rwm…-README" "/gnu/store/44i…-LEGU-MIN")

   Das Modul ‘(guix packages)’ exportiert die folgenden paketbezogenen
monadischen Prozeduren:

 -- Monadische Prozedur: package-file PAKET [DATEI] [#:system
          (%current-system)] [#:target #f]  [#:output "out"] Liefert als
     monadischen Wert den absoluten Dateinamen der DATEI innerhalb des
     Ausgabeverzeichnisses OUTPUT des PAKETs. Wird keine DATEI
     angegeben, wird der Name des Ausgabeverzeichnisses OUTPUT für das
     PAKET zurückgeliefert. Ist TARGET wahr, wird sein Wert als das
     Zielsystem bezeichnendes Tripel zum Cross-Kompilieren benutzt.

     Beachten Sie, dass durch diese Prozedur das PAKET _nicht_ erstellt
     wird, also muss ihr Ergebnis keine bereits existierende Datei
     bezeichnen, kann aber. Wir empfehlen, diese Prozedur nur dann zu
     benutzen, wenn Sie wissen, was Sie tun.

 -- Monadische Prozedur: package->derivation PAKET [SYSTEM]
 -- Monadische Prozedur: package->cross-derivation PAKET ZIEL [SYSTEM]
          Monadische Version von ‘package-derivation’
     und ‘package-cross-derivation’ (siehe *note Pakete definieren::).

   ---------- Footnotes ----------

   (1) Diese Operation wird gemeinhin „bind“ genannt, aber mit diesem
Begriff wird in Guile eine völlig andere Prozedur bezeichnet, die nichts
damit zu tun hat. Also benutzen wir dieses etwas kryptische Symbol als
Erbe der Haskell-Programmiersprache.


File: guix.de.info,  Node: G-Ausdrücke,  Next: Aufruf von guix repl,  Prev: Die Store-Monade,  Up: Programmierschnittstelle

9.12 G-Ausdrücke
================

Es gibt also „Ableitungen“, die eine Abfolge von Erstellungsaktionen
repräsentieren, die durchgeführt werden müssen, um ein Objekt im Store
zu erzeugen (siehe *note Ableitungen::). Diese Erstellungsaktionen
werden durchgeführt, nachdem der Daemon gebeten wurde, die Ableitungen
tatsächlich zu erstellen; dann führt der Daemon sie in einer isolierten
Umgebung (einem sogenannten Container) aus (siehe *note Aufruf des
guix-daemon::).

   Wenig überraschend ist, dass wir diese Erstellungsaktionen gerne in
Scheme schreiben würden. Wenn wir das tun, bekommen wir zwei
verschiedene “Schichten” von Scheme-Code(1): den „wirtsseitigen Code“
(„host code“) – also Code, der Pakete definiert, mit dem Daemon
kommuniziert etc. – und den „erstellungsseitigen Code“ („build code“) –
also Code, der die Erstellungsaktionen auch wirklich umsetzt, indem
Dateien erstellt werden, ‘make’ aufgerufen wird und so weiter (siehe
*note Erstellungsphasen::).

   Um eine Ableitung und ihre Erstellungsaktionen zu beschreiben, muss
man normalerweise erstellungsseitigen Code im wirtsseitigen Code
einbetten. Das bedeutet, man behandelt den erstellungsseitigen Code als
Daten, was wegen der Homoikonizität von Scheme – dass Code genauso als
Daten repräsentiert werden kann – sehr praktisch ist. Doch brauchen wir
hier mehr als nur den normalen Quasimaskierungsmechanismus mit
‘quasiquote’ in Scheme, wenn wir Erstellungsausdrücke konstruieren
möchten.

   Das Modul ‘(guix gexp)’ implementiert “G-Ausdrücke”, eine Form von
S-Ausdrücken, die zu Erstellungsausdrücken angepasst wurden. G-Ausdrücke
(englisch „G-expressions“, kurz “Gexps”) setzen sich grundlegend aus
drei syntaktischen Formen zusammen: ‘gexp’, ‘ungexp’ und
‘ungexp-splicing’ (alternativ einfach: ‘#~’, ‘#$’ und ‘#$@’), die
jeweils mit ‘quasiquote’, ‘unquote’ und ‘unquote-splicing’ vergleichbar
sind (siehe *note ‘quasiquote’: (guile)Expression Syntax.). Es gibt aber
auch erhebliche Unterschiede:

   • G-Ausdrücke sind dafür gedacht, in eine Datei geschrieben zu
     werden, wo sie von anderen Prozessen ausgeführt oder manipuliert
     werden können.

   • Wenn ein abstraktes Objekt wie ein Paket oder eine Ableitung
     innerhalb eines G-Ausdrucks demaskiert wird, ist das Ergebnis davon
     dasselbe, wie wenn dessen Ausgabedateiname genannt worden wäre.

   • G-Ausdrücke tragen Informationen über die Pakete oder Ableitungen
     mit sich, auf die sie sich beziehen, und diese Abhängigkeiten
     werden automatisch zu den sie benutzenden Erstellungsprozessen als
     Eingaben hinzugefügt.

   Dieser Mechanismus ist nicht auf Pakete und Ableitung beschränkt: Es
können “Compiler” definiert werden, die weitere abstrakte,
hochsprachliche Objekte auf Ableitungen oder Dateien im Store
„herunterbrechen“, womit diese Objekte dann auch in G-Ausdrücken
eingefügt werden können. Zum Beispiel sind „dateiartige Objekte“ ein
nützlicher Typ solcher abstrakter Objekte. Mit ihnen können Dateien
leicht in den Store eingefügt und von Ableitungen und anderem
referenziert werden (siehe unten ‘local-file’ und ‘plain-file’).

   Zur Veranschaulichung dieser Idee soll uns dieses Beispiel eines
G-Ausdrucks dienen:

     (define build-exp
       #~(begin
           (mkdir #$output)
           (chdir #$output)
           (symlink (string-append #$coreutils "/bin/ls")
                    "list-files")))

   Indem wir diesen G-Ausdruck an ‘gexp->derivation’ übergeben, bekommen
wir eine Ableitung, die ein Verzeichnis mit genau einer symbolischen
Verknüpfung auf ‘/gnu/store/…-coreutils-8.22/bin/ls’ erstellt:

     (gexp->derivation "das-ding" build-exp)

   Wie man es erwarten würde, wird die Zeichenkette
‘"/gnu/store/…-coreutils-8.22"’ anstelle der Referenzen auf das Paket
COREUTILS im eigentlichen Erstellungscode eingefügt und COREUTILS
automatisch zu einer Eingabe der Ableitung gemacht. Genauso wird auch
‘#$output’ (was äquivalent zur Schreibweise ‘(ungexp output)’ ist)
ersetzt durch eine Zeichenkette mit dem Namen der Ausgabe der Ableitung.

   Im Kontext der Cross-Kompilierung bietet es sich an, zwischen
Referenzen auf die _native_ Erstellung eines Pakets – also der, die auf
dem Wirtssystem ausgeführt werden kann – und Referenzen auf
Cross-Erstellungen eines Pakets zu unterscheiden. Hierfür spielt ‘#+’
dieselbe Rolle wie ‘#$’, steht aber für eine Referenz auf eine native
Paketerstellung.

     (gexp->derivation "vi"
        #~(begin
            (mkdir #$output)
            (mkdir (string-append #$output "/bin"))
            (system* (string-append #+coreutils "/bin/ln")
                     "-s"
                     (string-append #$emacs "/bin/emacs")
                     (string-append #$output "/bin/vi")))
        #:target "aarch64-linux-gnu")

Im obigen Beispiel wird die native Erstellung der COREUTILS benutzt,
damit ‘ln’ tatsächlich auf dem Wirtssystem ausgeführt werden kann, aber
danach die cross-kompilierte Erstellung von EMACS referenziert.

   Eine weitere Funktionalität von G-Ausdrücken stellen “importierte
Module” dar. Manchmal will man bestimmte Guile-Module von der
„wirtsseitigen Umgebung“ im G-Ausdruck benutzen können, deswegen sollten
diese Module in die „erstellungsseitige Umgebung“ importiert werden. Die
‘with-imported-modules’-Form macht das möglich:

     (let ((build (with-imported-modules '((guix build utils))
                    #~(begin
                        (use-modules (guix build utils))
                        (mkdir-p (string-append #$output "/bin"))))))
       (gexp->derivation "leeres-Verzeichnis"
                         #~(begin
                             #$build
                             (display "Erfolg!\n")
                             #t)))

In diesem Beispiel wird das Modul ‘(guix build utils)’ automatisch in
die isolierte Erstellungsumgebung unseres G-Ausdrucks geholt, so dass
‘(use-modules (guix build utils))’ wie erwartet funktioniert.

   Normalerweise möchten Sie, dass der _Abschluss_ eines Moduls
importiert wird – also das Modul und alle Module, von denen es abhängt –
statt nur das Modul selbst. Ansonsten scheitern Versuche, das Modul zu
benutzen, weil seine Modulabhängigkeiten fehlen. Die Prozedur
‘source-module-closure’ berechnet den Abschluss eines Moduls, indem es
den Kopf seiner Quelldatei analysiert, deswegen schafft die Prozedur
hier Abhilfe:

     (use-modules (guix modules))   ;„source-module-closure“ verfügbar machen

     (with-imported-modules (source-module-closure
                              '((guix build utils)
                                (gnu build image)))
       (gexp->derivation "etwas-mit-vm"
                         #~(begin
                             (use-modules (guix build utils)
                                          (gnu build image))
                             …)))

   Auf die gleiche Art können Sie auch vorgehen, wenn Sie nicht bloß
reine Scheme-Module importieren möchten, sondern auch „Erweiterungen“
wie Guile-Anbindungen von C-Bibliotheken oder andere „vollumfängliche“
Pakete. Sagen wir, Sie bräuchten das Paket ‘guile-json’ auf der
Erstellungsseite, dann könnten Sie es hiermit bekommen:

     (use-modules (gnu packages guile))  ;für „guile-json“

     (with-extensions (list guile-json)
       (gexp->derivation "etwas-mit-json"
                         #~(begin
                             (use-modules (json))
                             …)))

   Die syntaktische Form, in der G-Ausdrücke konstruiert werden, ist im
Folgenden zusammengefasst.

 -- Scheme-Syntax: #~AUSDRUCK
 -- Scheme-Syntax: (gexp AUSDRUCK)
     Liefert einen G-Ausdruck, der den AUSDRUCK enthält. Der AUSDRUCK
     kann eine oder mehrere der folgenden Formen enthalten:

     ‘#$OBJEKT’
     ‘(ungexp OBJEKT)’
          Eine Referenz auf das OBJEKT einführen. Das OBJEKT kann einen
          der unterstützten Typen haben, zum Beispiel ein Paket oder
          eine Ableitung, so dass die ‘ungexp’-Form durch deren
          Ausgabedateiname ersetzt wird – z.B.
          ‘"/gnu/store/…-coreutils-8.22’.

          Wenn das OBJEKT eine Liste ist, wird diese durchlaufen und
          alle unterstützten Objekte darin auf diese Weise ersetzt.

          Wenn das OBJEKT ein anderer G-Ausdruck ist, wird sein Inhalt
          eingefügt und seine Abhängigkeiten zu denen des äußeren
          G-Ausdrucks hinzugefügt.

          Wenn das OBJEKT eine andere Art von Objekt ist, wird es so wie
          es ist eingefügt.

     ‘#$OBJEKT:AUSGABE’
     ‘(ungexp OBJEKT AUSGABE)’
          Dies verhält sich wie die Form oben, bezieht sich aber
          ausdrücklich auf die angegebene AUSGABE des OBJEKTs – dies ist
          nützlich, wenn das OBJEKT mehrere Ausgaben generiert (siehe
          *note Pakete mit mehreren Ausgaben.::).

     ‘#+OBJEKT’
     ‘#+OBJEKT:AUSGABE’
     ‘(ungexp-native OBJEKT)’
     ‘(ungexp-native OBJEKT AUSGABE)’
          Das Gleiche wie ‘ungexp’, jedoch wird im Kontext einer
          Cross-Kompilierung eine Referenz auf die _native_ Erstellung
          des OBJEKTs eingefügt.

     ‘#$output[:AUSGABE]’
     ‘(ungexp output [AUSGABE])’
          Fügt eine Referenz auf die angegebene AUSGABE dieser Ableitung
          ein, oder auf die Hauptausgabe, wenn keine AUSGABE angegeben
          wurde.

          Dies ist nur bei G-Ausdrücken sinnvoll, die an
          ‘gexp->derivation’ übergeben werden.

     ‘#$@LISTE’
     ‘(ungexp-splicing LISTE)’
          Das Gleiche wie oben, jedoch wird nur der Inhalt der LISTE in
          die äußere Liste eingespleißt.

     ‘#+@LISTE’
     ‘(ungexp-native-splicing LISTE)’
          Das Gleiche, aber referenziert werden native Erstellungen der
          Objekte in der LISTE.

     G-Ausdrücke, die mit ‘gexp’ oder ‘#~’ erzeugt wurden, sind zur
     Laufzeit Objekte vom Typ ‘gexp?’ (siehe unten).

 -- Scheme-Syntax: with-imported-modules MODULE RUMPF…
     Markiert die in RUMPF… definierten G-Ausdrücke, dass sie in ihrer
     Ausführungsumgebung die angegebenen MODULE brauchen.

     Jedes Objekt unter den MODULEn kann der Name eines Moduls wie
     ‘(guix build utils)’ sein, oder es kann nacheinander ein Modulname,
     ein Pfeil und ein dateiartiges Objekt sein:

          `((guix build utils)
            (guix gcrypt)
            ((guix config) => ,(scheme-file "config.scm"
                                            #~(define-module …))))

     Im Beispiel oben werden die ersten beiden Module vom Suchpfad
     genommen und das letzte aus dem angegebenen dateiartigen Objekt
     erzeugt.

     Diese Form hat einen _lexikalischen_ Sichtbarkeitsbereich: Sie
     wirkt sich auf die direkt in RUMPF… definierten G-Ausdrücke aus,
     aber nicht auf jene, die, sagen wir, in aus RUMPF… heraus
     aufgerufenen Prozeduren definiert wurden.

 -- Scheme-Syntax: with-extensions ERWEITERUNGEN RUMPF…
     Markiert die in RUMPF… definierten G-Ausdrücke, dass sie
     ERWEITERUNGEN in ihrer Erstellungs- und Ausführungsumgebung
     benötigen. ERWEITERUNGEN sind typischerweise eine Liste von
     Paketobjekten wie zum Beispiel die im Modul ‘(gnu packages guile)’
     definierten.

     Konkret werden die unter den ERWEITERUNGEN aufgeführten Pakete zum
     Ladepfad hinzugefügt, während die in RUMPF… aufgeführten
     importierten Module kompiliert werden und sie werden auch zum
     Ladepfad des von RUMPF… gelieferten G-Ausdrucks hinzugefügt.

 -- Scheme-Prozedur: gexp? OBJEKT
     Liefert ‘#t’, wenn das OBJEKT ein G-Ausdruck ist.

   G-Ausdrücke sind dazu gedacht, auf die Platte geschrieben zu werden,
entweder als Code, der eine Ableitung erstellt, oder als einfache
Dateien im Store. Die monadischen Prozeduren unten ermöglichen Ihnen das
(siehe *note Die Store-Monade::, wenn Sie mehr Informationen über
Monaden suchen).

 -- Monadische Prozedur: gexp->derivation NAME AUSDRUCK [#:system
          (%current-system)] [#:target #f] [#:graft? #t]  [#:hash #f]
     [#:hash-algo #f]  [#:recursive? #f] [#:env-vars ’()] [#:modules
     ’()]  [#:module-path ‘%load-path’]  [#:effective-version "2.2"]
      [#:references-graphs #f] [#:allowed-references #f]
      [#:disallowed-references #f]  [#:leaked-env-vars #f]
      [#:script-name (string-append NAME "-builder")]
      [#:deprecation-warnings #f]  [#:local-build? #f] [#:substitutable?
     #t]  [#:properties ’()] [#:guile-for-build #f] Liefert eine
     Ableitung unter dem NAMEn, die jeden AUSDRUCK (ein G-Ausdruck) mit
     GUILE-FOR-BUILD (eine Ableitung) für das SYSTEM erstellt; der
     AUSDRUCK wird dabei in einer Datei namens SCRIPT-NAME gespeichert.
     Wenn „TARGET“ wahr ist, wird es beim Cross-Kompilieren als
     Zieltripel für mit AUSDRUCK bezeichnete Pakete benutzt.

     MODULES gilt als veraltet; stattdessen sollte
     ‘with-imported-modules’ benutzt werden. Die Bedeutung ist, dass die
     MODULE im Ausführungskontext des AUSDRUCKs verfügbar gemacht
     werden; MODULES ist dabei eine Liste von Namen von Guile-Modulen,
     die im Modulpfad MODULE-PATH gesucht werden, um sie in den Store zu
     kopieren, zu kompilieren und im Ladepfad während der Ausführung des
     AUSDRUCKs verfügbar zu machen – z.B. ‘((guix build utils) (guix
     build gnu-build-system))’.

     EFFECTIVE-VERSION bestimmt, unter welcher Zeichenkette die
     Erweiterungen des AUSDRUCKs zum Suchpfad hinzugefügt werden (siehe
     ‘with-extensions’) – z.B. ‘"2.2"’.

     GRAFT? bestimmt, ob vom AUSDRUCK benannte Pakete veredelt werden
     sollen, falls Veredelungen zur Verfügung stehen.

     Ist REFERENCES-GRAPHS wahr, muss es eine Liste von Tupeln in einer
     der folgenden Formen sein:

          (DATEINAME PAKET)
          (DATEINAME PAKET AUSGABE)
          (DATEINAME ABLEITUNG)
          (DATEINAME ABLEITUNG AUSGABE)
          (DATEINAME STORE-OBJEKT)

     Bei jedem Element von REFERENCES-GRAPHS wird das rechts Stehende
     automatisch zu einer Eingabe des Erstellungsprozesses vom AUSDRUCK
     gemacht. In der Erstellungsumgebung enthält das, was mit DATEINAME
     bezeichnet wird, den Referenzgraphen des entsprechenden Objekts in
     einem einfachen Textformat.

     ALLOWED-REFERENCES muss entweder ‘#f’ oder eine Liste von
     Ausgabenamen und Paketen sein. Eine solche Liste benennt
     Store-Objekte, die das Ergebnis referenzieren darf. Jede Referenz
     auf ein nicht dort aufgeführtes Store-Objekt löst einen
     Erstellungsfehler aus. Genauso funktioniert DISALLOWED-REFERENCES,
     was eine Liste von Objekten sein kann, die von den Ausgaben nicht
     referenziert werden dürfen.

     DEPRECATION-WARNINGS bestimmt, ob beim Kompilieren von Modulen
     Warnungen angezeigt werden sollen, wenn auf als veraltet markierten
     Code zugegriffen wird. DEPRECATION-WARNINGS kann ‘#f’, ‘#t’ oder
     ‘'detailed’ (detailliert) sein.

     Die anderen Argumente verhalten sich wie bei ‘derivation’ (siehe
     *note Ableitungen::).

   Die im Folgenden erklärten Prozeduren ‘local-file’, ‘plain-file’,
‘computed-file’, ‘program-file’ und ‘scheme-file’ liefern “dateiartige
Objekte”. Das bedeutet, dass diese Objekte, wenn sie in einem G-Ausdruck
demaskiert werden, zu einer Datei im Store führen. Betrachten Sie zum
Beispiel diesen G-Ausdruck:

     #~(system* #$(file-append glibc "/sbin/nscd") "-f"
                #$(local-file "/tmp/my-nscd.conf"))

   Der Effekt hiervon ist, dass ‘/tmp/my-nscd.conf’ „interniert“ wird,
indem es in den Store kopiert wird. Sobald er umgeschrieben wurde, zum
Beispiel über ‘gexp->derivation’, referenziert der G-Ausdruck diese
Kopie im ‘/gnu/store’. Die Datei in ‘/tmp’ zu bearbeiten oder zu
löschen, hat dann keinen Effekt mehr darauf, was der G-Ausdruck tut.
‘plain-file’ kann in ähnlicher Weise benutzt werden, es unterscheidet
sich aber darin, dass dort der Prozedur der Inhalt der Datei als eine
Zeichenkette übergeben wird.

 -- Scheme-Prozedur: local-file DATEI [NAME] [#:recursive? #f]
          [#:select? (const #t)] Liefert ein Objekt, dass die lokale
     Datei DATEI repräsentiert und sie zum Store hinzufügen lässt;
     dieses Objekt kann in einem G-Ausdruck benutzt werden. Wurde für
     die DATEI ein relativer Dateiname als literaler Ausdruck angegeben,
     wird sie relativ zur Quelldatei gesucht, in der diese Form steht.
     Wurde die DATEI _nicht_ als literale Zeichenkette angegeben, wird
     sie zur Laufzeit relativ zum aktuellen Arbeitsverzeichnis gesucht.
     Die DATEI wird unter dem angegebenen NAMEn im Store abgelegt – als
     Vorgabe wird dabei der Basisname der DATEI genommen.

     Ist RECURSIVE? wahr, werden in der DATEI enthaltene Dateien
     rekursiv hinzugefügt; ist die DATEI eine flache Datei und
     RECURSIVE? ist wahr, wird ihr Inhalt in den Store eingelagert und
     ihre Berechtigungs-Bits übernommen.

     Steht RECURSIVE? auf wahr, wird ‘(SELECT? DATEI STAT)’ für jeden
     Verzeichniseintrag aufgerufen, wobei DATEI der absolute Dateiname
     und STAT das Ergebnis von ‘lstat’ ist, außer auf den Einträgen, wo
     SELECT? keinen wahren Wert liefert.

     Dies ist das deklarative Gegenstück zur monadischen Prozedur
     ‘interned-file’ (siehe *note ‘interned-file’: Die Store-Monade.).

 -- Scheme-Prozedur: plain-file NAME INHALT
     Liefert ein Objekt, das eine Textdatei mit dem angegebenen NAMEn
     repräsentiert, die den angegebenen INHALT hat (eine Zeichenkette
     oder ein Bytevektor), welche zum Store hinzugefügt werden soll.

     Dies ist das deklarative Gegenstück zu ‘text-file’.

 -- Scheme-Prozedur: computed-file NAME G-AUSDRUCK [#:local-build? #t]
          [#:options '()] Liefert ein Objekt, das das Store-Objekt
     mit dem NAMEn repräsentiert, eine Datei oder ein Verzeichnis, das
     vom G-AUSDRUCK berechnet wurde. Wenn LOCAL-BUILD? auf wahr steht
     (wie vorgegeben), wird auf der lokalen Maschine erstellt. OPTIONS
     ist eine Liste zusätzlicher Argumente, die an ‘gexp->derivation’
     übergeben werden.

     Dies ist das deklarative Gegenstück zu ‘gexp->derivation’.

 -- Monadische Prozedur: gexp->script NAME AUSDRUCK [#:guile
          (default-guile)] [#:module-path %load-path]  [#:system
     (%current-system)] [#:target #f] Liefert ein ausführbares Skript
     namens NAME, das den AUSDRUCK mit dem angegebenen GUILE ausführt,
     wobei vom AUSDRUCK importierte Module in seinem Suchpfad stehen.
     Die Module des AUSDRUCKs werden dazu im Modulpfad MODULE-PATH
     gesucht.

     Folgendes Beispiel erstellt ein Skript, das einfach nur den Befehl
     ‘ls’ ausführt:

          (use-modules (guix gexp) (gnu packages base))

          (gexp->script "list-files"
                        #~(execl #$(file-append coreutils "/bin/ls")
                                 "ls"))

     Lässt man es durch den Store „laufen“ (siehe *note
     ‘run-with-store’: Die Store-Monade.), erhalten wir eine Ableitung,
     die eine ausführbare Datei ‘/gnu/store/…-list-files’ generiert,
     ungefähr so:

          #!/gnu/store/…-guile-2.0.11/bin/guile -ds
          !#
          (execl "/gnu/store/…-coreutils-8.22"/bin/ls" "ls")

 -- Scheme-Prozedur: program-file NAME G-AUSDRUCK [#:guile #f]
          [#:module-path %load-path] Liefert ein Objekt, das eine
     ausführbare Store-Datei NAME repräsentiert, die den G-AUSDRUCK
     ausführt. GUILE ist das zu verwendende Guile-Paket, mit dem das
     Skript ausgeführt werden kann. Importierte Module des G-AUSDRUCKs
     werden im Modulpfad MODULE-PATH gesucht.

     Dies ist das deklarative Gegenstück zu ‘gexp->script’.

 -- Monadische Prozedur: gexp->file NAME G-AUSDRUCK [#:set-load-path?
          #t] [#:module-path %load-path]  [#:splice? #f]  [#:guile
     (default-guile)] Liefert eine Ableitung, die eine Datei NAME
     erstellen wird, deren Inhalt der G-AUSDRUCK ist. Ist SPLICE? wahr,
     dann wird G-AUSDRUCK stattdessen als eine Liste von mehreren
     G-Ausdrücken behandelt, die alle in die resultierende Datei
     gespleißt werden.

     Ist SET-LOAD-PATH? wahr, wird in die resultierende Datei Code
     hinzugefügt, der den Ladepfad ‘%load-path’ und den Ladepfad für
     kompilierte Dateien ‘%load-compiled-path’ festlegt, die für die
     importierten Module des G-AUSDRUCKs nötig sind. Die Module des
     G-AUSDRUCKs werden im Modulpfad MODULE-PATH gesucht.

     Die resultierende Datei referenziert alle Abhängigkeiten des
     G-AUSDRUCKs oder eine Teilmenge davon.

 -- Scheme-Prozedur: scheme-file NAME AUSDRUCK [#:splice? #f]
          [#:set-load-path? #t] Liefert ein Objekt, das die
     Scheme-Datei NAME mit dem G-AUSDRUCK als Inhalt repräsentiert.

     Dies ist das deklarative Gegenstück zu ‘gexp->file’.

 -- Monadische Prozedur: text-file* NAME TEXT …
     Liefert eine Ableitung als monadischen Wert, welche eine Textdatei
     erstellt, in der der gesamte TEXT enthalten ist. TEXT kann eine
     Folge nicht nur von Zeichenketten, sondern auch Objekten beliebigen
     Typs sein, die in einem G-Ausdruck benutzt werden können, also
     Paketen, Ableitungen, Objekte lokaler Dateien und so weiter. Die
     resultierende Store-Datei referenziert alle davon.

     Diese Variante sollte gegenüber ‘text-file’ bevorzugt verwendet
     werden, wann immer die zu erstellende Datei Objekte im Store
     referenzieren wird. Typischerweise ist das der Fall, wenn eine
     Konfigurationsdatei erstellt wird, die Namen von Store-Dateien
     enthält, so wie hier:

          (define (profile.sh)
            ;; Liefert den Namen eines Shell-Skripts im Store,
            ;; welcher die Umgebungsvariable „PATH“ initialisiert.
            (text-file* "profile.sh"
                        "export PATH=" coreutils "/bin:"
                        grep "/bin:" sed "/bin\n"))

     In diesem Beispiel wird die resultierende Datei
     ‘/gnu/store/…-profile.sh’ sowohl COREUTILS, GREP als auch SED
     referenzieren, so dass der Müllsammler diese nicht löscht, während
     die resultierende Datei noch lebendig ist.

 -- Scheme-Prozedur: mixed-text-file NAME TEXT …
     Liefert ein Objekt, was die Store-Datei NAME repräsentiert, die
     TEXT enthält. TEXT ist dabei eine Folge von Zeichenketten und
     dateiartigen Objekten wie zum Beispiel:

          (mixed-text-file "profile"
                           "export PATH=" coreutils "/bin:" grep "/bin")

     Dies ist das deklarative Gegenstück zu ‘text-file*’.

 -- Scheme-Prozedur: file-union NAME DATEIEN
     Liefert ein ‘<computed-file>’, das ein Verzeichnis mit allen
     DATEIEN enthält. Jedes Objekt in DATEIEN muss eine zweielementige
     Liste sein, deren erstes Element der im neuen Verzeichnis zu
     benutzende Dateiname ist und deren zweites Element ein G-Ausdruck
     ist, der die Zieldatei benennt. Hier ist ein Beispiel:

          (file-union "etc"
                      `(("hosts" ,(plain-file "hosts"
                                              "127.0.0.1 localhost"))
                        ("bashrc" ,(plain-file "bashrc"
                                               "alias ls='ls --color=auto'"))))

     Dies liefert ein Verzeichnis ‘etc’, das zwei Dateien enthält.

 -- Scheme-Prozedur: directory-union NAME DINGE
     Liefert ein Verzeichnis, was die Vereinigung (englisch „Union“) der
     DINGE darstellt, wobei DINGE eine Liste dateiartiger Objekte sein
     muss, die Verzeichnisse bezeichnen. Zum Beispiel:

          (directory-union "guile+emacs" (list guile emacs))

     Das liefert ein Verzeichnis, welches die Vereinigung der Pakete
     ‘guile’ und ‘emacs’ ist.

 -- Scheme-Prozedur: file-append OBJEKT SUFFIX …
     Liefert ein dateiartiges Objekt, das zur Aneinanderreihung von
     OBJEKT und SUFFIX umgeschrieben wird, wobei das OBJEKT ein
     herunterbrechbares Objekt und jedes SUFFIX eine Zeichenkette sein
     muss.

     Betrachten Sie zum Beispiel diesen G-Ausdruck:

          (gexp->script "uname-ausfuehren"
                        #~(system* #$(file-append coreutils
                                                  "/bin/uname")))

     Denselben Effekt könnte man erreichen mit:

          (gexp->script "uname-ausfuehren"
                        #~(system* (string-append #$coreutils
                                                  "/bin/uname")))

     Es gibt jedoch einen Unterschied, nämlich enthält das resultierende
     Skript bei ‘file-append’ tatsächlich den absoluten Dateinamen als
     Zeichenkette, während im anderen Fall das resultierende Skript
     einen Ausdruck ‘(string-append …)’ enthält, der den Dateinamen erst
     _zur Laufzeit_ zusammensetzt.

 -- Scheme-Syntax: let-system SYSTEM RUMPF…
 -- Scheme-Syntax: let-system (SYSTEM ZIELSYSTEM) RUMPF…
     SYSTEM an das System binden, für das momentan erstellt wird – z.B.
     ‘"x86_64-linux"’ –, während der RUMPF ausgeführt wird.

     In der zweiten Form wird zusätzlich das ZIEL an das aktuelle Ziel
     („Target“) bei der Cross-Kompilierung gebunden. Dabei handelt es
     sich um ein GNU-Tripel wie z.B. ‘"arm-linux-gnueabihf"’ – oder um
     ‘#f’, wenn nicht cross-kompiliert wird.

     ‘let-system’ zu benutzen, bietet sich dann an, wenn einmal das in
     den G-Ausdruck gespleißte Objekt vom Zielsystem abhängen sollte,
     wie in diesem Beispiel:

          #~(system*
             #+(let-system system
                 (cond ((string-prefix? "armhf-" system)
                        (file-append qemu "/bin/qemu-system-arm"))
                       ((string-prefix? "x86_64-" system)
                        (file-append qemu "/bin/qemu-system-x86_64"))
                       (else
                        (error "weiß nicht!"))))
             "-net" "user" #$image)

 -- Scheme-Syntax: with-parameters ((PARAMETER WERT) …) AUSDRUCK
     Mit diesem Makro verhält es sich ähnlich wie mit der
     ‘parameterize’-Form für dynamisch gebundene “Parameter” (siehe
     *note (guile)Parameters::). Der Hauptunterschied ist, dass es sich
     erst auswirkt, wenn das vom AUSDRUCK zurückgelieferte dateiartige
     Objekt auf eine Ableitung oder ein Store-Objekt heruntergebrochen
     wird.

     Eine typische Anwendung von ‘with-parameters’ ist, den für ein
     bestimmtes Objekt geltenden Systemtyp zwingend festzulegen:

          (with-parameters ((%current-system "i686-linux"))
            coreutils)

     Obiges Beispiel liefert ein Objekt, das der Erstellung von
     Coreutils für die i686-Architektur entspricht, egal was der
     aktuelle Wert von ‘%current-system’ ist.

   Natürlich gibt es zusätzlich zu in „wirtsseitigem“ Code eingebetteten
G-Ausdrücken auch Module mit „erstellungsseitig“ nutzbaren Werkzeugen.
Um klarzustellen, dass sie dafür gedacht sind, in der Erstellungsschicht
benutzt zu werden, bleiben diese Module im Namensraum ‘(guix build …)’.

   Intern werden hochsprachliche, abstrakte Objekte mit ihrem Compiler
entweder zu Ableitungen oder zu Store-Objekten “heruntergebrochen”. Wird
zum Beispiel ein Paket heruntergebrochen, bekommt man eine Ableitung,
während ein ‘plain-file’ zu einem Store-Objekt heruntergebrochen wird.
Das wird mit der monadischen Prozedur ‘lower-object’ bewerkstelligt.

 -- Monadische Prozedur: lower-object OBJEKT [SYSTEM] [#:target #f]
          Liefert die Ableitung oder das Store-Objekt, das dem
     OBJEKT für SYSTEM als Wert in der Store-Monade ‘%store-monad’
     entspricht, cross-kompiliert für das Zieltripel TARGET, wenn TARGET
     wahr ist. Das OBJEKT muss ein Objekt sein, für das es einen mit ihm
     assoziierten G-Ausdruck-Compiler gibt, wie zum Beispiel ein
     ‘<package>’.

 -- Prozedur: gexp->approximate-sexp G-AUSDRUCK
     Es kann gelegentlich nützlich sein, einen G-Ausdruck in einen
     S-Ausdruck umzuwandeln, weil zum Beispiel manche Prüfer (siehe
     *note Aufruf von guix lint::) einen Blick auf die Erstellungsphasen
     eines Pakets werfen, um mögliche Fehler zu finden. Diese Umwandlung
     können Sie mit dieser Prozedur bewerkstelligen. Allerdings kann
     dabei manche Information verloren gehen. Genauer gesagt werden
     herunterbrechbare Objekte stillschweigend durch ein beliebiges
     Objekt ersetzt. Zurzeit ist dieses beliebige Objekt die Liste
     ‘(*approximate*)’, aber verlassen Sie sich nicht darauf, dass es so
     bleibt.

   ---------- Footnotes ----------

   (1) Der Begriff “Schicht”, englisch Stratum, wurde in diesem Kontext
von Manuel Serrano et al. in ihrer Arbeit an Hop geprägt. Oleg Kiselyov,
der aufschlussreiche Essays und Code zu diesem Thema
(http://okmij.org/ftp/meta-programming/#meta-scheme) geschrieben hat,
nennt diese Art der Code-Generierung “Staging”, deutsch etwa
Inszenierung bzw. Aufführung.


File: guix.de.info,  Node: Aufruf von guix repl,  Next: Interaktiv mit Guix arbeiten,  Prev: G-Ausdrücke,  Up: Programmierschnittstelle

9.13 ‘guix repl’ aufrufen
=========================

Der Befehl ‘guix repl’ erleichtert es, Guix von Guile aus zu
programmieren. Dazu startet er eine Guile-REPL (“Read-Eval-Print Loop”,
kurz REPL, deutsch Lese-Auswerten-Schreiben-Schleife) zur interaktiven
Programmierung (siehe *note (guile)Using Guile Interactively::) oder er
führt Guile-Skripts aus (siehe *note (guile)Running Guile Scripts::). Im
Vergleich dazu, einfach den Befehl ‘guile’ aufzurufen, garantiert ‘guix
repl’, dass alle Guix-Module und deren Abhängigkeiten im Suchpfad
verfügbar sind.

   Die allgemeine Syntax lautet:

     guix repl OPTIONEN [DATEI ARGUMENTE]

   Wird ein DATEI-Argument angegeben, wird die angegebene DATEI als
Guile-Skript ausgeführt.

     guix repl my-script.scm

   Um Argumente an das Skript zu übergeben, geben Sie davor ‘--’ an,
damit Sie nicht als Argumente an ‘guix repl’ verstanden werden:

     guix repl -- my-script.scm --input=foo.txt

   Wenn Sie möchten, dass ein Skript direkt aus der Shell heraus
ausgeführt werden kann und diejenige ausführbare Datei von Guix benutzt
wird, die sich im Suchpfad des Benutzers befindet, dann fügen Sie die
folgenden zwei Zeilen ganz oben ins Skript ein.

     #!/usr/bin/env -S guix repl --
     !#

   Ohne einen Dateinamen als Argument wird eine Guile-REPL gestartet, so
dass man Guix interaktiv benutzen kann (siehe *note Interaktiv mit Guix
arbeiten::):

     $ guix repl
     scheme@(guile-user)> ,use (gnu packages base)
     scheme@(guile-user)> coreutils
     $1 = #<package coreutils@8.29 gnu/packages/base.scm:327 3e28300>

   ‘guix repl’ implementiert zusätzlich ein einfaches maschinenlesbares
Protokoll für die REPL, das von ‘(guix inferior)’ benutzt wird, um mit
“Untergeordneten” zu interagieren, also mit getrennten Prozessen einer
womöglich anderen Version von Guix.

   Folgende OPTIONEN gibt es:

‘--type=TYP’
‘-t TYP’
     Startet eine REPL des angegebenen TYPs, der einer der Folgenden
     sein darf:

     ‘guile’
          Die Voreinstellung, mit der eine normale, voll funktionsfähige
          Guile-REPL gestartet wird.
     ‘machine’
          Startet eine REPL, die ein maschinenlesbares Protokoll
          benutzt. Dieses Protokoll wird vom Modul ‘(guix inferior)’
          gesprochen.

‘--listen=ENDPUNKT’
     Der Vorgabe nach würde ‘guix repl’ von der Standardeingabe lesen
     und auf die Standardausgabe schreiben. Wird diese
     Befehlszeilenoption angegeben, lauscht die REPL stattdessen auf dem
     ENDPUNKT auf Verbindungen. Hier sind Beispiele gültiger
     Befehlszeilenoptionen:

     ‘--listen=tcp:37146’
          Verbindungen mit dem „localhost“ auf Port 37146 akzeptieren.

     ‘--listen=unix:/tmp/socket’
          Verbindungen zum Unix-Socket ‘/tmp/socket’ akzeptieren.

‘--load-path=VERZEICHNIS’
‘-L VERZEICHNIS’
     Das VERZEICHNIS vorne an den Suchpfad für Paketmodule anfügen
     (siehe *note Paketmodule::).

     Damit können Nutzer dafür sorgen, dass ihre eigenen
     selbstdefinierten Pakete für Skript oder REPL sichtbar sind.

‘-q’
     Das Laden der ‘~/.guile’-Datei unterdrücken. Nach Voreinstellung
     würde diese Konfigurationsdatei beim Erzeugen einer REPL für
     ‘guile’ geladen.


File: guix.de.info,  Node: Interaktiv mit Guix arbeiten,  Prev: Aufruf von guix repl,  Up: Programmierschnittstelle

9.14 Interaktiv mit Guix arbeiten
=================================

Mit dem Befehl ‘guix repl’ finden Sie sich in einer netten und
freundlichen REPL wieder (das steht für Read-Eval-Print Loop, deutsch
Lese-Auswerten-Schreiben-Schleife) (siehe *note Aufruf von guix repl::).
Wenn Sie mit Guix programmieren möchten – also eigene Pakete definieren,
Manifeste schreiben, Dienste für Guix System oder Guix Home definieren
und so –, dann wird Ihnen sicher gefallen, dass Sie Ihre Ideen auf der
REPL ausprobieren können.

   Wenn Sie Emacs benutzen, eignet sich dafür Geiser am meisten (siehe
*note Perfekt eingerichtet::), aber Emacs zu benutzen ist nicht
unbedingt erforderlich, um Spaß an der REPL zu haben. Beim Verwenden von
‘guix repl’ oder ‘guile’ auf dem Terminal raten wir dazu, dass Sie
Readline aktivieren, um Autovervollständigung zu genießen, und Colorized
aktivieren für farbige Ausgaben. Führen Sie dazu dies aus:

     guix install guile guile-readline guile-colorized

… und legen Sie dann eine Datei ‘.guile’ in Ihrem Persönlichen
Verzeichnis („Home“-Verzeichnis) an mit diesem Inhalt:

     (use-modules (ice-9 readline) (ice-9 colorized))

     (activate-readline)
     (activate-colorized)

   Auf der REPL können Sie Scheme-Code auswerten lassen. Sie tippen also
einen Scheme-Ausdruck nach der Eingabeaufforderung und schon zeigt die
REPL, zu was er ausgewertet wird:

     $ guix repl
     scheme@(guix-user)> (+ 2 3)
     $1 = 5
     scheme@(guix-user)> (string-append "a" "b")
     $2 = "ab"

   Interessant wird es, wenn Sie auf der REPL anfangen, mit Guix
herumzubasteln. Dazu „importieren“ Sie zunächst das Modul ‘(guix)’,
damit Sie Zugriff auf den Hauptteil der Programmierschnittstelle haben,
und vielleicht wollen Sie auch noch andere nützliche Guix-Module
importieren. Sie könnten ‘(use-modules (guix))’ eintippen, denn es ist
gültiger Scheme-Code zum Importieren eines Moduls (siehe *note
(guile)Using Guile Modules::), aber auf der REPL können Sie den “Befehl”
‘use’ als Kurzschreibweise einsetzen (siehe *note (guile)REPL
Commands::):

     scheme@(guix-user)> ,use (guix)
     scheme@(guix-user)> ,use (gnu packages base)

   Beachten Sie, dass am Anfang jedes REPL-Befehls ein führendes Komma
stehen muss. Der Grund ist, dass ein REPL-Befehl wie ‘use’ eben _kein_
gültiger Scheme-Code ist; er wird von der REPL gesondert interpretiert.

   Durch Guix wird die Guile-REPL um zusätzliche Befehle erweitert, die
dort praktisch sind. Einer davon, der Befehl ‘build’, ist hier nützlich:
Mit ihm wird sichergestellt, dass das angegebene dateiartige Objekt
erstellt wurde; wenn nicht, wird es erstellt. In jedem Fall wird der
Dateiname jeder Ausgabe der Erstellung zurückgeliefert. Im folgenden
Beispiel erstellen wir die Pakete ‘coreutils’ und ‘grep’ sowie eine als
‘computed-file’ angegebene Datei (siehe *note ‘computed-file’:
G-Ausdrücke.), um sogleich mit der Prozedur ‘scandir’ aufzulisten, was
für Dateien in Grep im Verzeichnis ‘/bin’ enthalten sind:

     scheme@(guix-user)> ,build coreutils
     $1 = "/gnu/store/…-coreutils-8.32-debug"
     $2 = "/gnu/store/…-coreutils-8.32"
     scheme@(guix-user)> ,build grep
     $3 = "/gnu/store/…-grep-3.6"
     scheme@(guix-user)> ,build (computed-file "x" #~(mkdir #$output))
     /gnu/store/…-x.drv wird erstellt …
     $4 = "/gnu/store/…-x"
     scheme@(guix-user)> ,use(ice-9 ftw)
     scheme@(guix-user)> (scandir (string-append $3 "/bin"))
     $5 = ("." ".." "egrep" "fgrep" "grep")

   Will man die einzelnen Schritte von Guix nachvollziehen, eignet sich
der Befehl ‘lower’: Er nimmt ein dateiartiges Objekt, um es zu einer
Ableitung oder einem Store-Objekt „herunterzubrechen“ (siehe *note
Ableitungen::):

     scheme@(guix-user)> ,lower grep
     $6 = #<derivation /gnu/store/…-grep-3.6.drv => /gnu/store/…-grep-3.6 7f0e639115f0>
     scheme@(guix-user)> ,lower (plain-file "x" "Hallo!")
     $7 = "/gnu/store/…-x"

   Die vollständige Liste der REPL-Befehle bekommen Sie zu sehen, wenn
Sie ‘,help guix’ eingeben. Hier eine Referenz:

 -- REPL-Befehl: build OBJEKT
     Das OBJEKT herunterbrechen und erstellen, wenn es noch nicht
     erstellt ist. Als Ergebnis zurückgeliefert wird der Dateiname jeder
     Ausgabe.

 -- REPL-Befehl: lower OBJEKT
     Das OBJEKT zu einer Ausgabe oder einem Dateinamen im Store
     herunterbrechen und diesen zurückliefern.

 -- REPL-Befehl: verbosity STUFE
     Legt STUFE als die Ausführlichkeitsstufe für Erstellungen fest.

     Das ist das Gleiche wie die Befehlszeilenoption ‘--verbosity’
     (siehe *note Gemeinsame Erstellungsoptionen::): Stufe 0 zeigt gar
     nichts an, Stufe 1 nur Ereignisse bei der Erstellung und auf
     höheren Stufen bekommen Sie Erstellungsprotokolle angezeigt.

 -- REPL-Befehl: run-in-store AUSDRUCK
     Den AUSDRUCK, einen monadischen Ausdruck, durch die Store-Monade
     laufen lassen. Siehe *note Die Store-Monade:: für mehr Erklärungen.

 -- REPL-Befehl: enter-store-monad
     Damit betreten Sie eine neue REPL, die monadische Ausdrücke
     auswerten kann (siehe *note Die Store-Monade::). Sie können diese
     „innere“ REPL verlassen, indem Sie ‘,q’ eintippen.


File: guix.de.info,  Node: Zubehör,  Next: Fremde Architekturen,  Prev: Programmierschnittstelle,  Up: Top

10 Zubehör
**********

Dieser Abschnitt beschreibt die Befehlszeilenwerkzeuge von Guix. Manche
davon richten sich hauptsächlich an Entwickler und solche Nutzer, die
neue Paketdefinitionen schreiben, andere sind auch für ein breiteres
Publikum nützlich. Sie ergänzen die Scheme-Programmierschnittstelle um
bequeme Befehle.

* Menu:

* Aufruf von guix build::    Pakete aus der Befehlszeile heraus erstellen.
* Aufruf von guix edit::     Paketdefinitionen bearbeiten.
* Aufruf von guix download::  Eine Datei herunterladen und ihre
                                Hash-Prüfsumme ausgeben.
* Aufruf von guix hash::     Die kryptografische Prüfsumme einer Datei
                               berechnen.
* Aufruf von guix import::   Paketdefinitionen importieren.
* Aufruf von guix refresh::  Paketdefinitionen aktualisieren.
* Aufruf von guix style::    Paketdefinitionen umgestalten.
* Aufruf von guix lint::     Fehler in Paketdefinitionen finden.
* Aufruf von guix size::     Plattenplatzverbrauch profilieren.
* Aufruf von guix graph::    Den Paketgraphen visualisieren.
* Aufruf von guix publish::  Substitute teilen.
* Aufruf von guix challenge::  Die Substitut-Server anfechten.
* Aufruf von guix copy::     Mit einem entfernten Store Dateien austauschen.
* Aufruf von guix container::  Prozesse isolieren.
* Aufruf von guix weather::  Die Verfügbarkeit von Substituten
                               einschätzen.
* Aufruf von guix processes::  Auflisten der Client-Prozesse


File: guix.de.info,  Node: Aufruf von guix build,  Next: Aufruf von guix edit,  Up: Zubehör

10.1 Aufruf von ‘guix build’
============================

Der Befehl ‘guix build’ lässt Pakete oder Ableitungen samt ihrer
Abhängigkeiten erstellen und gibt die resultierenden Pfade im Store aus.
Beachten Sie, dass das Nutzerprofil dadurch nicht modifiziert wird –
eine solche Installation bewirkt der Befehl ‘guix package’ (siehe *note
Aufruf von guix package::). ‘guix build’ wird also hauptsächlich von
Entwicklern der Distribution benutzt.

   Die allgemeine Syntax lautet:

     guix build OPTIONEN PAKET-ODER-ABLEITUNG…

   Zum Beispiel wird mit folgendem Befehl die neueste Version von Emacs
und von Guile erstellt, das zugehörige Erstellungsprotokoll angezeigt
und letztendlich werden die resultierenden Verzeichnisse ausgegeben:

     guix build emacs guile

   Folgender Befehl erstellt alle Pakete, die zur Verfügung stehen:

     guix build --quiet --keep-going \
       $(guix package -A | awk '{ print $1 "@" $2 }')

   Als PAKET-ODER-ABLEITUNG muss entweder der Name eines in der
Software-Distribution zu findenden Pakets, wie etwa ‘coreutils’ oder
‘coreutils@8.20’, oder eine Ableitung wie
‘/gnu/store/…-coreutils-8.19.drv’ sein. Im ersten Fall wird nach einem
Paket mit entsprechendem Namen (und optional der entsprechenden Version)
in den Modulen der GNU-Distribution gesucht (siehe *note Paketmodule::).

   Alternativ kann die Befehlszeilenoption ‘--expression’ benutzt
werden, um einen Scheme-Ausdruck anzugeben, der zu einem Paket
ausgewertet wird; dies ist nützlich, wenn zwischen mehreren
gleichnamigen Paketen oder Paket-Varianten unterschieden werden muss.

   Null oder mehr OPTIONEN können angegeben werden. Zur Verfügung stehen
die in den folgenden Unterabschnitten beschriebenen
Befehlszeilenoptionen.

* Menu:

* Gemeinsame Erstellungsoptionen::  Erstellungsoptionen für die meisten
                                      Befehle.
* Paketumwandlungsoptionen::  Varianten von Paketen erzeugen.
* Zusätzliche Erstellungsoptionen::  Optionen spezifisch für „guix
                                        build“.
* Fehlschläge beim Erstellen untersuchen::  Praxiserfahrung beim
                                               Paketeschreiben.


File: guix.de.info,  Node: Gemeinsame Erstellungsoptionen,  Next: Paketumwandlungsoptionen,  Up: Aufruf von guix build

10.1.1 Gemeinsame Erstellungsoptionen
-------------------------------------

Einige dieser Befehlszeilenoptionen zur Steuerung des Erstellungsprozess
haben ‘guix build’ und andere Befehle, mit denen Erstellungen ausgelöst
werden können, wie ‘guix package’ oder ‘guix archive’, gemeinsam. Das
sind folgende:

‘--load-path=VERZEICHNIS’
‘-L VERZEICHNIS’
     Das VERZEICHNIS vorne an den Suchpfad für Paketmodule anfügen
     (siehe *note Paketmodule::).

     Damit können Nutzer dafür sorgen, dass ihre eigenen
     selbstdefinierten Pakete für die Befehlszeilenwerkzeuge sichtbar
     sind.

‘--keep-failed’
‘-K’
     Den Verzeichnisbaum, in dem fehlgeschlagene Erstellungen
     durchgeführt wurden, behalten. Wenn also eine Erstellung
     fehlschlägt, bleibt ihr Erstellungsbaum in ‘/tmp’ erhalten. Der
     Name dieses Unterverzeichnisses wird am Ende dem
     Erstellungsprotokolls ausgegeben. Dies hilft bei der Suche nach
     Fehlern in Erstellungen. Der Abschnitt *note Fehlschläge beim
     Erstellen untersuchen:: zeigt Ihnen Hinweise und Tricks, wie
     Erstellungsfehler untersucht werden können.

     Diese Option impliziert ‘--no-offload’ und sie hat keine
     Auswirkungen, wenn eine Verbindung zu einem entfernten Daemon über
     eine ‘guix://’-URI verwendet wurde (siehe *note die
     ‘GUIX_DAEMON_SOCKET’-Variable: Der Store.).

‘--keep-going’
‘-k’
     Weitermachen, auch wenn ein Teil der Erstellungen fehlschlägt. Das
     bedeutet, dass der Befehl erst terminiert, wenn alle Erstellungen
     erfolgreich oder mit Fehler durchgeführt wurden.

     Das normale Verhalten ist, abzubrechen, sobald eine der angegebenen
     Ableitungen fehlschlägt.

‘--dry-run’
‘-n’
     Die Ableitungen nicht erstellen.

‘--fallback’
     Wenn das Substituieren vorerstellter Binärdateien fehlschlägt,
     diese ersatzweise lokal selbst erstellen (siehe *note Fehler bei
     der Substitution::).

‘--substitute-urls=URLS’
     Die URLS als durch Leerraumzeichen getrennte Liste von Quell-URLs
     für Substitute anstelle der vorgegebenen URL-Liste für den
     ‘guix-daemon’ verwenden (siehe *note ‘guix-daemon’ URLs:
     daemon-substitute-urls.).

     Das heißt, die Substitute dürfen von den URLS heruntergeladen
     werden, sofern sie mit einem durch den Systemadministrator
     autorisierten Schlüssel signiert worden sind (siehe *note
     Substitute::).

     Wenn als URLS eine leere Zeichenkette angegeben wurde, verhält es
     sich, als wären Substitute abgeschaltet.

‘--no-substitutes’
     Benutze keine Substitute für Erstellungsergebnisse. Das heißt, dass
     alle Objekte lokal erstellt werden müssen, und kein Herunterladen
     von vorab erstellten Binärdateien erlaubt ist (siehe *note
     Substitute::).

‘--no-grafts’
     Pakete nicht „veredeln“ (engl. „graft“). Praktisch heißt das, dass
     als Veredelungen verfügbare Paketaktualisierungen nicht angewandt
     werden. Der Abschnitt *note Sicherheitsaktualisierungen:: hat
     weitere Informationen zu Veredelungen.

‘--rounds=N’
     Jede Ableitung N-mal nacheinander erstellen und einen Fehler
     melden, wenn die aufeinanderfolgenden Erstellungsergebnisse nicht
     Bit für Bit identisch sind.

     Das ist eine nützliche Methode, um nicht-deterministische
     Erstellungsprozesse zu erkennen. Nicht-deterministische
     Erstellungsprozesse sind ein Problem, weil Nutzer dadurch praktisch
     nicht _verifizieren_ können, ob von Drittanbietern bereitgestellte
     Binärdateien unverfälscht sind. Der Abschnitt *note Aufruf von guix
     challenge:: erklärt dies genauer.

     Wenn dies zusammen mit ‘--keep-failed’ benutzt wird, bleiben die
     sich unterscheidenden Ausgaben im Store unter dem Namen
     ‘/gnu/store/…-check’. Dadurch können Unterschiede zwischen den
     beiden Ergebnissen leicht erkannt werden.

‘--no-offload’
     Nicht versuchen, an andere Maschinen ausgelagerte Erstellungen zu
     benutzen (siehe *note Auslagern des Daemons einrichten::). Somit
     wird lokal erstellt, statt Erstellungen auf entfernte Maschinen
     auszulagern.

‘--max-silent-time=SEKUNDEN’
     Wenn der Erstellungs- oder Substitutionsprozess länger als
     SEKUNDEN-lang keine Ausgabe erzeugt, wird er abgebrochen und ein
     Fehler beim Erstellen gemeldet.

     Standardmäßig wird die Einstellung für den Daemon benutzt (siehe
     *note ‘--max-silent-time’: Aufruf des guix-daemon.).

‘--timeout=SEKUNDEN’
     Entsprechend wird hier der Erstellungs- oder Substitutionsprozess
     abgebrochen und als Fehlschlag gemeldet, wenn er mehr als
     SEKUNDEN-lang dauert.

     Standardmäßig wird die Einstellung für den Daemon benutzt (siehe
     *note ‘--timeout’: Aufruf des guix-daemon.).

‘-v STUFE’
‘--verbosity=STUFE’
     Die angegebene Ausführlichkeitsstufe verwenden. Als STUFE muss eine
     ganze Zahl angegeben werden. Wird 0 gewählt, wird keine Ausgabe zur
     Fehlersuche angezeigt, 1 bedeutet eine knappe Ausgabe, 2 ist wie 1,
     aber zeigt zusätzlich an, von welcher URL heruntergeladen wird, und
     3 lässt alle Erstellungsprotokollausgaben auf die
     Standardfehlerausgabe schreiben.

‘--cores=N’
‘-c N’
     Die Nutzung von bis zu N Prozessorkernen für die Erstellungen
     gestatten. Der besondere Wert ‘0’ bedeutet, dass so viele wie
     möglich benutzt werden.

‘--max-jobs=N’
‘-M N’
     Höchstens N gleichzeitige Erstellungsaufträge erlauben. Im
     Abschnitt *note ‘--max-jobs’: Aufruf des guix-daemon. finden Sie
     Details zu dieser Option und der äquivalenten Option des
     ‘guix-daemon’.

‘--debug=STUFE’
     Ein Protokoll zur Fehlersuche ausgeben, das vom Erstellungsdaemon
     kommt. Als STUFE muss eine ganze Zahl zwischen 0 und 5 angegeben
     werden; höhere Zahlen stehen für ausführlichere Ausgaben. Stufe 4
     oder höher zu wählen, kann bei der Suche nach Fehlern, wie der
     Erstellungs-Daemon eingerichtet ist, helfen.

   Intern ist ‘guix build’ im Kern eine Schnittstelle zur Prozedur
‘package-derivation’ aus dem Modul ‘(guix packages)’ und zu der Prozedur
‘build-derivations’ des Moduls ‘(guix derivations)’.

   Neben auf der Befehlszeile übergebenen Optionen beachten ‘guix build’
und andere ‘guix’-Befehle, die Erstellungen durchführen lassen, die
Umgebungsvariable ‘GUIX_BUILD_OPTIONS’.

 -- Umgebungsvariable: GUIX_BUILD_OPTIONS
     Nutzer können diese Variable auf eine Liste von
     Befehlszeilenoptionen definieren, die automatisch von ‘guix build’
     und anderen ‘guix’-Befehlen, die Erstellungen durchführen lassen,
     benutzt wird, wie in folgendem Beispiel:

          $ export GUIX_BUILD_OPTIONS="--no-substitutes -c 2 -L /foo/bar"

     Diese Befehlszeilenoptionen werden unabhängig von den auf der
     Befehlszeile übergebenen Befehlszeilenoptionen grammatikalisch
     analysiert und das Ergebnis an die bereits analysierten auf der
     Befehlszeile übergebenen Befehlszeilenoptionen angehängt.


File: guix.de.info,  Node: Paketumwandlungsoptionen,  Next: Zusätzliche Erstellungsoptionen,  Prev: Gemeinsame Erstellungsoptionen,  Up: Aufruf von guix build

10.1.2 Paketumwandlungsoptionen
-------------------------------

Eine weitere Gruppe von Befehlszeilenoptionen, die ‘guix build’ und auch
‘guix package’ unterstützen, sind “Paketumwandlungsoptionen”. Diese
Optionen ermöglichen es, “Paketvarianten” zu definieren – zum Beispiel
können Pakete aus einem anderen Quellcode als normalerweise erstellt
werden. Damit ist es leicht, angepasste Pakete schnell zu erstellen,
ohne die vollständigen Definitionen von Paketvarianten einzutippen
(siehe *note Pakete definieren::).

   Paketumwandlungsoptionen bleiben über Aktualisierungen hinweg
erhalten: ‘guix upgrade’ versucht, Umwandlungsoptionen, die vorher zur
Erstellung des Profils benutzt wurden, auf die aktualisierten Pakete
anzuwenden.

   Im Folgenden finden Sie die verfügbaren Befehlszeilenoptionen. Die
meisten Befehle unterstützen sie ebenso wie eine Option
‘--help-transform’, mit der all die verfügbaren Optionen und je eine
Kurzbeschreibung dazu angezeigt werden. (Diese Optionen werden der Kürze
wegen nicht in der Ausgabe von ‘--help’ aufgeführt.)

‘--tune[=CPU]’
     Die optimierte Version als „tunebar“ markierter Pakete benutzen.
     CPU gibt die Prozessorarchitektur an, für die optimiert werden
     soll. Wenn als CPU die Bezeichnung ‘native’ angegeben wird oder
     nichts angegeben wird, wird für den Prozessor optimiert, auf dem
     der Befehl ‘guix’ läuft.

     Gültige Namen für CPU sind genau die, die vom zugrunde liegenden
     Compiler erkannt werden. Vorgegeben ist, dass als Compiler die GNU
     Compiler Collection benutzt wird. Auf x86_64-Prozessoren gehören
     ‘nehalem’, ‘haswell’, und ‘skylake’ zu den CPU-Namen (siehe *note
     ‘-march’: (gcc)x86 Options.).

     Mit dem Erscheinen neuer Generationen von Prozessoren wächst der
     Standardbefehlssatz (die „Instruction Set Architecture“, ISA) um
     neue Befehle an, insbesondere wenn es um Befehle zur
     Parallelverarbeitung geht („Single-Instruction/Multiple-Data“,
     SIMD). Zum Beispiel implementieren sowohl die Core2- als auch die
     Skylake-Prozessoren den x86_64-Befehlssatz, jedoch können nur
     letztere AVX2-SIMD-Befehle ausführen.

     Der Mehrwert, den ‘--tune’ bringt, besteht in erster Linie bei
     Programmen, für die SIMD-Fähigkeiten geeignet wären _und_ die über
     keinen Mechanismus verfügen, zur Laufzeit die geeigneten
     Codeoptimierungen zuzuschalten. Pakete, bei denen die Eigenschaft
     ‘tunable?’ angegeben wurde, werden bei der Befehlszeilenoption
     ‘--tune’ als “tunebare Pakete” optimiert. Eine Paketdefinition, bei
     der diese Eigenschaft hinterlegt wurde, sieht so aus:

          (package
            (name "hello-simd")
            ;; …

            ;; Dieses Paket kann von SIMD-Erweiterungen profitieren,
            ;; deshalb markieren wir es als "tunebar".
            (properties '((tunable? . #t))))

     Andere Pakete werden als _nicht_ tunebar aufgefasst. Dadurch kann
     Guix allgemeine Binärdateien verwenden, wenn sich die Optimierung
     für einen bestimmten Prozessor wahrscheinlich _nicht_ lohnt.

     Bei der Erstellung tunebarer Pakete wird ‘-march=CPU’ übergeben.
     Intern wird die Befehlszeilenoption ‘-march’ durch einen
     Compiler-Wrapper an den eigentlichen Wrapper übergeben. Weil die
     Erstellungsmaschine den Code für die Mikroarchitektur vielleicht
     gar nicht ausführen kann, wird der Testkatalog bei der Erstellung
     tunebarer Pakete übersprungen.

     Damit weniger Neuerstellungen erforderlich sind, werden die von
     tunebaren Paketen abhängigen Pakete mit den optimierten Paketen
     _veredelt_ (siehe *note Veredelungen:
     Sicherheitsaktualisierungen.). Wenn Sie ‘--no-grafts’ übergeben,
     wirkt ‘--tune’ deshalb _nicht_ mehr.

     Wir geben dieser Technik den Namen “Paket-Multiversionierung”:
     Mehrere Varianten des tunebaren Pakets können erstellt werden; eine
     für jede Prozessorvariante. Das ist die grobkörnige Entsprechung
     der “Funktions-Multiversionierung”, die in der GNU-Toolchain zu
     finden ist (siehe *note (gcc)Function Multiversioning::).

‘--with-source=QUELLE’
‘--with-source=PAKET=QUELLE’
‘--with-source=PAKET@VERSION=QUELLE’
     Den Paketquellcode für das PAKET von der angegebenen QUELLE holen
     und die VERSION als seine Versionsnummer verwenden. Die QUELLE muss
     ein Dateiname oder eine URL sein wie bei ‘guix download’ (siehe
     *note Aufruf von guix download::).

     Wird kein PAKET angegeben, wird als Paketname derjenige auf der
     Befehlszeile angegebene Paketname angenommen, der zur Basis am Ende
     der QUELLE passt – wenn z.B. als QUELLE die Datei
     ‘/src/guile-2.0.10.tar.gz’ angegeben wurde, entspricht das dem
     ‘guile’-Paket.

     Ebenso wird, wenn keine VERSION angegeben wurde, die Version als
     Zeichenkette aus der QUELLE abgeleitet; im vorherigen Beispiel wäre
     sie ‘2.0.10’.

     Mit dieser Option können Nutzer versuchen, eine andere Version
     ihres Pakets auszuprobieren, als die in der Distribution enthaltene
     Version. Folgendes Beispiel lädt ‘ed-1.7.tar.gz’ von einem
     GNU-Spiegelserver herunter und benutzt es als Quelle für das
     ‘ed’-Paket:

          guix build ed --with-source=mirror://gnu/ed/ed-1.4.tar.gz

     Für Entwickler wird es einem durch ‘--with-source’ leicht gemacht,
     „Release Candidates“, also Vorabversionen, zu testen, oder sogar
     welchen Einfluss diese auf abhängige Pakete haben:

          guix build elogind --with-source=…/shepherd-0.9.0rc1.tar.gz

     … oder ein Checkout eines versionskontrollierten Repositorys in
     einer isolierten Umgebung zu erstellen:

          $ git clone git://git.sv.gnu.org/guix.git
          $ guix build guix --with-source=guix@1.0=./guix

‘--with-input=PAKET=ERSATZ’
     Abhängigkeiten vom PAKET durch eine Abhängigkeit vom ERSATZ-Paket
     ersetzen. Als PAKET muss ein Paketname angegeben werden und als
     ERSATZ eine Paketspezifikation wie ‘guile’ oder ‘guile@1.8’.

     Mit folgendem Befehl wird zum Beispiel Guix erstellt, aber statt
     der aktuellen stabilen Guile-Version hängt es von der alten
     Guile-Version ‘guile@2.0’ ab:

          guix build --with-input=guile=guile@2.0 guix

     Die Ersetzung ist rekursiv und umfassend. In diesem Beispiel würde
     nicht nur ‘guix’, sondern auch seine Abhängigkeit ‘guile-json’ (was
     auch von ‘guile’ abhängt) für ‘guile@2.0’ neu erstellt.

     Implementiert wird das alles mit der Scheme-Prozedur
     ‘package-input-rewriting’ (siehe *note ‘package-input-rewriting’:
     Pakete definieren.).

‘--with-graft=PAKET=ERSATZ’
     Dies verhält sich ähnlich wie mit ‘--with-input’, aber mit dem
     wichtigen Unterschied, dass nicht die gesamte Abhängigkeitskette
     neu erstellt wird, sondern das ERSATZ-Paket erstellt und die
     ursprünglichen Binärdateien, die auf das PAKET verwiesen haben,
     damit “veredelt” werden. Im Abschnitt *note
     Sicherheitsaktualisierungen:: finden Sie weitere Informationen über
     Veredelungen.

     Zum Beispiel veredelt folgender Befehl Wget und alle Abhängigkeiten
     davon mit der Version 3.5.4 von GnuTLS, indem Verweise auf die
     ursprünglich verwendete GnuTLS-Version ersetzt werden:

          guix build --with-graft=gnutls=gnutls@3.5.4 wget

     Das hat den Vorteil, dass es viel schneller geht, als alles neu zu
     erstellen. Die Sache hat aber einen Haken: Veredelung funktioniert
     nur, wenn das PAKET und sein ERSATZ miteinander streng kompatibel
     sind – zum Beispiel muss, wenn diese eine Programmbibliothek zur
     Verfügung stellen, deren Binärschnittstelle („Application Binary
     Interface“, kurz ABI) kompatibel sein. Wenn das ERSATZ-Paket auf
     irgendeine Art inkompatibel mit dem PAKET ist, könnte das
     Ergebnispaket unbrauchbar sein. Vorsicht ist also geboten!

‘--with-debug-info=PAKET’
     Das PAKET auf eine Weise erstellen, die Informationen zur
     Fehlersuche enthält, und von ihm abhängige Pakete damit veredeln.
     Das ist nützlich, wenn das PAKET noch keine Fehlersuchinformationen
     als installierbare ‘debug’-Ausgabe enthält (siehe *note Dateien zur
     Fehlersuche installieren::).

     Als Beispiel nehmen wir an, Inkscape stürzt bei Ihnen ab und Sie
     möchten wissen, was dabei in GLib passiert. Die GLib-Bibliothek
     liegt tief im Abhängigkeitsgraphen von Inkscape und verfügt nicht
     über eine ‘debug’-Ausgabe; das erschwert die Fehlersuche.
     Glücklicherweise können Sie GLib mit Informationen zur Fehlersuche
     neu erstellen und an Inkscape anheften:

          guix install inkscape --with-debug-info=glib

     Nur GLib muss neu kompiliert werden, was in vernünftiger Zeit
     möglich ist. Siehe *note Dateien zur Fehlersuche installieren:: für
     mehr Informationen.

          Anmerkung: Intern funktioniert diese Option, indem
          ‘#:strip-binaries? #f’ an das Erstellungssystem des
          betreffenden Pakets übergeben wird (siehe *note
          Erstellungssysteme::). Die meisten Erstellungssysteme
          unterstützen diese Option, manche aber nicht. In diesem Fall
          wird ein Fehler gemeldet.

          Auch wenn ein in C/C++ geschriebenes Paket ohne ‘-g’ erstellt
          wird (was selten der Fall ist), werden Informationen zur
          Fehlersuche weiterhin fehlen, obwohl ‘#:strip-binaries?’ auf
          falsch steht.

‘--with-c-toolchain=PAKET=TOOLCHAIN’
     Mit dieser Befehlszeilenoption wird die Kompilierung des PAKETs und
     aller davon abhängigen Objekte angepasst, so dass mit der TOOLCHAIN
     statt der vorgegebenen GNU-Toolchain für C/C++ erstellt wird.

     Betrachten Sie dieses Beispiel:

          guix build octave-cli \
            --with-c-toolchain=fftw=gcc-toolchain@10 \
            --with-c-toolchain=fftwf=gcc-toolchain@10

     Mit dem obigen Befehl wird eine Variante der Pakete ‘fftw’ und
     ‘fftwf’ mit Version 10 der ‘gcc-toolchain’ anstelle der
     vorgegebenen Toolchain erstellt, um damit anschließend eine diese
     benutzende Variante des GNU-Octave-Befehlszeilenprogramms zu
     erstellen. Auch GNU Octave selbst wird mit ‘gcc-toolchain@10’
     erstellt.

     Das zweite Beispiel bewirkt eine Erstellung der „Hardware
     Locality“-Bibliothek (‘hwloc’) sowie ihrer abhängigen Objekte bis
     einschließlich ‘intel-mpi-benchmarks’ mit dem Clang-C-Compiler:

          guix build --with-c-toolchain=hwloc=clang-toolchain \
                     intel-mpi-benchmarks

          Anmerkung: Es kann vorkommen, dass die
          Anwendungsbinärschnittstellen („Application Binary
          Interfaces“, kurz ABIs) der Toolchains inkompatibel sind. Das
          tritt vor allem bei der C++-Standardbibliothek und
          Bibliotheken zur Laufzeitunterstützung wie denen von OpenMP
          auf. Indem alle abhängigen Objekte mit derselben Toolchain
          erstellt werden, minimiert ‘--with-c-toolchain’ das Risiko,
          dass es zu Inkompatibilitäten kommt, aber es kann nicht ganz
          ausgeschlossen werden. Bedenken Sie, für welches PAKET Sie
          dies benutzen.

‘--with-git-url=PAKET=URL’
     Das PAKET aus dem neuesten Commit im ‘master’-Branch des unter der
     URL befindlichen Git-Repositorys erstellen. Git-Submodule des
     Repositorys werden dabei rekursiv geladen.

     Zum Beispiel erstellt der folgende Befehl die
     NumPy-Python-Bibliothek unter Verwendung des neuesten Commits von
     Python auf dessen „master“-Branch.

          guix build python-numpy \
            --with-git-url=python=https://github.com/python/cpython

     Diese Befehlszeilenoption kann auch mit ‘--with-branch’ oder
     ‘--with-commit’ kombiniert werden (siehe unten).

     Da es den neuesten Commit auf dem verwendeten Branch benutzt,
     ändert sich das Ergebnis natürlich mit der Zeit. Nichtsdestoweniger
     ist es eine bequeme Möglichkeit, ganze Softwarestapel auf dem
     neuesten Commit von einem oder mehr Paketen aufbauen zu lassen. Es
     ist besonders nützlich im Kontext Kontinuierlicher Integration
     (englisch „Continuous Integration“, kurz CI).

     Checkouts bleiben zwischengespeichert als
     ‘~/.cache/guix/checkouts’, damit danach schneller auf dasselbe
     Repository zugegriffen werden kann. Eventuell möchten Sie das
     Verzeichnis ab und zu bereinigen, um Plattenplatz zu sparen.

‘--with-branch=PAKET=BRANCH’
     Das PAKET aus dem neuesten Commit auf dem BRANCH erstellen. Wenn
     das ‘source’-Feld des PAKETs ein origin-Objekt mit der Methode
     ‘git-fetch’ (siehe *note „origin“-Referenz::) oder ein
     ‘git-checkout’-Objekt ist, wird die URL des Repositorys vom
     ‘source’-Feld genommen. Andernfalls müssen Sie die
     Befehlszeilenoption ‘--with-git-url’ benutzen, um die URL des
     Git-Repositorys anzugeben.

     Zum Beispiel wird mit dem folgenden Befehl ‘guile-sqlite3’ aus dem
     neuesten Commit seines ‘master’-Branches erstellt und anschließend
     ‘guix’ (was von ‘guile-sqlite3’ abhängt) und ‘cuirass’ (was von
     ‘guix’ abhängt) unter Nutzung genau dieser
     ‘guile-sqlite3’-Erstellung erstellt:

          guix build --with-branch=guile-sqlite3=master cuirass

‘--with-commit=PAKET=COMMIT’
     Dies verhält sich ähnlich wie ‘--with-branch’, außer dass es den
     angegebenen COMMIT benutzt statt die Spitze eines angegebenen
     Branches. Als COMMIT muss ein gültiger SHA1-Bezeichner, ein Tag
     oder ein Bezeichner wie von ‘git describe’ (wie ‘1.0-3-gabc123’)
     für einen Git-Commit angegeben werden.

‘--with-patch=PAKET=DATEI’
     Die DATEI zur Liste der auf das PAKET anzuwendenden Patches
     hinzufügen. Als PAKET muss eine Spezifikation wie ‘python@3.8’ oder
     ‘glibc’ benutzt werden. In der DATEI muss ein Patch enthalten sein;
     er wird mit den im Ursprung (‘origin’) des PAKETs angegebenen
     Befehlszeilenoptionen angewandt (siehe *note „origin“-Referenz::).
     Die vorgegebenen Optionen enthalten ‘-p1’ (siehe *note
     (diffutils)patch Directories::).

     Zum Beispiel wird mit dem folgenden Befehl für die Neuerstellung
     von Coreutils die GNU-C-Bibliothek (glibc) wie angegeben gepatcht:

          guix build coreutils --with-patch=glibc=./glibc-frob.patch

     In diesem Beispiel wird glibc selbst und alles, was im
     Abhängigkeitsgraphen auf dem Weg zu Coreutils liegt, neu erstellt.

‘--with-latest=PAKET’
     Sie hätten gerne das Neueste vom Neuen? Dann ist diese
     Befehlszeilenoption das Richtige für Sie! Damit wird jedes
     Vorkommen von PAKET im Abhängigkeitsgraphen durch dessen neueste
     angebotene Version ersetzt, wie sie auch von ‘guix refresh’
     gemeldet würde (siehe *note Aufruf von guix refresh::).

     Dazu wird die neueste angebotene Version des PAKETs ermittelt (wenn
     möglich), heruntergeladen und, _wenn_ eine OpenPGP-Signatur mit
     dabei ist, es damit authentifiziert.

     Zum Beispiel wird durch folgenden Befehl Guix mit der neuesten
     Version von Guile-JSON erstellt:

          guix build guix --with-latest=guile-json

     Es gibt jedoch Einschränkungen. Erstens gehen Sie in dem Fall, dass
     das Werkzeug nicht in der Lage ist oder nicht weiß, wie es den
     Quellcode authentifiziert, das Risiko ein, dass bösartiger Code
     ausgeführt wird; Ihnen wird dann eine Warnung angezeigt. Zweitens
     wird mit dieser Option einfach der Quellcode ausgetauscht und die
     übrige Paketdefinition bleibt erhalten. Manchmal reicht das nicht;
     es könnte sein, dass neue Abhängigkeiten hinzugefügt oder neue
     Patches angewandt werden müssen oder dass ganz allgemein Arbeiten
     zur Qualitätssicherung, die Guix-Entwickler normalerweise leisten,
     fehlen werden.

     Sie sind gewarnt worden! Wenn aber kein Problem auftritt, können
     Sie das Paket zackig auf den neuesten Stand bringen. Wir ermutigen
     Sie dazu, Patches einzureichen, die die eigentliche Paketdefinition
     aktualisieren, sobald Sie die neue Version erfolgreich getestet
     haben (siehe *note Mitwirken::).

‘--without-tests=PAKET’
     Das PAKET erstellen, ohne seine Tests zu durchlaufen. Das erweist
     sich als nützlich, wenn Sie Testkataloge überspringen möchten, die
     viel Zeit in Anspruch nehmen, oder wenn der Testkatalog eines
     Pakets nichtdeterministisch fehlschlägt. Dies sollte mit Bedacht
     eingesetzt werden, denn das Ausführen des Testkatalogs sichert zu,
     dass ein Paket wie gewollt funktioniert.

     Wenn die Tests abgeschaltet werden, ergibt sich ein anderes
     Store-Objekt. Dadurch muss, wenn diese Option benutzt wird, auch
     alles, was vom Paket abhängt, neu erstellt werden, wie Sie in
     diesem Beispiel sehen können:

          guix install --without-tests=python python-notebook

     Mit obigem Befehl wird ‘python-notebook’ für ein ‘python’
     installiert, dessen Testkatalog nicht ausgeführt wurde. Dazu wird
     auch alles neu erstellt, was von ‘python’ abhängt, einschließlich
     ‘python-notebook’.

     Intern funktioniert ‘--without-tests’, indem es die Option
     ‘#:tests?’ der ‘check’-Phase eines Pakets abändert (siehe *note
     Erstellungssysteme::). Beachten Sie, dass manche Pakete eine
     angepasste ‘check’-Phase benutzen, die eine Einstellung wie
     ‘#:tests? #f’ nicht berücksichtigt. Deshalb wirkt sich
     ‘--without-tests’ auf diese Pakete nicht aus.

   Sie fragen sich sicher, wie Sie dieselbe Wirkung mit Scheme-Code
erzielen können, zum Beispiel wenn Sie Ihr Manifest oder eine eigene
Paketumwandlung schreiben? Siehe *note Paketvarianten definieren:: für
eine Übersicht über verfügbare Programmierschnittstellen.

