我喜欢local::lib
的想法。至少,我发现它比cpan/perl在 * 大多数 * 情况下默认的全系统安装更好。但是,我在安装XS和发行版升级到较新的Perl的模块上遇到了困难。local::lib
的说明要求将此行添加到您的.bashrc
(或类似文件)
eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"
执行任意shell代码,这很好。您可以通过运行
perl -I$HOME/perl5/lib/perl5 -Mlocal::lib
在我的例子中,它返回以下代码,
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;
在上面的示例中,我们为两个最广泛使用的模块构建系统设置了默认选项,
MB
代表Module::Build
MM
代表ExtUtils::MakeMaker
我们告诉这些系统安装到/home/ecarroll/perl5
。
PERL5LIB
,用于设置@INC
。Perl中的@INC
变量用于解析use
调用。- 以及
PATH
,其预先规划local::lib
安装到的bin/
目录。
所以基本上,在您的home目录中安装perl模块,并首先查找安装在您的home目录中的文件。
我的问题是当你安装了带有XS的东西会发生什么?在我的例子中,我有一个XS文件,
/home/ecarroll/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/auto/Class/Load/XS/XS.so
这是用local::lib
安装的,使用的是Perl的早期版本。后来我运行了Debian dist-upgrade
,得到了一个更新的Perl版本(v5.36)。现在很多实用程序都产生了一个关于这个的迟钝错误,包括那些通过发行版本身安装的,比如我的例子Dist::Zilla
dzil
,我是用Debian's libdist-zilla-perl
package安装的。
$ dzil
XS.c: loadable library and perl binaries are mismatched (got first handshake key 0xeb00080, needed 0xeb80080)
这都是这个模块XS的结果,
perl -MClass::Load::XS -e1
XS.c: loadable library and perl binaries are mismatched (got first handshake key 0xeb00080, needed 0xeb80080)
这看起来像是local::lib
的常规用法:
- 我是否按照预期的方式使用
local::lib
?我还应该做什么? local::lib
应该如何处理XS?- 有没有办法让
local::lib
支持Perl的多个版本?我的发行版读写它管理的XS到/usr/share/perl/$PERL_VERSION
。这意味着dist-upgrade会把旧版本的所有XS都留在后面。如果local::lib
不是安装到/home/ecarroll/perl5/lib/perl5/
而是安装到/home/ecarroll/perl5/lib/perl5.30/
会很好吗?注意增加的次要版本。那么至少dist-upgrade不会“不要破坏分配。
3条答案
按热度按时间c3frrgcw1#
Perl在不同版本之间不保持ABI兼容性。(例如,5.34.x -〉5.36.y。)在安装了新版本的Perl之后,您需要重新安装那些安装在arch目录中的模块(XS模块和其他一些模块)。最简单和最安全的方法可能是删除(重命名)本地lib目录(/home/ecarroll/perl 5)并从头开始。
这就是为什么我避免使用除了distro提供的模块和distro提供的
perl
之外的任何东西。包管理器确保你总是有兼容的模块版本。如果这还不够好,我建议安装您自己的
perl
版本,而不是使用local::lib。像perlbrew
这样的工具使这变得容易。当您安装一个新的perl
时,您仍然需要重新安装所有的模块,但是如果您忘记了一个模块,您会得到更清晰的错误消息“找不到”。pbwdgjma2#
我很少使用
local::lib
,但在管理方面,我也是一个极简主义者。层次越多,情况就越糟糕。正如你所看到的,你自己的答案(现在被删除)提出了更高的复杂性来处理复杂性,这可能不适合你的情况。但是,
local::lib
有一种方法可以设置所有东西的位置。你试图对所有东西使用相同的位置,而不是根据你想做的事情来改变位置。然而,即使local::lib
允许你这样做,你也很可能忘记切换东西。我的解决方案更简单,我只是install a perl for whatever I'm doing(或者重用一个合适的perl),我根本不改变默认位置,我从来不需要管理它,我只是调用我想要的perl:
我有各种符号链接和稳定的路径调整,我使用工具名称和版本标记,我给它:
人们使用各种各样的工具,比如perlbrew,plenv,现在还有一些你认为可能解决这个问题的工具。如果你不得不不断地创建新的工具来处理你正在使用的工具,这是一个很大的危险信号。我宁愿把时间花在其他事情上。
piah890a3#
我坚持我的另一个答案-这太复杂了,你应该减少它。但是,让我们处理这个约束。你想使用
local::lib
。问题是你试图在任何特定的
perl
上强制使用相同的模块集,不管它是如何编译的。正如ikegami所解释的,你不能假设两个不同的perls,或者用不同的perls编译的同一个库是兼容的。perls的版本并不重要。两个不同的perl5.36,或者任何版本,都可能彼此不兼容。但是
local::lib
提供了设置适当值所需的信息,模块本身可以提供一些初始值:但是,您不需要在任何地方都使用这些值。您可以拥有任意多组这些变量。您可以为每个项目、每个perl或任何您想要的组织方式拥有不同的变量集。唯一的技巧是如何选择正确的变量集。
local::lib
的概要表明它希望您为项目设置适当的值:知道了这一点,你就可以通过在
local::lib
的路径中添加$^V
来获得每个版本的库(仍然存在二进制不兼容的问题):