Nächste: Erstellungssysteme, Vorige: Paketvarianten definieren, Nach oben: Programmierschnittstelle [Inhalt][Index]
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 die Befehlszeilenoption
-m von guix package
):
guix package -m manifest.scm
… oder Sie übergeben das Manifest an guix shell
(siehe
die Befehlszeilenoption -m von guix
shell
) 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 die Befehlszeilenoption -m
von guix pack
). 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
guix package --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
guix 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 Paketumwandlungsoptionen).
Anmerkung: Manifeste sind symbolisch: Sie beziehen sich auf die Pakete, die in den aktuell verwendeten Kanälen enthalten sind (siehe 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 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 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 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 Pakete definieren)
und die Module, in denen gdb
und git
definiert sind (siehe
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.
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.
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 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 dateiartige Objekte).
output
(Vorgabe: "out"
)Welche der Ausgaben von item
genommen werden soll, sofern item
mehrere Ausgaben umfasst (siehe 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
propagated-inputs
) 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 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 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.
Fasst die Manifeste in der Liste zu einem zusammen und liefert es zurück.
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 options->transformation
).
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")))
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")))
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
guix shell -D
) 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.
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 guix package
aufrufen).
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!
Nächste: Erstellungssysteme, Vorige: Paketvarianten definieren, Nach oben: Programmierschnittstelle [Inhalt][Index]