Next: Utilidades de construcción, Previous: Sistemas de construcción, Up: Interfaz programática [Contents][Index]
Prácticamente todos los sistemas de construcción de paquetes implementan una
noción de fases de construcción: una secuencia de acciones ejecutadas
por el sistema de construcción, cuando usted construya el paquete, que
conducen a la instalación de su producción en el almacén. Una excepción
notable es el sistema de construcción trivial trivial-build-system
(see Sistemas de construcción).
As discussed in the previous section, those build systems provide a standard
list of phases. For gnu-build-system
, the main build phases are the
following:
set-paths
Define search path environment variables for all the input packages,
including PATH
(see Search Paths).
unpack
Extrae el archivador tar de la fuente, y cambia el directorio actual al directorio recién extraído. Si la fuente es realmente un directorio, lo copia al árbol de construcción y entra en ese directorio.
patch-source-shebangs
Sustituye secuencias “#!” encontradas al inicio de los archivos de fuentes
para que hagan referencia a los nombres correctos de archivos del
almacén. Por ejemplo, esto cambia #!/bin/sh
por
#!/gnu/store/…-bash-4.3/bin/sh
.
configure
Ejecuta el guión configure con algunas opciones predeterminadas, como
--prefix=/gnu/store/…, así como las opciones especificadas
por el parámetro #:configure-flags
.
build
Ejecuta make
con la lista de opciones especificadas en
#:make-flags
. Si el parámetro #:parallel-build?
es verdadero
(por defecto), construye con make -j
.
check
Ejecuta make check
, u otro objetivo especificado con
#:test-target
, a menos que se pasase #:tests? #f
. Si el
parámetro #:parallel-tests?
es verdadero (por defecto), ejecuta
make check -j
.
install
Ejecuta make install
con las opciones enumeradas en
#:make-flags
.
patch-shebangs
Sustituye las secuencias “#!” en los archivos ejecutables instalados.
strip
Extrae los símbolos de depuración de archivos ELF (a menos que el valor de
#:strip-binaries?
sea falso), y los copia a la salida debug
cuando esté disponible (see Instalación de archivos de depuración).
validate-runpath
Validate the RUNPATH
of ELF binaries, unless
#:validate-runpath?
is false (see Sistemas de construcción).
This validation step consists in making sure that all the shared libraries
needed by an ELF binary, which are listed as DT_NEEDED
entries in its
PT_DYNAMIC
segment, appear in the DT_RUNPATH
entry of that
binary. In other words, it ensures that running or using those binaries
will not result in a “file not found” error at run time. See -rpath in The GNU Linker, for more information on
RUNPATH
.
Other build systems have similar phases, with some variations. For example,
cmake-build-system
has same-named phases but its configure
phases runs cmake
instead of ./configure
. Others, such as
python-build-system
, have a wholly different list of standard
phases. All this code runs on the build side: it is evaluated when
you actually build the package, in a dedicated build process spawned by the
build daemon (see Invocación de guix-daemon
).
Las fases de construcción se representan como listas asociativas o “alists” (see Association Lists in GNU Guile Reference Manual) donde cada clave es un símbolo que nombra a la fase y el valor asociado es un procedimiento que acepta un número arbitrario de parámetros. Por convención, estos procedimientos reciben información sobre la construcción en forma de parámetros que usan palabras clave, de los cuales pueden hacer uso o ignorarlos.
Por ejemplo, esta es la forma en la que (guix build gnu-build-system)
define %standard-phases
, la variable que contiene su lista asociativa
de fases de construcción23:
;; Las fases de construcción de 'gnu-build-system'. (define* (unpack #:key source #:allow-other-keys) ;; Extracción del archivador tar de las fuentes. (invoke "tar" "xvf" source)) (define* (configure #:key outputs #:allow-other-keys) ;; Ejecución del guión 'configure'. Instalación de la salida ;; en "out". (let ((out (assoc-ref outputs "out"))) (invoke "./configure" (string-append "--prefix=" out)))) (define* (build #:allow-other-keys) ;; Compilación. (invoke "make")) (define* (check #:key (test-target "check") (tests? #true) #:allow-other-keys) ;; Ejecución de la batería de pruebas. (if tests? (invoke "make" test-target) (display "test suite not run\n"))) (define* (install #:allow-other-keys) ;; Instalación de los archivos en el prefijo especificado ;; al guión 'configure'. (invoke "make" "install")) (define %standard-phases ;; La lista de las fases estándar (algunas se omiten por ;; brevedad). Cada elemento es un par símbolo/procedimiento. (list (cons 'unpack unpack) (cons 'configure configure) (cons 'build build) (cons 'check check) (cons 'install install)))
Aquí se muestra como %standard-phases
se define como una lista de
pares símbolo/procedimiento (see Pairs in GNU Guile Reference
Manual). El primer par asocia el procedimiento unpack
con el símbolo
unpack
—un nombre; el segundo par define de manera similar la fase
configure
, etcétera. Cuando se construye un paquete que usa
gnu-build-system
, con su lista predeterminada de fases, estas fases
se ejecutan de manera secuencial. Puede ver el nombre de cada fase a su
inicio y tras su finalización en el registro de construcción de los paquetes
que construya.
Echemos un vistazo a los propios procedimientos. Cada uno se define con
define*
: #:key
enumera parámetros con palabras clave que el
procedimiento acepta, con la posibilidad de proporcionar un valor
predeterminado, y #:allow-other-keys
especifica que se ignora
cualquier otra palabra clave en los parámetros (see Optional Arguments in GNU Guile Reference Manual).
El procedimiento unpack
utiliza el valor proporcionado al parámetro
source
, usado por el sistema de construcción usa para proporcionar el
nombre de archivo del archivador de fuentes (o la copia de trabajo del
sistema de control de versiones), e ignora otros parámetros. La fase
configure
únicamente tiene en cuenta el parámetro outputs
, una
lista asociativa de nombres de salida de paquetes con su nombre de archivo
en el almacén (see Paquetes con múltiples salidas). Para ello se extrae
el nombre de archivo de out
, la salida predeterminada, y se lo
proporciona a la orden ./configure
como el prefijo de la
instalación (./configure --prefix=out
), lo que significa que
make install
acabará copiando todos los archivos en dicho
directorio (see configuration and makefile conventions in GNU Coding Standards). Tanto build
como install
ignoran todos los parámetros. check
utiliza el parámetro
test-target
, que especifica el nombre del objetivo del archivo
Makefile que debe ejecutarse para ejecutar las pruebas; se imprime un
mensaje y se omiten las pruebas cuando el parámetro tests?
tiene
falso como valor.
Se puede cambiar con el parámetro #:phases
la lista de fases usada
por el sistema de construcción para un paquete en particular. El cambio del
conjunto de fases de construcción se realiza mediante la construcción de una
nueva lista asociativa basada en la lista asociativa %standard-phases
descrita previamente. Esto se puede llevar a cabo con procedimientos
estándar para la manipulación de listas asociativas como alist-delete
(see SRFI-1 Association Lists in GNU Guile Reference Manual); no
obstante es más conveniente hacerlo con modify-phases
(see modify-phases
).
Aquí se encuentra un ejemplo de una definición de paquete que borra la fase
configure
de %standard-phases
e inserta una nueva fase antes
de la fase build
, llamada proporciona-prefijo-en-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 (see Referencia de package
). It also honors the outputs
parameter we have seen
before. See Utilidades de construcción, for more about the helpers used by this
phase, and for more examples of modify-phases
.
Tip: You can inspect the code associated with a package’s
#:phases
argument interactively, at the REPL (see Using Guix Interactively).
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. See Expresiones-G, for an explanation
of code staging and the code strata involved.
Presentamos una visión simplificada de las
fases de dichas construcción, ¡eche un vistazo al módulo (guix build
gnu-build-system)
para ver todos los detalles!
Next: Utilidades de construcción, Previous: Sistemas de construcción, Up: Interfaz programática [Contents][Index]