Siguiente: , Anterior: , Subir: Interfaz programática   [Índice general][Índice]


8.5 Fases de construcción

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 (véase Sistemas de construcción).

Como se ha tratado en las secciones anteriores, dichos sistemas de construcción proporcionan una lista de fases estándar. Las fáses estándar de gnu-build-system incluyen una fase unpack para desempaquetar el archivador de código fuente, una fase configure para ejecutar ./configure, una fase build para ejecutar make, y (entre otras) una fase install para ejecutar make install; véase Sistemas de construcción para obtener una visión más detallada de estas fases. De igual modo cmake-build-system hereda estas fases, pero su fase configure ejecuta cmake en vez de ./configure. Otros sistemas de construcción, como python-build-system, tienen una lista de fases de construcción completamente diferente. Todo este código se ejecuta en el lado de la construcción: se evalua cuando realmente construya el paquete, en un proceso de construcción dedicado que lanza el daemon de construcción (véase Invocación de guix-daemon).

Las fases de construcción se representan como listas asociativas o “alists” (véase Association Lists en 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ón19:

;; 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 (véase Pairs en 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 (véase Optional Arguments en 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 (véase 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 (véase configuration and makefile conventions en 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 (véase SRFI-1 Association Lists en GNU Guile Reference Manual); no obstante es más conveniente hacerlo con modify-phases (véase 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 ejemplo
  (package
    (name "ejemplo")
    ;; se omiten otros campos
    (build-system gnu-build-system)
    (arguments
     '(#:phases (modify-phases %standard-phases
                  (delete 'configure)
                  (add-before 'build 'proporciona-prefijo-en-makefile
                    (lambda* (#:key outputs #:allow-other-keys)
                      ;; Modifica el archivo de make para que la
                      ;; variable 'PREFIX' apunte a "out".
                      (let ((out (assoc-ref outputs "out")))
                        (substitute* "Makefile"
                          (("PREFIX =.*")
                           (string-append "PREFIX = "
                                          out "\n")))
                        #true))))))))

La nueva fase insertada se escribe como un procedimiento anónimo, generado con lambda*; usa el parámetro outputs visto anteriormente. Véase Utilidades de construcción para obtener más información sobre las funciones auxiliares usadas en esta fase y donde encontrará más ejemplos de uso de modify-phases.

Tenga en cuenta que las fases de construcción son código que se evalúa cuando se realiza la construcción real del paquete. Esto explica por qué la expresión modify-phases al completo se encuentra escapada (viene precedida de ', un apóstrofe): se ha preparado para una ejecución posterior. Véase Expresiones-G para obener una explicación sobre esta preparación del código para las distintas fases de ejecución y los distintos estratos de código implicados.


Notas al pie

(19)

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!


Siguiente: , Anterior: , Subir: Interfaz programática   [Índice general][Índice]