Perl 5 custom module directory with CPAN setup

Created: 2009-02-03

Background

This page describes what I did to configure an additional module directory on a Solaris 10 zone.

Non-root Solaris 10 zones will not let you run the cpan shell. This has to do with the module directories being non-writable because they are shared by multiple zones.

Files to download

Notes: This file needs to be edited. It is intended to be used to setup the CPAN module directory in a user's home directory. Also it needs to contain some paths to programs on Solaris.

Setup

 # mkdir -p /data/perl/perl5
 # mkdir -p ~/.cpan/CPAN/
 # cd ~/.cpan/CPAN/
The MyConfig.pm is also available from the above link.
 # wget 'http://sial.org/howto/perl/life-with-cpan/MyConfig.pm'
 # cp MyConfig.pm MyConfig.pm.orig
 # perl -p -i -e 's#HOMEDIRFIX##g' MyConfig.pm
 # perl -p -i -e 's#~/#/data/perl/perl5/#g' MyConfig.pm
 # perl -p -i -e 's#/usr/bin/wget#/usr/sfw/bin/wget#' MyConfig.pm
 # perl -p -i -e 's#/usr/bin/tar#/usr/sfw/bin/gtar#g' MyConfig.pm
 # perl -p -i -e 's#/usr/bin/make#/usr/ccs/bin/make#g' MyConfig.pm

 # perl -c MyConfig.pm
 
 # echo >> /etc/profile
 # echo 'export PERL5LIB=${PERL5LIB:+$PERL5LIB:}/data/perl/perl5/lib/perl5:/data/perl/perl5/lib/site_perl' >> /etc/profile
 # echo 'export MANPATH=${MANPATH:+$MANPATH:}/data/perl/perl5/share/man' >> /etc/profile
 # echo 'alias cpan="perl -MCPAN -e shell"' >> /etc/profile
 # tail /etc/profile
If it hasn't been done yet edit /etc/profile to have the "cc" binary in your search path. For example add the line:
 export PATH="$PATH:/opt/SUNWspro/prod/bin"
You may also need to add the path the directory that contains "perldoc". Be sure to check /.profile because on Solaris it clobers the PATH. For example:
 export PATH="$PATH:/usr/perl5/5.8.4/bin"

 # export PERL5LIB=${PERL5LIB:+$PERL5LIB:}/data/perl/perl5/lib/perl5:/data/perl/perl5/lib/site_perl
 # export MANPATH=${MANPATH:+$MANPATH:}/data/perl/perl5/share/man

 # perl -MCPAN -e shell
 cpan> install Bundle::CPAN

 # find /data/perl/perl5/lib/perl5/ -name '*.pm' | head

Changes to your code

Option 1 : use the PERL5LIB environtment variable

By using the '''PERL5LIB''' environment variable the '''@INC''' path is automatically updated. This variable is exported by /etc/profile assuming you are using the BASH shell. For example:
 $ echo $PERL5LIB 
 /data/perl/perl5/lib/perl5

 $ perl -le '$,="\n"; print @INC' | grep /data
 /data/perl/perl5/lib/perl5/i86pc-solaris-64int
 /data/perl/perl5/lib/perl5
 
 $ PERL5LIB="" perl -le '$,="\n"; print @INC' | grep /data
Unfortunately the taint-mode ignores environment variables so there is a second way to use the new module directory.

Option 2 : edit the code

Edit the code to use the new library directory. See this diff for example.
 [chad@keys /data/www/superfrink.net/htdocs/journal]$ diff -u old/index.pl.2008-12-28.pl  index.pl
 --- old/index.pl.2008-12-28.pl  Sun Dec 28 14:49:57 2008
 +++ index.pl    Sun Dec 28 14:51:46 2008
 @@ -6,6 +6,8 @@
  # chad c d clark < chad.clark _AT_ gmail _DOT_ com >
  # created: 2006-03-08
  
 +use lib '/data/perl/perl5/lib/perl5/';
 +
  use strict;
  use Data::Dumper;
  use CGI::Pretty;

Compiling perl modules from source

Sometimes "cpan" isn't able to install a module correctly. I'm not sure why. To manually install a module in the custom directory do:
 # perl Makefile.PL PREFIX=/data/perl/perl5/ SITELIBEXP=/data/perl/perl5/lib/perl5 LIB=/data/perl/perl5/lib/perl5 INSTALLMAN1DIR=/data/perl/perl5/share/man/man1 INSTALLMAN3DIR=/data/perl/perl5/share/man/man3 INSTALLSITEMAN1DIR=/data/perl/perl5/share/man/man1 INSTALLSITEMAN3DIR=/data/perl/perl5/share/man/man3
 # make
 # make test
 # make install