Nächste: , Vorige: , Nach oben: Programmierschnittstelle   [Inhalt][Index]


8.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 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.

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

Prozedur: concatenate-manifests Liste

Fasst die Manifeste in der Liste zu einem zusammen und liefert es zurück.

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 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")))
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")))
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 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.

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