I love the idea of local::lib
. At least, I find it preferable to the default system-wide installs that cpan/perl defualts to in most every way. However, I'm having difficulties with modules that install XS and distribution upgrades to newer Perls. The instructions for local::lib
call for adding this line to your .bashrc
(or like file)
eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"
That executes arbitrary shell code, which is fine. You can see the code it executes by running
perl -I$HOME/perl5/lib/perl5 -Mlocal::lib
In my case it returns this code,
PATH="/home/ecarroll/perl5/bin${PATH: :${PATH}}"; export PATH;
PERL5LIB="/home/ecarroll/perl5/lib/perl5${PERL5LIB: :${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/ecarroll/perl5${PERL_LOCAL_LIB_ROOT: :${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/ecarroll/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/ecarroll/perl5"; export PERL_MM_OPT;
In the above, we're setting the default options for the two most widely used module build systems,
MB
is forModule::Build
MM
is forExtUtils::MakeMaker
We're telling those system to install to /home/ecarroll/perl5
. The rest of the command sets
PERL5LIB
which is used in setting@INC
. The@INC
variable in Perl is used to resolve calls withuse
.- and,
PATH
which prepends thebin/
directory thatlocal::lib
installs to.
So basically, install perl modules in your home directory, and look first for files installed in your home directory.
My question is what happens when you install something that has XS? In my case, I have an XS file,
/home/ecarroll/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/auto/Class/Load/XS/XS.so
This was installed, with local::lib
using an earlier version of Perl. I've since ran a Debian dist-upgrade
and got a newer version of Perl (v5.36). Now a lot of utilities produce an obtuse error about this, including ones installed through the distro itself like in my case Dist::Zilla
dzil
which I installed with Debian's libdist-zilla-perl
package.
$ dzil
XS.c: loadable library and perl binaries are mismatched (got first handshake key 0xeb00080, needed 0xeb80080)
Which is all a result of this module's XS,
perl -MClass::Load::XS -e1
XS.c: loadable library and perl binaries are mismatched (got first handshake key 0xeb00080, needed 0xeb80080)
This seems like very routine use of local::lib
:
- Am I using
local::lib
in the way intended? What else should I be doing? - How is
local::lib
supposed to handle XS? - Is there a way to make
local::lib
support multiple versions of Perl? My distro reads and writes the XS it manages to/usr/share/perl/$PERL_VERSION
. This means a dist-upgrade leaves all the XS from the old version behind. It would be nice to havelocal::lib
install not to/home/ecarroll/perl5/lib/perl5/
but instead to/home/ecarroll/perl5/lib/perl5.30/
? Note the added minor version. Then at least a dist-upgrade wouldn't break the distribution.
CodePudding user response:
Perl doesn't maintain ABI compatibility between versions. (5.34.x -> 5.36.y, for example.) After installing a new version of Perl, you will need to re-install modules that install themselves in arch dirs (XS modules and a few others). Might be easiest and safest to remove (rename) the local lib directory (/home/ecarroll/perl5) and start from scratch.
That's why I avoid using anything but distro-provided modules with distro-provided perl
. The package manager ensures you always have compatible builds of the modules.
If that's not good enough, I recommend installing your own builds of perl
instead of using local::lib. Tools like perlbrew
makes this easy. You'll still have to re-install all the modules when you install a new perl
, but you'll get the cleaner "Can't locate" error message if you forget one.
CodePudding user response:
This is a shortcoming of local::lib
The local::lib
system currently suffers in only supporting one version of perl at a time. Things are local to the user, not the user and perl version. That means
- If your system has two different versions of perl, the instructions and configuration for setting this in
.profile
will not work. Because they'll both save to and read from the same directory which is read from the user's environment. - If your system upgrades from one version of perl, to a different version of perl you'll have to manually clear out your
local::lib
directory (defaults to~/perl
). Otherwise, your newer perl version will read from code compiled against your older perl. This won't work as XS ABI is different. Deleting~/perl
is whatmst
does to solve this problem, and he wrotelocal::lib
.
The author of local::lib
, mst, has tried to remedy some of these problems with plx
however I'm not sure if the problem is fixed there either.