10

我最近在安装一些模块时遇到了一些麻烦,我惊讶地发现许多已安装的模块都有重复的安装和版本。尝试使用 跟踪标准(如果有这样的东西)安装中的东西cpanm,我发现以下结果非常令人困惑。

报告显示以下位置:

  • 使用cpan -V
# cpan -V

/usr/bin/cpan script version 1.672, CPAN.pm version 2.22
--------------------------------------------------
Checking install dirs...
Checking core
        + /usr/share/perl5/5.26
        + /usr/lib/perl5/5.26/x86_64-cygwin-threads
Checking vendor
        + /usr/share/perl5/vendor_perl/5.26
        + /usr/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads
Checking site
        + /usr/local/share/perl5/site_perl/5.26
        + /usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads
Checking PERL5LIB
        no directories for PERL5LIB
Checking PERLLIB
        no directories for PERLLIB
  • 使用perl -V:.*site.*
# perl -V:.*site.* |column -t -s "=" |sort -d -i -k 1.22

d_sitearch           'define';
usesitecustomize     'undef';
siteprefix           '/usr/local';
siteprefixexp        '/usr/local';
installsitebin       '/usr/local/bin';
installsitescript    '/usr/local/bin';
sitebin              '/usr/local/bin';
sitebinexp           '/usr/local/bin';
sitescript           '/usr/local/bin';
sitescriptexp        '/usr/local/bin';
installsitearch      '/usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads';
sitearch             '/usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads';
sitearchexp          '/usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads';
installsitehtml1dir  '/usr/local/share/doc/perl/html/html1';
sitehtml1dir         '/usr/local/share/doc/perl/html/html1';
sitehtml1direxp      '/usr/local/share/doc/perl/html/html1';
installsitehtml3dir  '/usr/local/share/doc/perl/html/html3';
sitehtml3dir         '/usr/local/share/doc/perl/html/html3';
sitehtml3direxp      '/usr/local/share/doc/perl/html/html3';
installsiteman1dir   '/usr/local/share/man/man1';
siteman1dir          '/usr/local/share/man/man1';
siteman1direxp       '/usr/local/share/man/man1';
installsiteman3dir   '/usr/local/share/man/man3';
siteman3dir          '/usr/local/share/man/man3';
siteman3direxp       '/usr/local/share/man/man3';
installsitelib       '/usr/local/share/perl5/site_perl/5.26';
sitelib              '/usr/local/share/perl5/site_perl/5.26';
sitelib_stem         '/usr/local/share/perl5/site_perl/5.26';
sitelibexp           '/usr/local/share/perl5/site_perl/5.26';
  • 使用@INC
# perl -e 'print join("\n",@INC,"")'

/usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads
/usr/local/share/perl5/site_perl/5.26
/usr/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads
/usr/share/perl5/vendor_perl/5.26
/usr/lib/perl5/5.26/x86_64-cygwin-threads
/usr/share/perl5/5.26

结果是cpan-outdated -p --verbose显示完全不同(且更短)的过时模块列表cpan -lO。不用说,模块安装在所有地方,我不知道如何理解是否有默认安装位置以及它去哪里,或者应该去哪里。


问题

  1. core那么,vendorsite 类型的路径有什么区别呢?
  2. 为什么每种类型都有 2 条路径?
4

2 回答 2

12

这些安装位置的最佳参考可能是关于它安装位置的ExtUtils::MakeMaker文档。在本质上:

  • core(也称为privlib) - 是与 Perl 一起安装的核心模块所在的位置。在早于 5.12 的 Perls 上,双生命模块的更新也需要在这里安装在核心版本上,而不是安装到站点或供应商 lib 中,因为 privlib@INC在 5.12 之前首先出现。这在 privlib 中的文件通常由包管理器管理的系统 Perl 中尤其危险。
  • vendor- 是分发供应商可以安装模块的地方。这通常是系统包管理器安装非核心模块的地方。
  • site- 是 CPAN 客户端在直接调用时安装模块的位置,除非像上面提到的双生命模块这样的异常配置。

(双生命模块是核心模块,也可以在 CPAN 上单独使用,这意味着您可以安装更新版本。)

这些库位置中的每一个都有一个arch变体,这是安装特定于构建输出文件的发行版的位置。没有动态配置的纯 perl 发行版安装到与架构无关的标准目录中,并且通常可以在 Perl 和架构的其他安装中不加修改地运行,只要它们的要求仍然满足(尽管这不是一个好主意,除非你真的知道你是什么正在做)。带有任何已编译 XS 模块或在构建过程中动态生成模块的发行版都安装到该arch目录中,并且从另一个 Perl 中使用是不安全的。

所有这些位置都是在构建 Perl 时配置的,并且可以使用perl -V您显示的选项发现。它们也都有附带scriptbin目录(通常是相同的)和联机帮助页目录。

至于差异cpan-outdated- 这个工具(就像许多使用ExtUtils::Installed的工具一样)仅限于查找具有packlists的模块,这些模块在使用 CPAN 客户端安装模块时包含,但不包含核心模块,它们通常被剥离供应商包。所以很可能cpan-outdated只会发现sitelib中的模块,但这通常是你需要找到的。我不确定 cpan 命令使用什么机制。

于 2019-01-31T22:48:21.677 回答
3

更新

感谢ikegami的 SO 链接,我已经做了一些源代码浏览,我们可以在其中找到很多关于此的信息。要获得更具体的位置:

# perl -V:'install(privlib|archlib|vendorlib|vendorarch|sitelib|sitearch)' |column -t -s "="

installarchlib     '/usr/lib/perl5/5.26/x86_64-cygwin-threads';
installprivlib     '/usr/share/perl5/5.26';
installsitearch    '/usr/local/lib/perl5/site_perl/5.26/x86_64-cygwin-threads';
installsitelib     '/usr/local/share/perl5/site_perl/5.26';
installvendorarch  '/usr/lib/perl5/vendor_perl/5.26/x86_64-cygwin-threads';
installvendorlib   '/usr/share/perl5/vendor_perl/5.26';

然后对于这些含义,我们可以在文件中查看(在 perl 源代码中)./Porting/Glossary::

installarchlib    '- is the same for modules with arch- or build-dependent components.'
installprivlib    '- contains the "pure Perl" modules that came with Perl.'
installsitearch   '- is the same for modules with arch- or build-dependent components.'
installsitelib    '- contains the "pure Perl" modules installed by you.'
installvendorarch '- is the same for modules with arch- or build-dependent components.'
installvendorlib  '- contains the "pure Perl" modules installed by your distro.'

关于installstyle选项的附加有趣说明:

installstyle (installstyle.U):

这个变量描述了 perl 安装的风格。这对于需要操纵整个 perl 发行版的工具很有用。Perl 本身并不使用它来查找它的库——库目录直接存储在 Config.pm 中。目前,只有两种样式: liblib/perl5。默认库位置(例如 privlib、sitelib)是$prefix/lib$prefix/lib/perl5。如果$prefix是专用于 perl 的目录(例如 /opt/perl),则前者很有用,而如果 $prefix 由许多包共享,则后者很有用,例如 if $prefix=/usr/local

不幸的是,虽然这个“样式”变量用于为所有三个目录层次结构(核心、供应商和站点)设置默认值,但不能保证相同的样式实际上适用于所有这些目录。例如,$prefix 可能是 /opt/perl,但 $siteprefix也可能是 /usr/local。(也许,回想起来,“lib”风格不应该得到支持,但在当时看来确实是个好主意。)

对于 MakeMaker 等可用于将附加模块安装到非标准位置的工具,情况就更不明确了。例如,如果用户打算将模块安装到私有目录中(可能通过在 Makefile.PL 命令行上设置 PREFIX),那么没有理由假设 Configure-time $installstyle 设置与该 PREFIX 相关.

这可能会在以后扩展以包含其他信息,因此请注意结果的模式匹配。

为了与 perl5.005 和更早版本兼容,默认设置基于 $prefix 是否包含字符串“perl”。

然后可以在INSTALLATION文件中的Installation Directories标题下找到所有坚韧不拔的细节。

  • Directories for the perl distribution
    默认情况下,Configure 将使用以下目录(5.28.1):

        Configure variable  Default value
        $prefixexp          /usr/local
        $binexp             $prefixexp/bin
        $scriptdirexp       $prefixexp/bin
        $privlibexp         $prefixexp/lib/perl5/$version
        $archlibexp         $prefixexp/lib/perl5/$version/$archname
    
  • Directories for site-specific add-on files

       Configure        Default
       variable          value
     $siteprefixexp    $prefixexp
     $sitebinexp       $siteprefixexp/bin
     $sitescriptexp    $siteprefixexp/bin
     $sitelibexp       $siteprefixexp/lib/perl5/site_perl/$version
     $sitearchexp      $siteprefixexp/lib/perl5/site_perl/$version/$archname
    
  • Directories for vendor-supplied add-on files

    如果正在构建 perl 的二进制分发版进行分发,Configure 可以选择设置以下目录供您用于分发附加模块。

       Configure          Default
       variable            value
     $vendorprefixexp    (none)
    
     (The next ones are set only if vendorprefix is set.)
    
     $vendorbinexp       $vendorprefixexp/bin
     $vendorscriptexp    $vendorprefixexp/bin
     $vendorlibexp       $vendorprefixexp/lib/perl5/vendor_perl/$version
     $vendorarchexp      $vendorprefixexp/lib/perl5/vendor_perl/$version/$archname
    
  • otherlibdirs
    作为最后的包罗万象,Configure 还提供了一个$otherlibdirs变量。此变量包含要添加到@INC的附加目录的冒号分隔列表。默认情况下,它将为空。

  • APPLLIB_EXP
    还有另一种在 perl 构建时添加 @INC 路径的方法,即设置 APPLLIB_EXP C 预处理器令牌。由 APPLLIB_EXP 定义的目录首先被添加到 @INC,在任何其他目录之前。
    sh Configure -Accflags='-DAPPLLIB_EXP=\"/usr/libperl\"'

于 2019-02-01T10:42:48.067 回答