Perl - How to install perl module without root or super user

By default, perl modules installed through cpanX (cpanm, cpanp & cpan) utilities are install into system wide perl directory. Although this will make the module available through out all users on this box, it also means if there's a problem with particular module, it affects all users. Some other problem hit me as well :

Problem 1 - bloated with perl modules :
Some modules installed because it was needed to fulfill some dependencies (not necessary useful though), testing purpose or other reasons. This resulted the system wide perl directory is bloated with modules that aren't used as often as it should & should be removed. Removing modules in perl aren't easy as removing packages through a package manager. Because a typical package manager will check for dependencies to make sure that removing 1 package won't break another package.

Removing perl modules typically means manually remove the .pm files (or directory) in perl system wide directory. And this means there is a risk that removing a module might break some program or modules that depends on it.

Problem 2 - no root privileges :
In a hosting environment, normally one doesn't have root or sudo account, which installing CPAN modules needs it to add or change files in perl system wide directory. How nice if a normal users can have their own perl module directory.

Problem 3 - development environment :
Developers likes to setup individual perl projects to test & work on different environment. Naturally sets of modules that can be install into few different directories to serve as environment, switching between these directories are ideal for this situation. In this case, messing up an environment doesn't means messing up the entire perl modules.

Given the above situation, local::lib fits into the picture by solving the problems. Local::lib creates a directory resides in ~/ and cpan modules are install into here afterwards. Local::lib does that by changing the environment parameters @INC & system's $PATH variable.

The below instruction uses the "bootstrap" method of local::lib installation. This is useful on hosting environment where no access for root or sudo execution to install local::lib perl module.

Pre-requisite :
  1. wget
  2. cpanm (wondering what's this? refer here)
  3. bash

local::lib Installation starts here :
wget http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.005001.tar.gz
tar zxf local-lib-1.005001.tar.gz
cd ~/local-lib-1.005001
perl Makefile.PL --bootstrap
make test && make install
echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc

*** press enter for "YES" when prompted :
Would you like me to configure as much as possible automatically? [yes] "

After finishing the installation, close your command line session and start it again. This is needed to make the new settings to take effect.

How to make sure that local::lib works?
Pick a module from CPAN that hadn't exist in your box. In this example, the module "Acme::Time::Baby" is selected to test perl module local::lib. This example will show that after installing & configuring local::lib, any subsequent perl module installation through cpanX (cpanm, cpanp & cpan) will install into the directory "localmod", which define in the above installation steps.

cpanm Acme::Time::Baby
perl -MAcme::Time::Baby -E 'say babytime'

Now, there should have a line telling where's the clock's hand now (showing the time). Next login as another user or root to run the same command and you should get an error "Can't locate Acme/Time/Baby.pm in @INC" blah, blah, blah. This shows that installing perl module is not affecting the default perl installation on the box!

Additional stuff :
Local::lib can be install into multiple directory to simulate different environment. Similarly to the installation steps above, here's how to do it :

cd ~/local-lib-1.005001
perl Makefile.PL --bootstrap=~/secondmod
make test && make install

Next, instead of just echo the environment variables into ~/.bashrc, manually vim the ~/.bashrc. Because the previous environment variable need to be comment out and add the new line as below :
eval $(perl -I$HOME/secondmod/lib/perl5 -Mlocal::lib=$HOME/secondmod)

Again, after finishing the installation, close your command line session and start it again. This is needed to make the new settings to take effect.

To check out local::lib pointing to which directory, use the below 2 commands to confirm :
perl -e 'print "@INC"'
echo $PATH

Alternately :
  • Tell the Perl program to use local::lib :
    use local::lib;
    which it defaults to look for module in ~/perl5.
    For example,
    use local::lib;
    use warnings;
    use strict;
    use Acme::Time::Baby;
    print babytime . "\n";
  • Or, if you've installed local::lib into other other directory :
    use local::lib '~/my_other_locallib/';
    Another example,
    use local::lib '~/my_other_locallib';
    use warnings;
    use strict;
    use Acme::Time::Baby;
    print babytime . "\n";

Now, with local::lib & cpanminus, isn't the world a better place now? :p

Hasta la vista !!!

ref :
- local::lib, the CPAN module by Chris Nehren
- cpanm, the must have CPAN module installation tool, by Tatsuhiko Miyagawa

1 comment:

Winn said...

I'm having some trouble getting this to work. Namely, I do not have permission to create directories in ~/, only in specific folders within ~/ (such as ~/cgi-bin). I was able to specify that folder (perl Makefile.PL --bootstrap=~/cgi-bin/bin), but I'm getting a whole host of errors about the versions being out of date (BEGIN failed--compilation aborted.
ExtUtils::Install version 1.43 required--this is only version 1.32.
BEGIN failed--compilation aborted.

I followed your link to the old cpanm file, since I couldn't find a newer one that didn't require root access to build and install.

Any tips?