Suivant: Utilitaires de construction, Précédent: Systèmes de construction, Monter: Interface de programmation [Table des matières][Index]
Presque tous les systèmes de construction de paquets mettent en œuvre une
notion de phase de construction : une séquence d’actions que le
système de construction exécute, lorsque vous construisez le paquet,
conduisant aux sous-produits installés dans le dépôt. Une exception notable
est le trivial-build-system
(voir Systèmes de construction) minimaliste.
Comme nous l’avons dit dans la section précédente, ces systèmes de
construction fournissent une liste de phases standards. Pour
gnu-build-system
, les phases de construction principales sont les
suivantes :
set-paths
Défini les variables d’environnement de chemins de recherche pour tous les
paquets d’entrée, dont PATH
(voir Chemins de recherche).
unpack
Décompresse l’archive des sources et se déplace dans l’arborescence des sources fraîchement extraites. Si la source est en fait un répertoire, le copie dans l’arborescence de construction et entre dans ce répertoire.
patch-source-shebangs
Corrige les shebangs (#!
) rencontrés dans les fichiers pour qu’ils se
réfèrent aux bons noms de fichiers. Par exemple, elle change
#!/bin/sh
en #!/gnu/store/…-bash-4.3/bin/sh
.
configure
Lance le script configure
avec un certain nombre d’options par
défaut, comme --prefix=/gnu/store/…, ainsi que les options
spécifiées par l’argument #:configure-flags
.
build
Lance make
avec la liste des drapeaux spécifiés avec
#:make-flags
. Si l’argument #:parallel-build?
est vrai (par
défaut), construit avec make -j
.
check
Lance make check
, ou une autre cible spécifiée par
#:test-target
, à moins que #:tests? #f
ne soit passé. Si
l’argument #:parallel-tests?
est vrai (par défaut), lance make
check -j
.
install
Lance make install
avec les drapeaux listés dans #:make-flags
.
patch-shebangs
Corrige les shebangs des fichiers exécutables installés.
strip
Nettoie les symboles de débogage dans les fichiers ELF (à moins que
#:strip-binaries?
ne soit faux), les copie dans la sortie
debug
lorsqu’elle est disponible (voir Installer les fichiers de débogage).
validate-runpath
Valide le RUNPATH
des binaires ELF, à moins que
#:validate-runpath?
ne soit faux (voir Systèmes de construction).
Cette étape de validation s’assure que toutes les bibliothèques partagées
par les binaires ELF, qui sont listées dans des entrées DT_NEEDED
de
leur segment PT_DYNAMIC
apparaissent dans l’entrée DT_RUNPATH
de ce même binaire. En d’autres termes, elle s’assure que lancer ou utiliser
ces binaires ne renvoie pas l’erreur « fichier introuvable » à
l’exécution. Voir -rpath dans The GNU Linker, pour plus
d’informations sur le RUNPATH
.
Les autres systèmes de construction ont des phases similaires, avec quelques
variations. Par exemple, cmake-build-system
a des phases de même nom,
mais sa phase configure
exécute cmake
au lieu de
./configure
. D’autres, tels que python-build-system
, ont une
liste de phases standard totalement différente. Tout ce code s’exécute
côté construction : il est évalué lorsque vous construisez réellement
le paquet, dans un processus de construction dédié engendré par le démon de
construction (voir Invoquer guix-daemon
).
Les phases de construction sont représentées sous forme de listes d’associations ou « alists » (voir Listes d’association dans Manuel de référence de GNU Guile) où chaque clé est un symbole pour le nom de la phase et la valeur associée est une procédure qui accepte un nombre arbitraire d’arguments. Par convention, ces procédures reçoivent des informations sur la construction sous la forme de paramètres nommés, qu’elles peuvent utiliser ou ignorer.
Par exemple, voici comment (guix build gnu-build-system)
définit
%standard-phases
, la variable contenant sa liste de phases de
construction21 :
;; Les phases de construction de « gnu-build-system ». (define* (unpack #:key source #:allow-other-keys) ;; Extrait l'archive des sources. (invoke "tar" "xvf" source)) (define* (configure #:key outputs #:allow-other-keys) ;; Exécute le script « configure ». Installe la sortie « out ». (let ((out (assoc-ref outputs "out"))) (invoke "./configure" (string-append "--prefix=" out)))) (define* (build #:allow-other-keys) ;; Compile. (invoke "make")) (define* (check #:key (test-target "check") (tests? #true) #:allow-other-keys) ;; Lance la suite de tests. (if tests? (invoke "make" test-target) (display "test suite not run\n"))) (define* (install #:allow-other-keys) ;; Installe les fichiers sous le préfixe spécifié à « configure ». (invoke "make" "install")) (define %standard-phases ;; La liste des phases standard (un certain nombre d'entre elles sont omises ;; par souci de concision). Chaque élément est une paire symbole/procédure. (list (cons 'unpack unpack) (cons 'configure configure) (cons 'build build) (cons 'check check) (cons 'install install)))
Cela montre comment %standard-phases
est défini comme une liste de
paires symbole/procédure (voir Pairs dans GNU Guile Reference
Manual). La première paire associe le symbole unpack
— un nom —
à la procédure unpack
; la deuxième paire définit la phase
configure
de manière similaire, et ainsi de suite. Lors de la
construction d’un paquet qui utilise gnu-build-system
avec sa liste
de phases par défaut, ces phases sont exécutées de manière séquentielle.
Vous pouvez voir le nom de chaque phase commencée et terminée dans le
journal de construction des paquets que vous construisez.
Examinons maintenant les procédures elles-mêmes. Chacune est définie par
define*
: #:key
énumère les paramètres nommés que la procédure
accepte, éventuellement avec une valeur par défaut, et
#:allow-other-keys
précise que les autres paramètres nommés sont
ignorés (voir Optional Arguments dans GNU Guile Reference Manual).
La procédure unpack
prend en compte le paramètre source
, que
le système de compilation utilise pour passer le nom de fichier de l’archive
source (ou le répertoire cloné d’un système de contrôle de version), et elle
ignore les autres paramètres. La phase configure
ne s’intéresse
qu’au paramètre outputs
, une liste d’association des noms des sorties
du paquet avec le nom de leur fichier du dépôt (voir Des paquets avec plusieurs résultats). Elle extrait le nom de fichier de out
, la sortie
par défaut, et le transmet à ./configure
comme préfixe
d’installation, ce qui signifie que make install
copiera tous les
fichiers vers ce répertoire (voir configuration and
makefile conventions dans GNU Coding Standards). build
et
install
ignorent tous leurs arguments. check
prend en compte
l’argument test-target
, qui spécifie le nom de la cible du Makefile
pour exécuter les tests ; il imprime un message et saute les tests lorsque
tests?
est faux.
La liste des phases utilisées pour un paquet particulier peut être modifiée
avec le paramètre #:phases
du système de construction. La
modification de l’ensemble des phases de construction se résume à la
création d’une nouvelle liste de phases basée sur la liste
%standard-phases
décrite ci-dessus. On peut faire cela à l’aide des
procédures standards qui manipulent des listes d’associations telles que
alist-delete
(voir SRFI-1 Association Lists dans GNU Guile
Reference Manual) ; cependant, il est plus pratique de le faire avec
modify-phases
(voir modify-phases
).
Voici un exemple de définition de paquet qui supprime la phase
configure
de %standard-phases
et insère une nouvelle phase
avant la phase build
, appelée set-prefix-in-makefile
:
(define-public example
(package
(name "example")
;; other fields omitted
(build-system gnu-build-system)
(arguments
(list
#:phases
#~(modify-phases %standard-phases
(delete 'configure)
(add-before 'build 'set-prefix-in-makefile
(lambda* (#:key inputs #:allow-other-keys)
;; Modify the makefile so that its
;; 'PREFIX' variable points to #$output and
;; 'XMLLINT' points to the correct path.
(substitute* "Makefile"
(("PREFIX =.*")
(string-append "PREFIX = " #$output "\n"))
(("XMLLINT =.*")
(string-append "XMLLINT = "
(search-input-file inputs "/bin/xmllint")
"\n"))))))))))
The new phase that is inserted is written as an anonymous procedure,
introduced with lambda*
; it looks for the xmllint executable
under a /bin directory among the package’s inputs (voir Référence de package
). It also honors the outputs
parameter we have seen
before. Voir Utilitaires de construction, for more about the helpers used by this
phase, and for more examples of modify-phases
.
Astuce : You can inspect the code associated with a package’s
#:phases
argument interactively, at the REPL (voir Utiliser Guix de manière interactive).
Keep in mind that build phases are code evaluated at the time the package is
actually built. This explains why the whole modify-phases
expression
above is quoted (it comes after the #~
or hash-tilde): it is
staged for later execution. Voir G-Expressions, for an explanation
of code staging and the code strata involved.
Nous présentons une vue simplifiée de ces phases de
construction, mais jetez un œil à (guix build gnu-build-system)
pour
voir tous les détails !
Suivant: Utilitaires de construction, Précédent: Systèmes de construction, Monter: Interface de programmation [Table des matières][Index]