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

时间:2008-12-29 18:01:21

标签: linux perl module packages cpan

这里的recent question让我想到了。

在我尝试的大多数Linux发行版中,一些Perl模块可以通过包管理器获得。其他人当然不是。很长一段时间我会使用我的软件包管理器,只要我需要安装一些CPAN模块来确定软件包是否可用,并在软件包安装时安装它。

显而易见的优点是,只要有新版本的软件包,您就可以更新模块。

但是,如果模块没有预先打包的形式,并且该模块存在依赖关系,则会遇到麻烦。每次cpan shell询问是否应该遵循依赖关系时,启动你的包管理器可能会非常累人。

通常,另一个缺点是预打包模块的版本。如果您正在运行Debian或Ubuntu,您很快就会发现,您将无法像最近的CPAN模块作者那样生活在最前沿。

Linux上的其他Perl人如何处理这个问题?你只是忽略你的包经理提供的东西吗?是否有任何工具可以使apt(例如)和cpan更好的队友?或者你只是不通过cpan shell安装任何东西?

10 个答案:

答案 0 :(得分:35)

对于开发,我安装自己的Perl并单独保留系统Perl。如果我想升级系统Perl,我使用系统包管理器。对于我的开发Perl,我使用cpan工具。

由于我将这些内容分开,我不应该把系统所需的Perl搞砸到维护任务等等,但我不必依赖系统的开发决策。

安装单独的Perls非常容易。从源代码分发中运行Configure时,它会询问您要在何处安装所有内容。给它任何你喜欢的路径。例如,我在 / usr / local / perls 中安装了许多Perls,并且每个安装的所有内容都是分开的。然后我在 / 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!\n" 
    unless -d dirname $perls_directory;

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

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

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

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

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

    foreach my $bin ( glob( catfile( $directory, 'bin', '*' ) ) )
    {
        say "\tFound $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 "\t\tlinking $bin => $link";
        symlink $bin => $link or
            warn "\t\tCould not create symlink [$!]: $bin => $link!";
    }
}

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

我一直在想我应该将这些Perl目录置于某种源代码控制之下。如果我添加一个我不喜欢的模块,我只需要回到早期版本。我只是开始这样做,并没有玩过多少。

我在Effective Perler博客中写了更多关于此类事情的内容:

答案 1 :(得分:12)

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

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

答案 2 :(得分:8)

由于最初询问此问题,perlbrew已被释放。它使安装自定义,自包含的perl安装变得微不足道。在这些版本之间切换同样简单:

perlbrew switch $version

答案 3 :(得分:6)

我在所有方框上执行以下操作:

  • 我编译自己的perl:我仍然使用5.8。[89]大多数情况下,股票5.10.0有一个性能回归,给我很多,等待5.10.1再试一次;
  • 我使用(强烈推荐)local :: lib模块来保存每个项目的模块目录。现在,该目录与所有安装项目的服务器进行了rsync,但我正在使用git进行测试;
  • 我为每个项目创建一个Task ::模块,这样我就可以用一个命令安装所有依赖项。

答案 4 :(得分:6)

我正在使用Debian进行开发和制作,并依赖于随发行版提供的debian Perl包。

如果我需要一个debian中没有的Perl模块,我通常会创建自己的debian软件包并安装它。

当然,这种方法并非没有缺点,因为很多debian perl模块已经过时了(至少在目前的debian稳定版本中是蚀刻版本),并且向后移植具有很多依赖性的Catalyst之类的东西并不是实用。

然而,依靠操作系统软件包管理器,我保留了它的所有强大功能,这使得易于维护,特别是对于已部署的服务器,因为您确切知道安装了哪些软件包,以及一个简单的apt-get update;apt-get upgrade(来自debian或本地存储库)将所有服务器升级到相同的状态,包括Perl模块。

答案 5 :(得分:4)

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

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

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

然后只需要在'modules :: dependency'中弹出你的依赖项;在Makefile.PL中。最后,在安装时,您只需perl Makefile.PL(回答是),然后make installdeps

[从我最初给出这个答案开始编辑5年]

这些天perlbrew和cpanm是可以使用的东西。 local :: lib仍然有一个用例,但perlbrew和cpanm的组合解决了这些情况的超集。当你还没准备编译自己的perl时,请使用local :: lib。

答案 6 :(得分:0)

我建议只使用cpan。 Linux发行版中的模块仅用于覆盖包依赖。当你在没有互联网访问的情况下安装只有CD的linux时,它不能使用cpan,因此一些模块作为包包含在内,但对于Perl开发人员而言这是不好的。

此外,我曾经将cpan配置为在我的家中安装模块(.perl),无需root登录。

答案 7 :(得分:0)

生产:

在开发中,选择似乎适合要求的perl模块版本;如果可能的话,选择目标操作系统的发货版本(这使得以下大部分内容都是多余的),否则,选择另一个版本。为它创建RPM规范文件。使用clean build VM以可重现的方式构建RPM(来自在相应分支上签入的specfile / source)。

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

生产中的所有服务器都使用完全相同的二进制文件;他们使用与开发人员预期相同的spec文件和源代码。

Perl模块不会被任何不遵循此模型的进程升级。也没有任何其他制作软件。

答案 8 :(得分:0)

我使用FreeBSD端口并将“元端口”中的所有CPAN依赖关系包装为local port。 FreeBSD拥有相当多的CPAN模块及其build system is approachable enough,如果它们不存在,你可以轻松编写自己的端口 - 只是不要忘记submit said port所以它被包含在ports树中。如果端口没有库存的当前版本,您可以随时编辑端口的Makefile,使其再次使用新版本don't forget to submit the change: - )。

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

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

答案 9 :(得分:0)

我最近开始使用Gentoo,Gentoo在这方面有一些非常重要的优势。第一个是g-cpan通常能够安装CPAN中的许多(尽管不是全部)模块作为Gentoo软件包,但更新会成为一个问题。

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

相关问题