Suivant: , Précédent: , Monter: Interface de programmation   [Table des matières][Index]


6.2 Définition des paquets

L’interface de haut-niveau pour les définitions de paquets est implémentée dans les modules (guix packages) et (guix build-system). Par exemple, la définition du paquet, ou la recette, du paquet GNU Hello ressemble à cela :

(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+)))

Sans être un expert Scheme, le lecteur peut comprendre la signification des différents champs présents. Cette expression lie la variable hello à un objet <package>, qui est essentiellement un enregistrement (voir Scheme records dans GNU Guile Reference Manual). On peut inspecter cet objet de paquet avec les procédures qui se trouvent dans le module (guix packages) ; par exemple, (package-name hello) renvoie — oh surprise ! — "hello".

Avec un peu de chance, vous pourrez importer tout ou partie de la définition du paquet qui vous intéresse depuis un autre répertoire avec la commande guix import (voir Invoquer guix import).

Dans l’exemple précédent, hello est défini dans un module à part, (gnu packages hello). Techniquement, cela n’est pas strictement nécessaire, mais c’est pratique : tous les paquets définis dans des modules sous (gnu packages …) sont automatiquement connus des outils en ligne de commande (voir Modules de paquets).

Il y a quelques points à remarquer dans la définition de paquet précédente :

Voir Référence des paquets, pour une description complète des champs possibles.

Lorsqu’une définition de paquet est en place, le paquet peut enfin être construit avec l’outil en ligne de commande guix build (voir Invoquer guix build), pour résoudre les échecs de construction que vous pourriez rencontrer (voir Débogage des échecs de construction). Vous pouvez aisément revenir à la définition du paquet avec la commande guix edit (voir Invoquer guix edit). Voir Consignes d'empaquetage, pour plus d’informations sur la manière de tester des définitions de paquets et Invoquer guix lint, pour des informations sur la manière de vérifier que la définition respecte les conventions de style. Enfin, voir Canaux pour des informations sur la manière d’étendre la distribution en ajoutant vos propres définitions de paquets dans un « canal ».

Finalement, la mise à jour de la définition du paquet à une nouvelle version amont peut en partie s’automatiser avec la commande guix refresh (voir Invoquer guix refresh).

Sous le capot, une dérivation qui correspond à un objet <package> est d’abord calculé par la procédure package-derivation. Cette dérivation est stockée dans un fichier .drv dans /gnu/store. Les actions de construction qu’il prescrit peuvent ensuite être réalisées par la procédure build-derivation (voir Le dépôt).

Procédure Scheme : package-derivation store package [system]

Renvoie l’objet <derivation> du paquet pour le système (voir Dérivations).

paquet doit être un objet <package> valide et système une chaîne indiquant le type de système cible — p.ex. "x86_64-linux" pour un système GNU x86_64 basé sur Linux. dépôt doit être une connexion au démon, qui opère sur les dépôt (voir Le dépôt).

De manière identique, il est possible de calculer une dérivation qui effectue une compilation croisée d’un paquet pour un autre système :

Procédure Scheme : package-cross-derivation store paquet cible [système] renvoie l'objet <derivation>

du paquet construit depuis système pour cible.

cible doit être un triplet GNU valide indiquant le matériel cible et le système d’exploitation, comme "mips64el-linux-gnu" (voir Specifying Target Triplets dans Autoconf).

On peut manipuler les paquets de manière arbitraire. Une transformation utile est par exemple la réécriture d’entrées où l’arbre des dépendances d’un paquet est réécrit en replaçant des entrées spécifiques par d’autres :

Procédure Scheme : package-input-rewriting replacements [nom-réécrit] Renvoie une procédure qui, lorsqu'on lui donne un

paquet, remplace des dépendances directes et indirectes (mais pas ses entrées implicites) en fonction de remplacements. remplacements est une liste de paires de paquets ; le premier élément de chaque pair est le paquet à remplacer, le second son remplaçant.

De manière facultative, nom-réécrit est une procédure à un argument qui prend le nom d’un paquet et renvoie son nouveau nom après l’avoir réécrit.

Regardez cet exemple :

(define libressl-instead-of-openssl
  ;; Cette procédure remplace OPENSSL par LIBRESSL,
  ;; récursivement.
  (package-input-rewriting `((,openssl . ,libressl))))

(define git-with-libressl
  (libressl-instead-of-openssl git))

Ici nous définissons d’abord une procédure de réécriture qui remplace openssl par libressl. Ensuite nous l’utilisons pour définir une variante du paquet git qui utilise libressl plutôt que openssl. cela est exactement ce que l’option en ligne de commande --with-input fait (voir --with-input).

La variante suivante de package-input-rewriting peut repérer les paquets à remplacer par nom à la place de leur identité.

Procédure Scheme : package-input-rewriting/spec remplacements

Renvoie une procédure qui, étant donné un paquet, applique les remplacements à tous le graphe du paquet (en dehors des entrées implicites). remplacements est une liste de paires de spécifications et de procédures ; chaque spécification est une spécification de paquet comme "gcc" ou "guile@2", et chaque procédure prend un paquet correspondant et renvoie un remplaçant pour ce paquet.

L’exemple ci-dessus pourrait être réécrit de cette manière :

(define libressl-instead-of-openssl
  ;; Remplace tous les paquets nommés « openssl » par LibreSSL.
  (package-input-rewriting/spec `(("openssl" . ,(const libressl)))))

Le différence clef est que, cette fois-ci, les paquets correspondent à la spécification et non à l’identité. En d’autres termes, tout paquet dans le graphe qui est appelé openssl sera remplacé.

Une procédure plus générique pour réécrire un graphe de dépendance d’un paquet est package-mapping : elle supporte n’importe quel changement dans les nœuds du graphe.

Procédure Scheme : package-mapping proc [cut?]

Renvoie une procédure qui, avec un paquet, applique proc sur tous les paquets dont il dépend et renvoie le paquet qui en résulte. La procédure arrête la récursion là où cut? renvoie vrai pour un paquet donné.


Suivant: , Précédent: , Monter: Interface de programmation   [Table des matières][Index]