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


6.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 `(("gawk" ,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 Scheme records in GNU Guile Reference Manual). 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 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 Paketmodule).

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

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

Sobald eine Paketdefinition eingesetzt wurde, können Sie das Paket mit Hilfe des Befehlszeilenwerkzeugs guix build dann auch tatsächlich erstellen (siehe Aufruf von guix build) und dabei jegliche Erstellungsfehler, auf die Sie stoßen, beseitigen (siehe Fehlschläge beim Erstellen untersuchen). Sie können den Befehl guix edit benutzen, um leicht zur Paketdefinition zurückzuspringen (siehe Aufruf von guix edit). Unter Paketrichtlinien finden Sie mehr Informationen darüber, wie Sie Paketdefinitionen testen, und unter Aufruf von guix lint finden Sie Informationen, wie Sie prüfen, ob eine Definition alle Stilkonventionen einhält. Zuletzt finden Sie unter 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 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 Der Store).

Scheme-Prozedur: package-derivation Store Paket [System]

Das <derivation>-Objekt zum Paket für das angegebene System liefern (siehe 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 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. "mips64el-linux-gnu" (siehe Specifying Target Triplets in Autoconf).

Pakete können auf beliebige Art verändert werden. Ein Beispiel für eine nützliche Veränderung ist das Umschreiben von Eingaben, womit der Abhängigkeitsbaum eines Pakets umgeschrieben wird, indem bestimmte Eingaben durch andere ersetzt werden:

Scheme-Prozedur: package-input-rewriting Ersetzungen [umgeschriebener-Name] Eine Prozedur liefern, die für ein ihr

übergebenes Paket dessen direkte und indirekte Abhängigkeit (aber nicht dessen implizite Eingaben) gemäß den Ersetzungen umschreibt. 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 --with-input).

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

Liefert eine Prozedur, die für ein gegebenes Paket die angegebenen Ersetzungen auf dessen gesamten Paketgraphen anwendet (außer auf implizite Eingaben). 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?]

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.


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