CPAN: Si no tenemos los privilegios de administrador

En las versiones mas recientes de Perl que hacen uso de las versiones mas modernas de CPAN.pm esto no es un problema. Simplemente escriba perl -MCPAN -e shell y responda al interrogatorio para determinar la configuración que necesita.

En el caso de que la versión con la que trabajemos sea antigua y no tengamos los privilegios de administrador del sistema tendremos que trabajar un poco para usar el módulo CPAN:

 1	home/casiano[23]> uname -a
 2	Linux millo.etsii.ull.es 2.4.22-1.2188.nptl #1 \
    Wed Apr 21 20:36:05 EDT 2004 i686 i686 i386 GNU/Linux
 3	/home/casiano[5]> perl -MCPAN -e shell
 4	Terminal does not support AddHistory.
 5	
 6	Your configuration suggests "/root/.cpan" as your
 7	CPAN.pm working directory. I could not create this directory due
 8	to this error: mkdir /root/.cpan: Permiso denegado at \
              /usr/local/lib/perl5/5.8.5/CPAN.pm line 553
 9	
10	
11	Please make sure the directory exists and is writable.
12
Lo primero que obtenemos es un fracaso: Obviamente no podemos modificar el fichero /root/.cpan. Por tanto deberemos indicar que este no es el fichero de configuración:
13	/home/casiano[6]> mkdir .cpan
14	/home/casiano[7]> mkdir .cpan/CPAN
15	/home/casiano[9]> perl -MCPAN::Config -e 'print $INC{"CPAN/Config.pm"},"\n"'
16	/usr/local/lib/perl5/5.8.5/CPAN/Config.pm
En la línea 15 ejecutamos un guión interactivo (-e) que carga el módulo CPAN::Config (opción -M) y que hace uso del hash %INC.
17	/home/casiano[10]> cp /usr/local/lib/perl5/5.8.5/CPAN/Config.pm .cpan/CPAN/MyConfig.pm
18	/home/casiano[11]> cd .cpan/CPAN/
19	/home/casiano/.cpan/CPAN[12]> perl -ne 'print if /(build_dir|keep_source_where)/' MyConfig.pm
20	  'build_dir' => q[/root/.cpan/build],
21	  'keep_source_where' => q[/root/.cpan/sources],
La opción -n en la línea 19 envuelve en un bucle de lectura el guión interactivo. Muestra las líneas del fichero que casan con la expresión regular. Ahora editamos el fichero y cambiamos las líneas que hacen alusión al root:
/home/casiano/.cpan/CPAN[13]> vi MyConfig.pm
un poco después ...
23	/home/casiano/.cpan/CPAN[16]> perl -ne 'print if /(casiano)/' MyConfig.pm
24	  'build_dir' => q[/scratch/casiano/build],
25	  'cpan_home' => q[/scratch/casiano/.cpan],
26	  'histfile' => q[/scratch/casiano/.cpan/histfile],
27	  'keep_source_where' => q[/scratch/casiano/.cpan/sources],
El comando nos muestra que líneas fueron cambiadas en la edición. Ahora estamos en condiciones de ejecutar CPAN, pero tenemos que hacer aún algunos cambios en la configuración:
28	/home/casiano/.cpan/CPAN[19]> perl -MCPAN -e shell
29	Terminal does not support AddHistory.
30	
31	cpan shell -- CPAN exploration and modules installation (v1.7601)
32	ReadLine support available (try 'install Bundle::CPAN')
33	cpan> o conf makepl_arg PREFIX=/scratch/casiano/perl
34	    makepl_arg         PREFIX=/scratch/casiano/perl
35	cpan> o conf commit
36	commit: wrote /home/casiano/.cpan/CPAN/MyConfig.pm
En las líneas 33 y 35 le hemos indicado a CPAN donde debe dejar los módulos descargados. Deberemos asegurarnos que los programas que usen esos módulos tengan dicho directorio en su @INC. Ahora podemos instalar un módulo:
37	cpan> install Parse::Yapp
38	CPAN: Storable loaded ok
39	Going to read /scratch/casiano/.cpan/Metadata
40	....
41	Appending installation info to /scratch/casiano/perl/lib/perl5/5.8.5/i686-linux/perllocal.pod
42	  /usr/bin/make install  -- OK
Veamos la jerarquía creada por la instalacion de Parse::Yapp
$ tree /scratch/casiano/perl/
/scratch/casiano/perl/
|-- bin
|   `-- yapp
|-- lib
|   `-- perl5
|       |-- 5.8.5
|       |   `-- i686-linux
|       |       `-- perllocal.pod
|       `-- site_perl
|           `-- 5.8.5
|               |-- Parse
|               |   |-- Yapp
|               |   |   |-- Driver.pm
|               |   |   |-- Grammar.pm
|               |   |   |-- Lalr.pm
|               |   |   |-- Options.pm
|               |   |   |-- Output.pm
|               |   |   `-- Parse.pm
|               |   `-- Yapp.pm
|               `-- i686-linux
|                   `-- auto
|                       `-- Parse
|                           `-- Yapp
`-- share
    `-- man
        |-- man1
        |   `-- yapp.1
        `-- man3
            `-- Parse::Yapp.3

17 directories, 11 files
Aún mas secillo: use el módulo CPAN::FirstTime:
$ perl -MCPAN::FirstTime -e 'CPAN::FirstTime::init()'
CPAN is the world-wide archive of perl resources. It consists of about
100 sites that all replicate the same contents all around the globe.
Many countries have at least one CPAN site already. The resources
found on CPAN are easily accessible with the CPAN.pm module. If you
want to use CPAN.pm, you have to configure it properly.

If you do not want to enter a dialog now, you can answer 'no' to this
question and I'll try to autoconfigure. (Note: you can revisit this
dialog anytime later by typing 'o conf init' at the cpan prompt.)

Are you ready for manual configuration? [yes] yes


The following questions are intended to help you with the
configuration. The CPAN module needs a directory of its own to cache
important index files and maybe keep a temporary mirror of CPAN files.
This may be a site-wide directory or a personal directory.



I see you already have a  directory
    /root/.cpan
Shall we use it as the general CPAN build and cache directory?

CPAN build and cache directory? [/root/.cpan]
.... # etc.

Casiano Rodríguez León
2010-03-03
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)

Uso de Módulos via Web

Es posible utilizar ficheros PAR cuya localización está en una máquina remota:

   use PAR "http://orion.pcg.ull.es/~casiano/primexs.par";
En este escenario PAR cargará los módulos solicitados desde el repositorio PAR situado en http://foo/bar/. Por supuesto debemos el fichero .par deberá estar en la máquina remota (en el ejemplo que sigue orion). Copiamos el .par construido anteriormente en el directorio que contiene nuestros HTML publicos:
casiano@orion:~/public_html$ cp /tmp/primexs.par .
casiano@orion:~/public_html$ pwd
/home/casiano/public_html
casiano@orion:~/public_html$ ls -ltr | tail -1
-rw-r--r--  1 casiano casiano         11685 2008-08-23 12:57 primexs.par
Ahora podemos ejecutar en la máquina cliente nereida un programa que hace uso del repositorio situado en orion:
lhp@nereida:~/Lperl/src$ cat -n prime4.pl
   1  #!/usr/bin/perl -I../lib -w
   2  use PAR "http://orion.pcg.ull.es/~casiano/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 normalmente:
lhp@nereida:~/Lperl/src$ prime4.pl
2 3 5 7
5 7



Subsecciones
Casiano Rodríguez León
2011-02-09