Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perlbrew and local::lib at the same time?

So far I have been using the system perl (on Ubuntu 10.10) and I was using local::lib to install CPAN modules in my private directory ~/perl5

As I am trying to use perlbrew it seems that they don't know about each other. I installed perl-5.12.3 using perlbrew but when I switch to it using perlbrew use perl-5.12.3 I still see the PERL5LIB and PERL_MM_OPT set by local::lib.

That's not good:

$ cpan XML::Simple
/home/gabor/perl5/perlbrew/perls/perl-5.12.3/bin/perl: symbol lookup error: /home/gabor/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/auto/Cwd/Cwd.so: undefined symbol: Perl_Gthr_key_ptr

while

$ which cpan
/home/gabor/perl5/perlbrew/perls/perl-5.12.3/bin/cpan

so it is using the right version of the cpan client but dues to the PERL5LIB environment variable it picks up the modules from the wrong place.

Does perlbrew have some compability mode or do I need to turn off PERL5LIB and PERL_MM_OPT manually?

like image 929
szabgab Avatar asked Mar 27 '11 06:03

szabgab


3 Answers

Since I started using perlbrew I stopped using local::lib for the shell use, because now that I have my own perl that i have write permissions to everything, just installing to site_perl is much more straightforward, and that allows me to have different versions of modules for each perl.

I still use local::lib (or more specifically, cpanm's -l or -L options that automatically sets up local::lib directory) to keep application specific dependencies inside an application directory.

like image 104
miyagawa Avatar answered Oct 25 '22 17:10

miyagawa


local::lib was not designed to work with multiple versions of Perl installed at the same time. Pure-Perl modules aren't usually a problem, but XS modules aren't compatible across major releases.

You can continue to use local::lib for pure-Perl modules (so you don't have to install them for every version of Perl you have brewed up, but XS modules should be installed into the perlbrew-created directories. You don't need to clear PERL5LIB (and you shouldn't, as XS modules might have pure-Perl dependencies that are installed there), but you will need to clear PERL_MB_OPT and PERL_MM_OPT when installing XS modules to keep them from installing into the local::lib directory.

If you need to continue using local::lib for XS modules for the system Perl, then I suggest creating a second local::lib environment for that (perhaps in ~/perl5sys). It might be easier to use perlbrew to install a copy of the same version of Perl as the system Perl, and then use that instead of the system Perl.

You can clean out the XS modules in your existing local::lib by removing the /home/gabor/perl5/lib/perl5/x86_64-linux-gnu-thread-multi directory.

like image 38
cjm Avatar answered Oct 25 '22 18:10

cjm


It is possible, but not comfortable. If this is a single-user setup, you might be better off not using local::lib and just letting perlbrew manage the modules for you. Also if it's a multi-user setup on a homogenous network, where everyone has the same machine and OS, then you can just set PERLBREW_ROOT to e.g. /net/share/perlbrew and then your installed perls (and their modules) can be shared. As noted in the other answers, this will be a problem if you try to mix machines (and possibly also problematic if you have different operating systems).

On a very diverse network, we prefer to keep everything separate. You can simply setup your local::lib to be a function of your current perl and your current platform, e.g.

distro=lsb_release -d|cut -f2|tr ' ' '-'
arch=`uname -m`
platform="$distro-$arch"

export PERLBREW_ROOT=/net/share/perlbrew/$platform
# You will have to first do 'perlbrew init' (just once for all users)
# In this case you don't need (and shouldn't have) a ~/.perlbrew
source $PERLBREW_ROOT/etc/bashrc

perl5base=/net/share/perl
# When $PERLBREW_PERL is not defined, local::lib puts modules in $perl5base/$platform
perl5=$perl5base/$platform/$PERLBREW_PERL

# We also found that we needed to clean PERL5LIB in between
export PERL5LIB=`echo -n $PERL5LIB|sed "s|${perl5base}[^:]*||g"`
export PATH=`echo -n $PATH|sed "s|${perl5base}[^:]*||g"`

# Setup local lib, relative to the perl being used
lib=$perl5/lib/perl5
mkdir -p $lib
eval $(perl -I"$lib" -Mlocal::lib="$perl5")

This is not our exact script, in particular you would need to check that these directories all exist first. You need to run perlbrew init once per platform and you need to bootstrap local::lib each time as well.

I don't recommend this approach, but provide as an example of one way to make this work, which it does for our mixed network (even on Mac OS). Leaving local::lib out and just using perlbrew (ignoring the system perl), would be a cleaner approach.

like image 34
Chad A. Davis Avatar answered Oct 25 '22 19:10

Chad A. Davis