【问题标题】:Where does CPAN install modules?CPAN 在哪里安装模块?
【发布时间】:2018-03-28 10:35:04
【问题描述】:

我找不到关于 CPAN 将其文件安装在何处的权威/全面描述。我假设必须有一套规则,而且它不像“XYZ 目录”那么简单,因为例如,Linux 机器上的多个用户可以运行 CPAN,即使只有一个 Perl 安装并且它仍然可以工作。那么,这些规则是什么?

这个问题的第二部分:PERL5LIB 环境变量的文档说它是“在查看标准库和当前目录之前要在其中查找 Perl 库文件的目录列表”。

我假设 CPAN 没有安装到标准库位置,因为大概是针对特定 Perl 版本修复的。那么也许 CPAN 会安装到 PERL5LIB 中?

最后,正如我已经提到的,CPAN 如何处理多个用户可能正在运行同一个 Perl 安装的事实?抱歉,如果这是一个单独的问题,但它似乎可能相关。

【问题讨论】:

  • 对于如此复杂的答案集,我希望这个问题会有更多的赞成票。自最初的答案以来情况是否发生了变化,还是现在所有的开发都转向 Perl6?
  • 更新:似乎 cpan 已经改进为 cpanm cpan App::cpanminus

标签: perl cpan


【解决方案1】:

首先,CPAN 不安装模块。这是一个存储库。

cpan 也不安装模块。 cpan 从 CPAN 下载发行版并运行其中提供的安装程序,无论是 Makefile.PL 还是 Build.PL。 (cpanmcpanp 也是如此。)

这些安装脚本主要使用ExtUtils::MakeMakerModule::Build 来安装发行版(尽管存在其他安装程序)。


Perl 指定了三组安装位置。

  • perl,用于 Perl 本身包含的模块。
  • vendor,用于由您的 perl 二进制文件的提供者安装的模块。
  • site,用于使用 cpan 安装的模块。

这些集合中的每一个都提供了多种文件类型的安装位置。

                        Installation location
                        --------------------------------------------------------
Type of file            perl             vendor                 site
----------------------  ---------------  ---------------------  -------------------
Build-specific modules  installarchlib   installvendorarch      installsitearch
Modules                 installprivlib   installvendorlib       installsitelib
Binary programs         installbin       installvendorbin       installsitebin
Other programs          installscript    installvendorscript    installsitescript
man pages for scripts   installman1dir   installvendorman1dir   installsiteman1dir
man pages for modules   installman3dir   installvendorman3dir   installsiteman3dir
html docs for scripts   installhtml1dir  installvendorhtml1dir  installsitehtml1dir
html docs for modules   installhtml3dir  installvendorhtml3dir  installsitehtml3dir

您可以使用以下方法获取任何这些位置的路径:

perl -V:{var}        # Substitute `{var}` for the var name.

您可以使用以下方法获取这些位置的所有路径:

perl -V:'install.*'

这些是安装程序使用的默认值[1]。但是,两个最常用的安装程序允许用户进行安装以覆盖任何和所有这些。如果模块安装在非标准位置,

  • PERL5LIB 可用于让perl 知道在哪里可以找到模块。
  • PATH 可用于让系统知道在哪里可以找到捆绑的程序。
  • MANPATH 可用于让 man 知道在哪里可以找到手册页。

【讨论】:

  • 除了 CPAN-the-repository,还有 CPAN-the-Perl-module(这是cpan 命令使用的)。
  • 该表是从某个地方获取的还是您自己编写的?
  • @simbabque,它基于ExtUtils::MakeMaker 的文档中标题make intstall 下的表格以及perl -V:'install.*' 提供的变量列表。
【解决方案2】:

CPAN 实际上并不安装文件。它运行嵌入在每个发行版中的安装脚本,然后执行实际安装。

对于使用 ExtUtils::MakeMaker 的发行版,此处记录了默认值:https://metacpan.org/pod/ExtUtils::MakeMaker#make-installINSTALLDIRS 的默认值为 site)。对于Module::Build,请参阅https://metacpan.org/pod/Module::Build#INSTALL-PATHS

当文档中提到$Config{foo}%Config 时,是指the Config module 提供的%Config 变量。 $Config{foo} 的值也可以通过运行perl -V:foo 来检查。

(如果您认为这看起来不必要地复杂,那么您是对的。)

简短的版本是 perl 有多个“系统目录”,其中一个用于“站点特定”模块,因此用作默认安装目标。你是对的,这是一个单一的目录(perl install),它不能很好地与多用户系统配合:它在所有用户之间共享,你需要root权限来安装模块(这样做可能会升级/覆盖系统包中的模块,这是个坏主意)。

人们所做的是配置 ExtUtils::MakeMaker、Module::Build 等以安装到用户的主目录中。这可以通过环境变量来完成。然后他们告诉 perl 将该目录添加到@INC,这样就可以真正找到并加载模块。这是通过另一个环境变量PERL5LIB 完成的。 (PERL5LIB不影响安装,纯粹用于加载。)

以上所有内容都是自动化的,并封装在local::lib 中。 (local::lib 也可以用于例如创建每个项目的模块子目录。)

CPAN 文档还说:

从 CPAN 1.9463 开始,如果您没有写入默认 perl 库目录的权限,CPAN 的配置过程会询问您是否要引导 local::lib,这使得保持个人 perl 库目录变得容易。


您可以通过在您的主目录中安装一个私有 perl 来回避整个问题(在这种情况下,“系统”目录只是您的 $HOME 下的另一个子目录,因此不与任何人共享并且可以由你)。这很容易,例如perlbrew.


另一个注意事项:您刚刚在PERL5LIB 的文档中发现了一个错误。 “当前目录”已过时:出于安全原因,. 已从模块位置的默认列表中删除。

【讨论】:

  • 谢谢,这很有帮助。关于这一点:“人们所做的是配置 ExtUtils::MakeMaker、Module::Build 等以安装到用户的主目录中” local::lib 是否使这变得多余?
  • @Stephen 好吧,大多数人使用 local::lib 来做这件事。 :-) local::lib 的核心只是一种自动创建一些目录并正确设置一些环境变量的方法。所以是的:如果您使用 local::lib (通过将魔术线添加到您的 .bashrc 或等效项),您不需要手动配置任何其他内容。
【解决方案3】:

这是一个复杂的问题。您可以通过查找其中一个库的位置来判断 核心 库的位置:

perldoc -l B

会告诉你B核心模块的位置。并且你可以尝试其他不同的结果......

另外,perl -V 会告诉你所有重要的 shell 变量以及 @INC 的值,它会在哪里寻找库。

Core 库通常位于与 local 库不同的位置。此外,如果您使用的是 perlbrewlocal::lib,您可能需要考虑更多的事情。关于 shell 变量,除了PERL5LIB,还有PERL_LOCAL_LIB_ROOT

关于您的其他问题,我想说root 可能会在系统范围内安装库。任何用户都会通过 shell 变量或其他方式(如命令行选项perl -I <lib location>,或在代码中(如use lib <lib location>;)包含这些位置和任何本地位置。

还有perlbrewlocal::lib 一起允许非特权用户在本地目录中安装Perl 和库。

关于从 CPAN 安装模块的方法,我最喜欢的是 cpanminus。它使用cpanm <library to install> 调用。它永远不会失败......

【讨论】:

    猜你喜欢
    • 2011-03-31
    • 1970-01-01
    • 2011-05-17
    • 2018-06-19
    • 2014-12-06
    • 2013-11-04
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多