打包一个perl应用程序,使其可以在perl的默认前缀之外运行 [英] Packaging a perl app so that it will work outside of perl's default prefix

查看:101
本文介绍了打包一个perl应用程序,使其可以在perl的默认前缀之外运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Module :: Build(尽管我在构建环境上很灵活)来打包一些我正在编写的perl软件,以供我在内部工作使用.它包括一些脚本和一些帮助程序模块.我的计划是这样做,以便您可以在构建过程中指定所需的前缀(即,超出perl默认@INC的内容),并且构建的脚本应该仍然能够找到其帮助程序模块而没有任何问题. /p>

我要这样做是因为我想使用"Encap"在内部分发此软件,"Encap"是一种打包工具,默认情况下不能 在/usr/local之外安装任何东西,并且处于RedHat,默认情况下,我们的perl不会在/usr/local/lib中搜索模块.

这使我有一个希望告诉用户每次想要运行该应用程序时都将PERL5LIB手动设置为/usr/local/lib的方法,或者对构建系统进行一些智能化的处理在--prefix之后指定了每个脚本的use lib行.

现在,我只是将use lib设置为在每个脚本中手动直接指向/usr/local/lib,但是我并不是很喜欢将其作为解决方案.主要是因为测试过程:我想在测试过程中覆盖@INC,以便它首先将我的工作目录用于perl模块,但是在构建之后,应从@INC中删除该工作目录,并用用户指定的前缀替换.也是因为我希望将此软件安装到任意位置(例如在NFS上具有自己的bin/和lib/dirs的自己的小岛上),并且仍然可以正常工作.

问题:

Module :: Build是否可以在构建步骤中摆弄脚本的use lib行?我注意到MakeMaker有一个pm_filter选项,该选项使您可以指定一个搜索和替换项,该文件可以在构建.pm文件时任意修改它们,但仅适用于.pm文件,而不适用于脚本. Module :: Build应该更灵活,但是我淹没在文档中试图找出您要在哪里指定.

解决方案

>>> daxim@champion:/tmp/Foo-Bar$ tree
.
├── bin
│   └── foobar
├── Build.PL
├── inc
│   └── Local
│       └── Module
│           └── Build
│               └── Fnord.pm
└── lib
    └── Foo
        └── Bar.pm

7 directories, 4 files

>>> daxim@champion:/tmp/Foo-Bar$ cat bin/foobar
use lib "DUMMY";
use Foo::Bar;
print "It works!\n";

>>> daxim@champion:/tmp/Foo-Bar$ cat Build.PL
use lib 'inc';
use Local::Module::Build::Fnord;

my $build = Local::Module::Build::Fnord->new(
    module_name => 'Foo::Bar',
    license     => 'restricted',
);
$build->add_build_element('bin');
$build->create_build_script;

>>> daxim@champion:/tmp/Foo-Bar$ cat inc/Local/Module/Build/Fnord.pm
package Local::Module::Build::Fnord;
use parent 'Module::Build';
sub process_bin_files {
    my ($self) = @_;
    my $lib = $self->install_base . '/lib/perl5';
    system "chmod u+w blib/script/*";
    my $call = qq($^X -p -i -e's[use lib "DUMMY";][use lib "$lib";]' blib/script/*);
    print "$call\n";
    system $call;
};
1;

>>> daxim@champion:/tmp/Foo-Bar$ cat lib/Foo/Bar.pm
package Foo::Bar;
1;

>>> daxim@champion:/tmp/Foo-Bar$ perl Build.PL --install_base=/tmp/usr/local
⋮

>>> daxim@champion:/tmp/Foo-Bar$ ./Build install
Building Foo-Bar
/home/daxim/local/bin/perl -p -i -e's[use lib "DUMMY";][use lib "/tmp/usr/local/lib/perl5";]' blib/script/*
Installing /tmp/usr/local/lib/perl5/Foo/Bar.pm
Installing /tmp/usr/local/bin/foobar

>>> daxim@champion:/tmp/Foo-Bar$ cat blib/script/foobar
use lib "/tmp/usr/local/lib/perl5";
use Foo::Bar;
print "It works!\n";

>>> daxim@champion:/tmp/Foo-Bar$ cd /tmp/usr/local/bin/

>>> daxim@champion:/tmp/usr/local/bin$ perl foobar
It works!

I'm using Module::Build (although I'm flexible on build environments) to package up some perl software I'm writing for internal use where I work. It includes a handful of scripts, and some helper modules. My plan is to make it so you can specify a prefix of whatever you want (ie. something outside of perl's default @INC) during the build process and the built scripts should still be able to find their helper modules without any problems.

I want to do this because I want to distribute this software internally with "Encap", which is a packaging tool that by default can not install anything outside of /usr/local, and being on RedHat, our perl does not search /usr/local/lib for modules by default.

This leaves me with the prospect of either telling the user to manually set PERL5LIB to /usr/local/lib every time they want to run the app, or to do something intelligent with the build system to have it fiddle with each script's use lib line after a --prefix is specified.

Right now I'm just setting use lib to point straight to /usr/local/lib manually in each of my scripts, but I'm not really liking that as a solution. Chiefly because of the testing process: I want to override @INC during testing so that it uses my working directory first for perl modules, but upon being built, the working directory should be removed from @INC and replaced with the user's specified prefix. But also because I would like this software to be installed to arbitrary locations (such as its own little island somewhere on NFS with its own bin/ and lib/ dirs) and still work without issue.

The question:

Can Module::Build allow me to fiddle with my scripts' use lib lines during build steps? I notice MakeMaker has a pm_filter option that lets you specify a search-and-replace that can arbitrarily modify your .pm files as they're being built, but that only works with .pm files, not scripts. Module::Build is supposed to be more flexible but I'm drowning in the documentation trying to figure out where you'd specify that.

解决方案

>>> daxim@champion:/tmp/Foo-Bar$ tree
.
├── bin
│   └── foobar
├── Build.PL
├── inc
│   └── Local
│       └── Module
│           └── Build
│               └── Fnord.pm
└── lib
    └── Foo
        └── Bar.pm

7 directories, 4 files

>>> daxim@champion:/tmp/Foo-Bar$ cat bin/foobar
use lib "DUMMY";
use Foo::Bar;
print "It works!\n";

>>> daxim@champion:/tmp/Foo-Bar$ cat Build.PL
use lib 'inc';
use Local::Module::Build::Fnord;

my $build = Local::Module::Build::Fnord->new(
    module_name => 'Foo::Bar',
    license     => 'restricted',
);
$build->add_build_element('bin');
$build->create_build_script;

>>> daxim@champion:/tmp/Foo-Bar$ cat inc/Local/Module/Build/Fnord.pm
package Local::Module::Build::Fnord;
use parent 'Module::Build';
sub process_bin_files {
    my ($self) = @_;
    my $lib = $self->install_base . '/lib/perl5';
    system "chmod u+w blib/script/*";
    my $call = qq($^X -p -i -e's[use lib "DUMMY";][use lib "$lib";]' blib/script/*);
    print "$call\n";
    system $call;
};
1;

>>> daxim@champion:/tmp/Foo-Bar$ cat lib/Foo/Bar.pm
package Foo::Bar;
1;

>>> daxim@champion:/tmp/Foo-Bar$ perl Build.PL --install_base=/tmp/usr/local
⋮

>>> daxim@champion:/tmp/Foo-Bar$ ./Build install
Building Foo-Bar
/home/daxim/local/bin/perl -p -i -e's[use lib "DUMMY";][use lib "/tmp/usr/local/lib/perl5";]' blib/script/*
Installing /tmp/usr/local/lib/perl5/Foo/Bar.pm
Installing /tmp/usr/local/bin/foobar

>>> daxim@champion:/tmp/Foo-Bar$ cat blib/script/foobar
use lib "/tmp/usr/local/lib/perl5";
use Foo::Bar;
print "It works!\n";

>>> daxim@champion:/tmp/Foo-Bar$ cd /tmp/usr/local/bin/

>>> daxim@champion:/tmp/usr/local/bin$ perl foobar
It works!

这篇关于打包一个perl应用程序,使其可以在perl的默认前缀之外运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆