Empaquetado de Modulos XS

PAR soporta la carga de módulos XS (véase perlxs). XS es un formato para la descripción de interfases entre código C y código Perl. Veamos un ejemplo. La sesión se inicia como administrador arrancando cpan para a continuación descargar el módulo Math::Prime::XS el cual, como su nombre indica, tiene partes escritas en C:

root@orion:~# cpan

cpan shell -- CPAN exploration and modules installation (v1.7602)
ReadLine support enabled
El comando
look Math::Prime::XS
que emitimos a continuación indica que queremos abrir una shell en el directorio de la distribución de Math::Prime::XS. Si el módulo no está actualizado, cpan procederá a descargarse la última versión antes de abrir una shell:
cpan> look Math::Prime::XS
CPAN: Storable loaded ok
Going to read /root/.cpan/Metadata
  Database was generated on Fri, 08 Aug 2008 03:02:59 GMT
CPAN: LWP::UserAgent loaded ok
Fetching with LWP:
  ftp://perl.di.uminho.pt/pub/CPAN/authors/01mailrc.txt.gz
Going to read /root/.cpan/sources/authors/01mailrc.txt.gz
CPAN: Compress::Zlib loaded ok
Fetching with LWP:
  ftp://perl.di.uminho.pt/pub/CPAN/modules/02packages.details.txt.gz
Going to read /root/.cpan/sources/modules/02packages.details.txt.gz
  Database was generated on Thu, 21 Aug 2008 02:03:21 GMT
Fetching with LWP:
  ftp://perl.di.uminho.pt/pub/CPAN/modules/03modlist.data.gz
Going to read /root/.cpan/sources/modules/03modlist.data.gz
Going to write /root/.cpan/Metadata
Running look for module Math::Prime::XS

Trying to open a subshell in the build directory...
CPAN: Digest::MD5 loaded ok
Checksum for /root/.cpan/sources/authors/id/S/SC/SCHUBIGER/Math-Prime-XS-0.20.tar.gz ok
Scanning cache /root/.cpan/build for sizes
Math-Prime-XS-0.20/
Math-Prime-XS-0.20/Changes
Math-Prime-XS-0.20/lib/
Math-Prime-XS-0.20/lib/Math/
Math-Prime-XS-0.20/lib/Math/Prime/
Math-Prime-XS-0.20/lib/Math/Prime/XS.pm
Math-Prime-XS-0.20/ppport.h
Math-Prime-XS-0.20/MANIFEST
Math-Prime-XS-0.20/XS.xs
Math-Prime-XS-0.20/t/
Math-Prime-XS-0.20/t/pod-coverage.t
Math-Prime-XS-0.20/t/calc_primes.t
Math-Prime-XS-0.20/t/pod.t
Math-Prime-XS-0.20/t/00-load.t
Math-Prime-XS-0.20/INSTALL
Math-Prime-XS-0.20/Build.PL
Math-Prime-XS-0.20/META.yml
Math-Prime-XS-0.20/Makefile.PL
Math-Prime-XS-0.20/README
Removing previously used /root/.cpan/build/Math-Prime-XS-0.20
Working directory is /root/.cpan/build/Math-Prime-XS-0.20
Aunque la sesión ha sido arrancada como root podría haberla hecho como un usuario ordinario. El único objetivo era descargar la distribución de Math::Prime::XS y posicionarse en el correspondiente directorio.
root@orion:~/.cpan/build/Math-Prime-XS-0.20# ls -l
total 204
-r--r--r-- 1 csegura csegura    786 2008-05-14 15:30 Build.PL
-r--r--r-- 1 csegura csegura   1445 2008-05-14 15:30 Changes
-r--r--r-- 1 csegura csegura    290 2008-05-14 15:30 INSTALL
drwxr-xr-x 3 csegura csegura   4096 2008-05-14 15:30 lib
-r--r--r-- 1 csegura csegura    498 2008-05-14 15:30 Makefile.PL
-r--r--r-- 1 csegura csegura    172 2008-05-14 15:30 MANIFEST
-r--r--r-- 1 csegura csegura    560 2008-05-14 15:30 META.yml
-r--r--r-- 1 csegura csegura 154956 2008-05-14 15:30 ppport.h
-r--r--r-- 1 csegura csegura   5033 2008-05-14 15:30 README
drwxr-xr-x 2 csegura csegura   4096 2008-05-14 15:30 t
-r--r--r-- 1 csegura csegura   4843 2008-05-14 15:30 XS.xs
Construimos la distribución siguiendo el procedimiento habitual:
root@orion:~/.cpan/build/Math-Prime-XS-0.20# perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Math::Prime::XS
root@orion:~/.cpan/build/Math-Prime-XS-0.20# make
cp lib/Math/Prime/XS.pm blib/lib/Math/Prime/XS.pm
/usr/bin/perl /usr/local/share/perl/5.8.8/ExtUtils/xsubpp  \
            -typemap /usr/share/perl/5.8/ExtUtils/typemap  \
                         XS.xs > XS.xsc && mv XS.xsc XS.c
cc -c   -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe \
        -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 \
        -DVERSION=\"0.20\" -DXS_VERSION=\"0.20\" -fPIC "-I/usr/lib/perl/5.8/CORE"   XS.c
Running Mkbootstrap for Math::Prime::XS ()
chmod 644 XS.bs
rm -f blib/arch/auto/Math/Prime/XS/XS.so
cc  -shared -L/usr/local/lib XS.o  -o blib/arch/auto/Math/Prime/XS/XS.so    
chmod 755 blib/arch/auto/Math/Prime/XS/XS.so
cp XS.bs blib/arch/auto/Math/Prime/XS/XS.bs
chmod 644 blib/arch/auto/Math/Prime/XS/XS.bs
Manifying blib/man3/Math::Prime::XS.3pm
El aspecto mas notable de esta construcción es que se ha llamado al compilador de C. Las opciones pasadas al compilador han sido las mismas que se usaron en la instalación de Perl en la plataforma en uso. Ahora cambiamos al directorio de construcción blib:
root@orion:~/.cpan/build/Math-Prime-XS-0.20# cd blib
En el directorio arch está la librería .so (shared object). En el directorio lib esta el módulo Perl .pm que contiene la interfaz Perl a las funciones C:
root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib# tree
.
|-- arch
|   `-- auto
|       `-- Math
|           `-- Prime
|               `-- XS
|                   |-- XS.bs
|                   `-- XS.so
|-- bin
|-- lib
|   |-- Math
|   |   `-- Prime
|   |       `-- XS.pm
|   `-- auto
|       `-- Math
|           `-- Prime
|               `-- XS
|-- man1
|-- man3
|   `-- Math::Prime::XS.3pm
`-- script
Para construir el fichero .par usamos zip añadiendo los directorios arch y lib. los contenidos de
root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib# zip -r /tmp/primexs.par arch/ lib/
  adding: arch/ (stored 0%)
  adding: arch/.exists (stored 0%)
  adding: arch/auto/ (stored 0%)
  adding: arch/auto/Math/ (stored 0%)
  adding: arch/auto/Math/Prime/ (stored 0%)
  adding: arch/auto/Math/Prime/XS/ (stored 0%)
  adding: arch/auto/Math/Prime/XS/.exists (stored 0%)
  adding: arch/auto/Math/Prime/XS/XS.so (deflated 59%)
  adding: arch/auto/Math/Prime/XS/XS.bs (stored 0%)
  adding: lib/ (stored 0%)
  adding: lib/Math/ (stored 0%)
  adding: lib/Math/Prime/ (stored 0%)
  adding: lib/Math/Prime/.exists (stored 0%)
  adding: lib/Math/Prime/XS.pm (deflated 59%)
  adding: lib/auto/ (stored 0%)
  adding: lib/auto/Math/ (stored 0%)
  adding: lib/auto/Math/Prime/ (stored 0%)
  adding: lib/auto/Math/Prime/XS/ (stored 0%)
  adding: lib/auto/Math/Prime/XS/.exists (stored 0%)
root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib#
Es habitual que un fichero .par este fundamentalmente constituído por los contenidos del directorio blib/ construido a partir de una distribución CPAN.

Ahora transferimos el fichero /tmp/primexs.par a una máquina que carece de los módulos en dicho fichero, pero que es binario-compatible con la máquina en la que se realizó la construcción:

lhp@nereida:~/Lperl/src$ perldoc -l Math::Prime::XS
No documentation found for "Math::Prime::XS".
Después de la transferencia estamos en condiciones de usar el módulo Math::Prime::XS utilizando via PAR la distribucion primexs.par:
lhp@nereida:~/Lperl/src$ scp orion:/tmp/primexs.par .
primexs.par                             100%   11KB  11.4KB/s   00:00
lhp@nereida:~/Lperl/src$ vi prime3.pl
lhp@nereida:~/Lperl/src$ cat -n prime3.pl
     1  #!/usr/bin/perl -I../lib -w
     2  use PAR "primexs.par";
     3  use Math::Prime::XS qw{:all};
     4
     5  @all_primes   = primes(9);
     6  print "@all_primes\n";
     7
     8  @range_primes = primes(4, 9);
     9  print "@range_primes\n";
El programa se ejecuta sin errores produciendo la salida esperada:
lhp@nereida:~/Lperl/src$ prime3.pl
2 3 5 7
5 7
Por supuesto, el éxito de esta ejecución depende de la compatibilidad binaria de ambas plataformas (orion y nereida)

Casiano Rodríguez León
Licencia de Creative Commons
Principios de Programación Imperativa, Funcional y Orientada a Objetos Una Introducción en Perl/Una Introducción a Perl
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=43.
2012-06-19