Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > perl > cpan > Module::Build

Module::Build

Herramienta estándar para construir e instalar módulos. El proceso generalmente consiste en:

$ perl ./Build.PL
$ ./Build
$ ./Build test
$ ./Build install

Es decir, lo primero que hay que hacer es invocar a Perl con el archivo Build.PL -base de todo el proyecto-, y luego usar el programa resultante para efectuar el resto de las tareas.

Algunas de estas tareas son:

  • build

    Ejecuta las acciones code y docs. Es la acción predeterminada si se llama sin ningún parámetro más.

  • code

    Crea el directorio blib/ y copia en él todos los archivos .pm y .pod que encuentra bajo el directorio lib/.

  • docs

    Crea documentación ([páginas de manual UNIX][1] y archivos HTML, por ejemplo) para todos los elementos instalables que encuentre bajo blib/, y contengan documentación POD.

  • distmeta

    Actualiza el archivo de descripción del proyecto META.yml

  • distsign

    Añade una firma criptográfica al paquete.

  • dist

    Crea el paquete para distribución final.

  • distdir

  • disttest

    Comprueba que la distribución final sea instalable.

  • clean

    Efectúa limpieza en el directorio de los archivos creados durante la la fase anterior (build), pero no borra el directorio _build/ ni el programa Build.

  • distclean

    Ejecuta las acciones realclean y la acción distcheck, las cuales sí borran el programa Build y el directorio _build.

  • test

    Invoca por orden todos los test regresivos del directorio t/ ó el programa test.pl en el directorio raíz del proyecto.

  • fakeinstall

    Indica lo que haría la acción install pero sin llevarlo a cabo realmente.

  • install

    Instala los módulos de la librería, la documentación y los scripts en los directorios de instalación. Estos pueden definirse mediante el parámetro installdirs.

Algo que conviene advertir es que Module::Build está diseñado para instalar módulos y librerías Perl, y no para efectuar operaciones complejas en la construcción de paquetes (tipo deb y rpm), por lo que querer forzarlo a hacer otras cosas es fuente de frustación contínua y muchísimos sudores. Sin embargo no faltan los trucos y recetas para ello, como se puede ver más abajo.

El archivo Build.PL

Este archivo es un programa Perl con instrucciones para crear un programa Build que ayude a mantener el paquete. Debe usar el módulo Module::Build correctamente y es el punto de partida de todo paquete Perl.

Un ejemplo de un archivo podría ser:

    1 #!/usr/bin/perl
    2 
    3 use Module::Build;
    4 
    5 Module::Build->new(
    6     module_name         =>  'MyIkiWiki::Tools',
    7     license             =>  q(gpl),
    8     dist_version        =>  '0.2',
    9     dist_author         =>  'Víctor Moral <victor@taquiones.net>',
   10     installdirs         =>  q(vendor),
   11     requires            =>  {
   12         'Perl6::Slurp'      =>  0,
   13         'List::MoreUtils'   =>  0,
   14         },
   15     script_files        =>  [
   16         'bin/ikitagit'
   17         ],
   18 )->create_build_script();
   19 

donde se puede ver que todo consiste en crear un objeto Module::Build e invocar un método sobre él (create_build_script()) a fin de crear el otro ejecutable.

Los parámetros del ejemplo y algunos otros también importantes son:

  • module_name

    Nombre del módulo principal. Es un atajo que abarca los parámetros dist_name y dist_version_from.

  • dist_name:

    Nombre de la distribución tal y como va a empaquetarse.

  • dist_version_from

    Especifica un archivo del cual obtener la versión. Se analiza buscando una línea donde aparezca la variable VERSION y se evalúa como expresión Perl; el resultado será el número de versión.

  • license

    Nombre de la licencia bajo la que se publica el código. Puede elegirse entre bastantes, aunque la más comunes son perl y gpl.

  • dist_version

    Número de versión que abarca todo el paquete.

  • dist_author

    Nombre y dirección de correo del autor de la distribución. Si son varios acepta una referencia a una lista. Si se omite se utiliza la sección POD denominada =head1 AUTHOR del módulo del cuál se obtiene la versión.

  • installdirs

    Determina los directorios donde se instalará el software. Acepta como valores site, vendor y core.

  • requires

    Indica qué modulos son necesarios tener instalados para usar éste. Generalmente es un hash cuyas claves son los nombres Perl de los módulos y cuyos valores son la versión mínima exigible. Un valor de cero indica que se acepta cualquier versión de dicho módulo.

  • script_files

    Lista de archivos que serán considerados como ejecutables, e instalados en los directorios adecuados.

Instalando en otros directorios

Supongamos que tenemos una aplicación Perl que contiene un enorme número de módulos (ó tal vez sólo unos pocos), y no queremos que se instalen en los directorios del sistema, junto con los (llamémosles) otros módulos Perl generalistas. ¿ Cómo hacemos ésto ?

Disponemos de varios parámetros con los que podemos jugar:

  • installdirs

    Nos permite elegir entre tres conjuntos de directorios donde instalar componentes:

    • core
    • site
    • vendor
  • install_path

    Sirve para cambiar las rutas de componentes concretos; estos que detallo son los correspondientes al conjunto vendor en Debian.

    • lib: /usr/share/perl5
    • arch: /usr/lib/perl5
    • script: /usr/bin
    • bin: /usr/bin
    • bindoc: /usr/share/man/man1
    • libdoc: /usr/share/man/man3
    • binhtml
    • libhtml
  • install_base

    Nos permite cambiar con un sólo parámetro el directorio raíz desde el que se forman los demás. Por ejemplo podemos situar todos comenzando por /home/victor.

  • destdir

    Idóneo para crear paquetes Debian o similares, porque añade un prefijo a todas las rutas, como el de un directorio temporal /tmp/debian.

Cualquiera de estos parámetros puede indicarse en la ejecución del programa Build ó en el archivo Build.PL:

$ perl ./Build --destdir=/tmp/debian
$ perl ./Build --install_path lib=/usr/share/mipaquete/
$ perl ./Build --install_base /home/victor
$ perl ./Build --installdirs=core

Preprocesando módulos

Introducción

Lo descrito aquí es una situación real: estamos construyendo una librería para un programa que posteriormente va a ser empaquetado. No queremos que sus módulos, que sólo usa él, vayan en los directorios genéricos del sistema; preferimos utilizar el del propio paquete.

Y es sencillo de conseguir: basta con poner lo siguiente en cada programa que incluya estos módulos:

    1 use lib qw(/usr/share/myprogram/);
    2 use MyModule;

Para depurar los programas empleamos la siguiente fórmula:

$ perl -Ilib -d myprogram.pl

es decir, anteponemos el directorio lib del directorio de trabajo en la lista de directorios dónde localizar módulos. Y funciona estupendamente hasta que ...

... hasta que creamos un primer paquete de este programa y lo instalamos; luego intentamos algún cambio (de interfaz por ejemplo) e intentamos depurarlo.

Los errores son muy extraños y nada de lo que hagamos en los módulos en desarrollo parece afectar a la depuración del programa. ¿ Qué está ocurriendo ? Pues que no estamos usando la versión de desarrollo en las pruebas, estamos usando la versión instalada en el sistema.

Veamos la secuencia de hechos para un programa (myprogram) que utiliza dos librerías llamadas A y B. Ambas incluyen el párrafo que llama al módulo lib.

  1. Invocamos el depurador de esta forma: $ perl -Ilib -d myprogram
  2. Perl inserta al comienzo del array @INC el directorio lib y éste queda de esta forma:
    1. lib
    2. /etc/perl
    3. /usr/local/share/perl/5.8.8
    4. /usr/lib/perl5
  3. Luego busca el primer módulo, el A, que encuentra en lib/A.pm, lo lee y lo compila, encontrándose una llamada al módulo lib que introduce cambios en el entorno. Ahora @INC tiene ya este aspecto:
    1. /usr/share/myprogram
    2. lib
    3. /etc/perl
    4. /usr/local/share/perl/5.8.8
    5. /usr/lib/perl5
  4. Después se le indica que tiene que cargar el módulo B y ... al buscarlo encuentra primero /usr/share/myprogram/B.pm que lib/B.pm. Y ya está liada :-)

Conclusión: De esto se deduce que no es necesario que los dos módulos modifiquen la ruta de búsqueda de otros módulos para apuntar a la suya propia. Eso debería hacerlo únicamente el programa que les llama.

Pero como un desarrollo grande en Perl puede requerir que varias librerías medio en desarrollo, medio en producción, interaccionen entre sí veamos qué opciones tenemos.

Módulos preprocesados

PENDIENTE DE COMPLETAR