2008-12-29 114 views
29

A recent question在这里让我思考。使用包管理器时,您如何管理Perl模块?

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

一个明显的优点是,只要新版本的软件包可用,就可以更新模块。

但是,当模块不可用于预封装格式并且该模块存在依赖关系时,您会遇到麻烦。每次cpan shell询问它是否应该遵循依赖关系时,打包你的包管理器会非常累人。

通常,另一个缺点是预封装模块的版本。如果您正在运行Debian或Ubuntu,您很快就会发现,您将无法生活在流血的边缘,就像许多CPAN模块作者似乎所做的那样。

Linux上的其他Perl人员如何处理该问题?你只是忽略你的软件包管理者必须提供什么?是否有任何工具可以帮助(例如)和更好的队友?或者你只是不通过cpan外壳安装任何东西?

+0

我已将标题从“如何在Linux上管理Perl模块?到“如何在使用包管理器时管理Perl模块?“,因为这与任何包管理器可能用于安装Perl本身的系统有关,而不是严格的Linux - 例如OSX的macports(http://macports.org)发行版 – Ether 2009-12-29 00:48:01

回答

7

由于本问题最初是询问perlbrew已经发布。它使得安装自定义的,独立的perl安装变得微不足道。而这些版本之间的切换也很简单:

perlbrew switch $version 
12

我们通过CPAN shell安装所有东西。这确实忽略了软件包管理者必须提供的功能,但是它避免了在尝试使用它们时所提到的令人头疼的问题(使用正确版本解决依赖性问题)。

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

+0

是否有自动的方式,在你安装了更新你的perl版本(比如说5.6.1到5.6.2)的操作系统更新之后,升级你安装的所有CPAN模块? – 2008-12-29 18:23:58

+1

哦,不要紧 - 我从对另一个问题的回答中看到, – 2008-12-29 18:25:53

+0

Paul:预计它是兼容的,任何在5.6.1上编译的XS模块都可以在5.6.2上工作,即使在5.6.2到5.61之间也是可以兼容的, – 2009-02-14 00:44:29

0

我建议只使用cpan。在Linux发行版中包含的模块仅包括软件包依赖性。当你只用CD安装没有互联网访问的linux时,它不能使用cpan,因此一些模块被包含在软件包中,但是对于Perl开发者来说这是不好的。

此外,我曾经有一个cpan配置为在我的家庭(.perl)没有根登录需要安装模块。

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-线程)中创建符号链接。当我需要一个特定的版本,我只是用一个我想要的:在特定的二进制确保该方案拿起正确模块搜索路径等(它在配置相同的东西

$ perl5.10.0 program.pl 

。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目录放在某种源代码控制之下。如果我添加一个我不喜欢的模块,我只是退回到以前的版本。我只是开始这样做,并没有玩得太多。

我已经写了更多关于这种事情在有效Perler博客:

+4

太多人在脚下自动拍摄手动回答配置问题请始终推荐相应的开关代替:./Configure -de -Dprefix =/some/path。-Dversiononly也很好 – ysth 2008-12-30 07:50:56

6

我对我所有的箱子下面:

  • 我编译我自己的Perl:我仍然使用5.8。[89]大多数情况下,股票5.10.0的表现回落打击了我很多,等待5.10.1再次尝试;
  • 我使用(并强烈建议)local :: lib模块为每个项目保留一个模块目录。现在,该目录已rsync到所有安装项目的服务器,但我正在使用git进行测试;
  • 我为每个项目创建一个Task ::模块,这样我就可以用一个命令安装所有的依赖项。
6

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

对于我需要debian中没有的Perl模块的情况,我通常会创建自己的debian软件包并安装它。当然,这种方法并非没有问题,因为许多debian perl模块已经过时(至少在当前的debian稳定版本 - etch中),并且backporting像Catalyst这样有很多依赖关系是不切实际的。但是,依靠OS软件包管理器,我保留了它的所有优点,这使得易于维护,尤其是对于已部署的服务器,因为您确切知道安装了哪些软件包,以及简单的apt-get update;apt-get upgrade(来自debian,或来自本地存储库)将所有服务器升级到相同的状态,包括Perl模块。

4

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

你不应该为每个项目需要一个Task ::。只要使用模块::安装(我喜欢用模块::启动这样的:

$ module-starter --mi --module=Module::Name --author="Me" [email protected] 

,然后就弹出你的依赖关系,需要“模块::依赖”;在Makefile.PL。最后,当它的安装时间,你只是perl Makefile.PL(回答是),则make installdeps

[编辑5年的时候我给了这个答案原本]

这些天perlbrew和cpanm是使用的东西。 local :: lib仍然有一个用例,但是perlbrew和cpanm的组合解决了这些情况的一个超集。如果您不准备编译自己的Perl,请使用local :: lib。

0

对于生产:

在发展中,选择一个版本,它似乎是正确的要求进行的Perl模块;如果可能的话选择目标操作系统的发货版本(这使得以下大部分是多余的),否则,选择另一个。为它创建一个RPM spec文件。使用clean build VM以可重现的方式(从相应分支中签入的specfile/source)构建RPM。

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

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

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

0

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

最后,我使用Tinderbox将整个混乱构建为二进制包,然后安装在所有生产和开发机器上。底线 - 一旦你克服了编辑Makefiles的恐惧症,FreeBSD的端口是维护你的perl应用程序及其依赖关系的好方法。

0

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

通常在Gentoo上,我的方法是使用g-cpan创建一个ebuild文件,然后根据需要进行安装,然后进行调整。优点是升级变得非常简单。然后我将文件从g-cpan/perl移动到dev-perl,并将其放在覆盖层中供其他人使用。这使我能够快速处理这些情况下,g-cpan不会和gentoo包装变得轻而易举/