Perl Advent Calendar 2009-12-03

Support your local libraries!

by Stephen R. Scaffidi

local::lib is a great tool for saving time and effort!

Best practices these days suggest that you should do your best to avoid installing CPAN modules as root, especially to the system's perl! Another best practice is to keep the modules for unrelated applications separate, lest an upgrade for one app break another. Furthermore, what if you want to experiment with the latest version of something but do not want to risk the stability of your system and apps? local::lib can help with all of this!

The two most common solutions for these scenarios?

Option 1: Build and install your own perl under your home directory and use nothing but that. Do it again for each application and experiment.

Option 2: Use the system perl, but install all the modules you need in a directory under your home dir. Make more directories as needed.

local::lib is quite good at helping you manage option #2.

Installing local::lib

Before you proceed, make sure your ~/.cpan dir is fully owned and writable by your user and that your cpan config (should be ~/.cpan/CPAN/ is set up properly for building as a non-root user!1 [assuming one is a CPAN shell user - ed.]

You want it available for everyone? Install in the usual way. Otherwise... if you either don't have root access or don't want to install local::lib globally, there's another solution: Bootstrapping.

There are detailed instructions for bootstrapping in local::lib's documentation but here's a condensed version:

  user@host:~$ cpan
  cpan[1]> look local::lib
  user@host:~/.cpan/build/local-lib-1...$ perl Makefile.PL --bootstrap=~/perl5
  user@host:~/.cpan/build/local-lib-1...$ make && make test && make install
  user@host:~/.cpan/build/local-lib-1...$ exit
  cpan[2]> exit

[or the equivalent with manual tarball build, just add that --bootstrap=~/perl5 to the Makefile.PL command. -ed.]

Now, you'll want to update your shell config to make your new local lib available automagically. For example, if you use bash, do this:

  echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
  . ~/.bashrc

You can do something similar with other shells, like csh2

Putting local::lib to use:

So, now that you have cpan configured and local::lib installed, give it a whirl! Try installing something you don't already have, logged in as an unprivileged user...

cpan TL1ng # I doubt any of you have (or need) this.

When it's done, you will be able to find those modules under your ~/perl5 directory. Go ahead, install more. So far, everything I have tried installing using local::lib has worked! (if it fails, it will almost certainly fail being installed as root, too)

While you have added a command to your shell rc file, you may want this functionality in your code, to make it clear what you want in your @INC.

To do so, just add this in your code:

use local::lib q(~/perl5);

It's that easy!

Oh and one more thing... the directory ~/perl5 is the default if you don't specify anything. Same goes for the --bootstrap option for the Makefile.PL! You can change it to anything you want, of course!

Wrapping up...

I find myself using local::lib for all sorts of things these days. For example, I keep my ~/perl5 dir under version control. If I mess something up, I can roll back at any time! Also, I now keep nearly all modules installed via CPAN there, and only use debian packaged modules for the system perl. My employer's website is now running out of a local::lib because it turns out the latest version of a certain CPAN module breaks things pretty bad!

local::lib may not be your cup of tea, or you may not need it now... but when you finally do it's a great little hidden gem of the CPAN.

I will likely use perl -Mlocal::lib=$HOME/advent/lib as it looks highly useful to keep stuff segregated, although inc is a tool that pulls in a per-directory dotfile that modifies @INC . - Eds


1. Take ownership of your ~/.cpan dir and config!
First thing you'll want is to make sure your CPAN client is configured correctly for building as yourself. So many people simply run sudo cpan that this really is worth mentioning! If that's what you have done, chances are your ~/.cpan directory is actually owned by root! Furthermore, your config may be directing cpan to write to other places outside your home directory!
So, we should fix all that...
Step 1, Permissions: you can either
- take ownership of your ~/.cpan dir:

sudo chown -R `getent passwd $USER | cut -d':' -f3,4` ~/.cpan
- delete your ~/.cpan and start over:
sudo rm -rf ~/.cpan
Step 2, CPAN client config:
- create the config file if necessary:
mkdir -p ~/.cpan/CPAN && touch ~/.cpan/CPAN/
- edit to contain at least the following:
  $CPAN::Config = {
    'cpan_home'         => qq[$ENV{HOME}/.cpan],
    'build_dir'         => qq[$ENV{HOME}/.cpan/build],
    'histfile'          => qq[$ENV{HOME}/.cpan/histfile],
    'keep_source_where' => qq[$ENV{HOME}/.cpan/sources],
    'prefs_dir'         => qq[$ENV{HOME}/.cpan/prefs],
Windows users, please note: you should use HOMEDIR instead of HOME.
And that's it! If you blew away your ~/.cpan you may now want to run cpan (as yourself!) and let it auto-configure everything else and then select your mirrors. Issue the o conf init command if it doesn't ask to configure things on it's own.

2. csh recipe

  perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc

  source ~/.cshrc

View Source (POD)