使用包管理器时如何管理 Perl 模块?

2024-10-30 08:35:00
admin
原创
47
摘要:问题描述:SO 上最近出现的一个问题引起了我的思考。在我尝试过的大多数 Linux 发行版中,一些 Perl 模块可以通过包管理器获得。当然,其他的则不行。很长一段时间里,每当我需要安装一些 CPAN 模块时,我都会使用包管理器来查明某个包是否可用,并在可用时安装它。明显的优势是,只要有新版本的软件包可用,您...

问题描述:

SO 上最近出现的一个问题引起了我的思考。

在我尝试过的大多数 Linux 发行版中,一些 Perl 模块可以通过包管理器获得。当然,其他的则不行。很长一段时间里,每当我需要安装一些 CPAN 模块时,我都会使用包管理器来查明某个包是否可用,并在可用时安装它。

明显的优势是,只要有新版本的软件包可用,您就可以更新模块。

但是,如果模块未以预打包形式提供,并且存在该模块的依赖项,则会出现问题。每次 cpan shell 询问是否应遵循依赖项时,启动包管理器可能会非常累人。

通常,另一个缺点是预打包模块的版本。如果您运行的是 Debian 或 Ubuntu,您很快就会发现您无法像许多 CPAN 模块作者那样处于前沿。

Linux 上其他 Perl 开发人员如何处理这个问题?您是否只是忽略了软件包管理器提供的内容?是否有任何工具可以使 apt(例如)和 cpan 成为更好的搭档?或者您只是不通过 cpan shell 安装任何东西?


解决方案 1:

对于开发,我会安装自己的 Perl,而不使用系统 Perl。如果我想升级系统 Perl,我会使用系统包管理器。对于开发 Perl,我会使用 cpan 工具。

由于我将它们分开,所以我永远不会弄乱系统维护任务等所需的 Perl,但我不需要依赖系统的决策进行开发。

安装单独的 Perl 非常简单。当您从源代码发行版运行 Configure 时,它​​会询问您要将所有内容安装到哪里。输入您喜欢的任何路径。例如,我在/usr/local/perls中安装了许多 Perl,并且每个安装的所有内容都单独存在。然后我在/usr/local/bin中为它们创建符号链接(例如 perl5.8.9、perl.5.10.0、perl5.10.0-threaded)。当我需要特定版本时,我只需使用我想要的版本:

$ perl5.10.0 program.pl

特定的二进制文件确保程序选择正确的模块搜索路径等等(它与该二进制文件的 Config.pm 模块中的内容相同)。

下面是我用来创建符号链接的脚本。它查看 bin 目录,找出 Perl 版本,并创建类似cpan5.10.1等的链接。每个程序都已经知道要调用的正确 perl:

#!perl

use 5.010;

use strict;
use warnings;

use File::Basename;
use File::Spec::Functions;

my $perls_directory = catfile(
    $ARGV[0] // '/usr/local/perls', 
    'perl*'
);
die "$perls_directory does not exist!
" 
    unless -d dirname $perls_directory;

my $links_directory = $ARGV[1] // catfile( $ENV{HOME}, 'bin' ); #/
die "$links_directory does not exist!
" unless -d $links_directory;

foreach my $directory ( glob( $perls_directory ) )
{
    say "Processing $directory...";

    unless( -e catfile( $directory, 'bin' ) )
    {
        say "    No bin/ directory. Skipping!";
        next;
    }

    my @perls = glob( catfile( $directory, qw( bin perl5* ) ) );    

    my( $perl_version ) = $perls[0] =~ m/(5.d+.d+)z/;
    say "    perl version is $perl_version";

    foreach my $bin ( glob( catfile( $directory, 'bin', '*' ) ) )
    {
        say "    Found $bin";
        my $basename = basename( $bin );

        my $link_basename = do {
            if( $basename =~ m/5.d+.d+z/) { $basename }
            else                               { "$basename$perl_version" }
        };

        my $link = catfile( $links_directory, $link_basename );
        next if -e $link;
        say "        linking $bin => $link";
        symlink $bin => $link or
            warn "        Could not create symlink [$!]: $bin => $link!";
    }
}

所有内容都安装在适合该特定 Perl 的正确位置。

我也一直在想我应该把这些 Perl 目录放在某种源代码控制下。如果我添加了一个我不喜欢的模块,我只需回到较早的修订版本即可。不过我才刚刚开始这样做,还没有尝试过很多次。

我在 Effective Perler 博客中写了更多有关此类内容的文章:

  • 创建指向每个版本工具的链接。

  • 使用 Git 管理你的 Perl 模块。

解决方案 2:

我们通过 CPAN shell 安装所有内容。这确实忽略了包管理器所提供的内容,但它避免了您在尝试使用它们时提到的麻烦(触发依赖项、使用正确的版本)。

此外,这意味着我们的软件包可以在任何运行 CPAN 的平台上以编程方式(或通过 shell 手动)构建。依赖某个软件包管理器会影响您将软件分发到不使用/支持该软件包管理器的平台的能力。

解决方案 3:

自从最初提出这个问题以来,perlbrew已经发布。它使安装自定义、独立的 perl 安装变得轻而易举。并且在这些版本之间切换也同样容易:

perlbrew switch $version

解决方案 4:

我正在使用Debian进行开发和生产,并依赖于发行版提供的 Debian Perl 包。

对于我需要的 Perl 模块在 Debian 中不可用的情况,我通常会创建自己的 Debian 包并安装它。

当然,这种方法也不是没有缺点,因为很多 debian perl 模块已经过时了(至少在当前的 debian 稳定版本 - etch 中),并且反向移植具有大量依赖关系的Catalyst之类的东西并不实际。

但是,通过依赖 OS 包管理器,我保留了它的所有优秀功能,这些功能带来了易于维护,特别是对于已部署的服务器,因为您确切地知道安装了哪些包,并且只需简单apt-get update;apt-get upgrade(从 debian 或从本地存储库)即可将所有服务器升级到相同状态,包括 Perl 模块。

解决方案 5:

我在所有盒子上执行以下操作:

  • 我自己编译了 perl:还是主要用 5.8.[89] ,原版 5.10.0 性能倒退,对我影响很大,等 5.10.1 再试试;

  • 我使用(并强烈推荐)local::lib 模块来为每个项目保留一个模块目录。目前,该目录已通过 rsync 同步到安装项目的所有服务器,但我正在使用 git 进行测试;

  • 我为每个项目创建一个 Task:: 模块,这样我就可以使用单个命令安装所有依赖项。

解决方案 6:

我还使用 cpan shell 和 local::lib。

您不需要为每个项目都设置一个 Task::。只需使用 Module::Install(我喜欢像这样使用 Module::Starter:

$ module-starter --mi --module=Module::Name --author="Me" --email=me@cpan.org

然后只需在 Makefile.PL 中将依赖项放入需要“module::dependency”中即可。最后,当需要安装时,您只需perl Makefile.PL(回答是)然后make installdeps

[编辑于我最初给出这个答案的 5 年后]

如今,perlbrew 和 cpanm 是常用工具。local::lib 仍然有用例,但 perlbrew 和 cpanm 的组合解决了这些用例的超集。当您不准备编译自己的 perl 时,请使用 local::lib。

解决方案 7:

我建议只使用 cpan。Linux 发行版中包含的模块仅用于覆盖软件包依赖性。当您仅使用 CD 安装 Linux 且无法访问互联网时,它无法使用 cpan,因此一些模块以软件包形式包含,但对于 Perl 开发人员来说,这很糟糕。

另外,我曾经配置了一个 cpan 来在家里安装模块(.perl),而不需要 root 登录。

解决方案 8:

对于生产:

在开发中,选择一个适合要求的 perl 模块版本;如果可能,请选择目标操作系统的已发布版本(这使得以下大部分内容变得多余),否则,选择另一个。为其创建 RPM 规范文件。使用干净的构建 VM 以可重现的方式构建 RPM(从相应分支上签入的规范文件/源)。

当最终版本可以构建时(合并后),从发布分支执行相同的构建,将生成的 RPM 提交到部署存储库。这将用于最终验证,然后通过复制到生产存储库发布到生产中。

生产中的所有服务器都使用经过全面测试的完全相同的二进制文件;它们使用与开发人员预期相同的规范文件和源代码。

任何不遵循此模型的流程都无法升级 Perl 模块。其他任何生产软件亦是如此。

解决方案 9:

我使用 FreeBSD 端口并将所有 CPAN 依赖项包装在“元端口”中,作为一种本地端口。FreeBSD 拥有相当多的 CPAN 模块,并且它们的构建系统足够简单,即使不存在,您也可以轻松编写自己的端口 - 只需不要忘记提交所述端口,以便将其包含在端口树中。如果端口没有当前版本,您可以随时编辑端口的 Makefile 以使其使用新版本,同样不要忘记提交更改:-)。

最后,我使用Tinderbox将整个内容构建为二进制包,然后将其安装在所有生产和开发机器上。

底线 - 一旦您克服了编辑 Makefile 的恐惧,FreeBSD 的端口就是维护您的 perl 应用程序及其依赖项的好方法。

解决方案 10:

我最近开始使用 Gentoo,Gentoo 在这方面有几个非常重要的优势。首先,它g-cpan通常能够将 CPAN 中的许多(尽管不是全部)模块作为 Gentoo 软件包本地安装,尽管更新有点问题。

通常在 Gentoo 上,我的方法是g-cpan创建一个 ebuild 文件,然后从中安装,必要时进行调整。这样做的好处是升级变得非常容易。然后我将文件从 g-cpan/perl 移动到 dev-perl,并将其放在覆盖层中供其他人使用。这使我能够快速处理 g-cpan 无法处理的情况,而且 gentoo 打包无论如何都轻而易举/

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用