A recent question here on SO got me thinking.
On most Linux distributions that I tried, some Perl modules would be available through the package manager. Others, of
I do the following on all my boxes:
For development, I install my own Perl and leave the system Perl alone. If I want to upgrade the system Perl, I use the system package manager. For my development Perl, I use the cpan tool.
Since I keep those separate, I should never mess up the Perl that the system needs for its maintenance tasks and so on, but I don't have to rely on the system's decisions for development.
It's very easy to install separate Perls. When you run Configure from the source distribution, it will ask you where you want to install everything. Give it any path that you like. I have many Perls installed in /usr/local/perls, for instance, and everything for each installation lives separately. I then make symlinks in /usr/local/bin for them (e.g. perl5.8.9, perl.5.10.0, perl5.10.0-threaded). When I want a particular version, I just use the one I want:
$ perl5.10.0 program.pl
The particular binary ensures that the program picks up the right module search path and so on (it's the same stuff in the Config.pm module for that binary).
Here's a script I use to create the symlinks. It looks in the bin directory, figures out the Perl version, and makes links like cpan5.10.1
and so on. Each program already knows the right perl to call:
#!perl
use 5.010;
use strict;
use warnings;
use File::Basename;
use File::Spec::Functions;
my $perls_directory = catfile(
$ARGV[0] // '/usr/local/perls',
'perl*'
);
die "$perls_directory does not exist!\n"
unless -d dirname $perls_directory;
my $links_directory = $ARGV[1] // catfile( $ENV{HOME}, 'bin' ); #/
die "$links_directory does not exist!\n" unless -d $links_directory;
foreach my $directory ( glob( $perls_directory ) )
{
say "Processing $directory...";
unless( -e catfile( $directory, 'bin' ) )
{
say "\tNo bin/ directory. Skipping!";
next;
}
my @perls = glob( catfile( $directory, qw( bin perl5* ) ) );
my( $perl_version ) = $perls[0] =~ m/(5\.\d+\.\d+)\z/;
say "\tperl version is $perl_version";
foreach my $bin ( glob( catfile( $directory, 'bin', '*' ) ) )
{
say "\tFound $bin";
my $basename = basename( $bin );
my $link_basename = do {
if( $basename =~ m/5\.\d+\.\d+\z/) { $basename }
else { "$basename$perl_version" }
};
my $link = catfile( $links_directory, $link_basename );
next if -e $link;
say "\t\tlinking $bin => $link";
symlink $bin => $link or
warn "\t\tCould not create symlink [$!]: $bin => $link!";
}
}
Everything gets install in the right place for that particular Perl.
I've also been thinking that I should put those Perl directories under some sort of source control. If I add a module I don't like, I just back out to an earlier revision. I'm only starting to do that though and haven't played with it much.
I've written more about this sort of thing in the Effective Perler blog:
I have started using Gentoo recently and Gentoo has a few very important advantages in this area. The first is that g-cpan
is capable usually of installing many (though not all) modules from CPAN as Gentoo packages natively, though updating becomes a bit of a problem.
Usually on Gentoo, my approach is to use g-cpan
to create an ebuild file, then install from that, tweaking if necessary. The advantage is that upgrading becomes really easy. I then move the file from g-cpan/perl to dev-perl and put it in an overlay for others to use. This allows me to quickly handle the cases g-cpan does not and gentoo packaging is a breeze anyway/
I use FreeBSD ports and wrap up all the CPAN dependencies in a "meta port" as a sort of a local port. FreeBSD has quite a large number of CPAN modules and their build system is approachable enough that you can easily write your own port if it doesn't exist--just dont forget to submit said port so it gets included in the ports tree. If the port doesn't have the current version in stock, you can always edit the Makefile for the port so it uses the new version, again don't forget to submit the change :-).
Lastly, I use Tinderbox to build the whole mess as binary packages that I then install on the all the production and development machines.
Bottom line--Once you get over your phobia of editing Makefiles, FreeBSD's ports are a great way to maintain your perl application and its dependencies.