作为一名忠实的 Perl 程序员,我发现自己大量使用了出色的 Perl 模块存储库CPAN。我尽我最大的努力跟上 Perl 的所有最新动态。

我最近也迷上了conda,这是一个结合了包管理和环境管理的简洁工具。如果您还没有检查过,我建议您看看它是否适合您的需求。

TL;DR

(此 tl 之后的完整帖子;博士)

# envname is the name of your (existing) conda env
conda activate envname
# cpanm is available on either conda-forge or
# bioconda, so add conda-forge (or look up
# how to set up bioconda if you need tools
# for bioinformatics)
conda config --add channels conda-forge
# Install cpanm
conda install perl-app-cpanminus
# packagename is the name of the Perl package you want
env PERL5LIB="" PERL_LOCAL_LIB_ROOT="" PERL_MM_OPT="" PERL_MB_OPT="" $CONDA_PREFIX/bin/cpanm packagename

进入全屏模式 退出全屏模式

如果这不起作用:

# Make sure gcc is installed
# Replace gcc with gxx if you need to compile C++
conda install -n envname gcc_impl_linux-64
conda activate envname
declare perlarchloc=$($CONDA_PREFIX/bin/perl -V::installarchlib: | sed "s/[' ]//g")
for conffile in "Config_heavy.pl" "CORE/config.h" "Config.pm"
do
    sed -i -E 's%/tmp/build/[a-zA-Z0-9]+/perl_[0-9]+/_build_env%'"$CONDA_PREFIX"'%g' "$perlarchloc"/"$conffile"
done
unset perlarchloc

进入全屏模式 退出全屏模式

如果 still 不起作用,请跳到最后一节。

/tl;博士

安装 Perl 和 Python 包

Conda 是用 Python 编写的,我认为因此对 Python 中运行良好的东西有轻微的偏见。例如,安装尚未打包在 conda 通道中的 python 模块相对简单:

# envname is the name of your (existing) conda env
conda activate envname
# Make sure pip is installed
conda install pip
# packagename is the name of the python package you want
pip install packagename

进入全屏模式 退出全屏模式

凉爽的。现在,Perl 包怎么样?

# envname is the name of your (existing) conda env
conda activate envname
# cpanm is available on either conda-forge or
# bioconda, so add conda-forge (or look up
# how to set up bioconda if you need tools
# for bioinformatics)
conda config --add channels conda-forge
# Install cpanm
conda install perl-app-cpanminus
# packagename is the name of the Perl package you want
cpanm packagename

进入全屏模式 退出全屏模式

如果这对你有用,太好了!如果没有,那么让我们看看可能出了什么问题。

问题一:local::lib或者其他环境变量

我们很多人喜欢使用local::lib来在本地安装 Perl 包,而不需要弄乱系统级 Perl。这通常很好用。当您让 conda 处理事情时,就没有那么多了。

您想使用 conda 有几个原因,如果您正在阅读本文,您可能已经知道原因(如果您真的不知道 conda 有多大用处,请继续查找有关 conda 的更多信息)。因此,您最好只在该环境中为某个环境安装 Perl 模块。

也许您的环境使用的 perl 版本与您的系统(或其他环境)不同。也许您与许多用户共享 conda 环境,并且您希望它的任何用户都可以访问某些特定模块。

不幸的是,设置 local::lib 可能意味着之前的cpanm命令仅在 conda env 之外为您安装了该模块:

$ perldoc -l packagename
$HOME/perl5/lib/perl5/packagename/packagename.pm

进入全屏模式 退出全屏模式

啊。

为避免这种情况以及影响 Perl 模块的任何其他环境变量的干扰,您可以尝试以下操作:

env PERL5LIB="" PERL_LOCAL_LIB_ROOT="" PERL_MM_OPT="" PERL_MB_OPT="" $CONDA_PREFIX/bin/cpanm packagename

进入全屏模式 退出全屏模式

以上对我有用,它有点难看,但我现在需要一个解决方案。如果您知道更好的方法,请在评论中告诉我,我会更新帖子。

问题2:使用XS的模块

事实证明,以这种方式安装一个使用XS的模块(就像许多需要 C 速度的模块,或者访问 Perl 内部的模块一样)是行不通的。也是 conda 中的一个已知错误。

发生的情况是 cpanm 的配置保留了一些相对于构建它的目录的路径,而不是相对于 conda 环境的路径(正如您将在中看到该错误报告中的最后一条评论)。

该评论还解释了如何解决该问题,但我将在此处重现该解决方案,更笼统一点(假设您安装的 Perl 版本是 5.26.2,因此请务必先检查):

# Make sure gcc is installed
# Replace gcc with gxx if you need to compile C++
conda install -n envname gcc_impl_linux-64
conda activate envname
declare perlarchloc=$($CONDA_PREFIX/bin/perl -V::installarchlib: | sed "s/[' ]//g")
for conffile in "Config_heavy.pl" "CORE/config.h" "Config.pm"
do
    sed -i -E 's%/tmp/build/[a-zA-Z0-9]+/perl_[0-9]+/_build_env%'"$CONDA_PREFIX"'%g' "$perlarchloc"/"$conffile"
done
unset perlarchloc

进入全屏模式 退出全屏模式

现在只需重新运行您的cpanm命令,这应该可以工作!除非...

问题 2a:compilerroot?!

事实证明,在某些配置中,变量$compilerroot用于设置编译器在上述文件中的位置。自动化并不容易(对我来说),所以我建议你手动打开"$CONDA_PREFIX"/lib/5.26.2/x86_64-linux-thread-multi/下的“Config_heavy.pl”和“Config.pm”文件并查找以下行:

my $compilerroot = "";
# Some other code is here

进入全屏模式 退出全屏模式

更改该分配,并删除该行后面的 if/else 代码,该代码也有条件地设置为$compilerroot。确保为环境的 conda 前缀使用正确的路径(即,当您的环境处于活动状态时,值为$CONDA_PREFIX):

my $compilerroot = "/your/conda/env/prefix";

# Don't change this code below
local *_ = \my $a;

进入全屏模式 退出全屏模式

_现在_尝试使用 cpanm :)。

我希望这可以帮助别人 _。我花了几个小时才弄清楚这一点。回想起来,自己为 conda 打包缺少的 perl 模块可能更容易!

Edit:2021 年 2 月 20 日。更新了显示如何更改 conda perl 标头中的路径的代码块。现在不是硬编码 perl 版本,而是使用 conda perl 安装给出的 arch lib 位置的位置。还更新了帖子,以便调用 condacpanm使用$CONDA_PREFIX环境变量。

Logo

更多推荐