1. ホーム
  2. スクリプト・コラム
  3. パール

Perl モジュールをパッケージ化し、外部依存性を追加する

2022-01-30 04:09:03

PerlコミュニティーのすべてがCPANで公開されているわけではありません。Module::ThirdPartyモジュールもあり、これらの非CPANのPerlプロジェクトのリストを保持しています。最もよく知られているのは、ブログ用のMovable Typeとモニタリング用のSmokePingです。

しかし、簡単に展開できるようにsmokepingをパッケージ化したい場合、小さな問題が見つかります:rpmとしてパッケージ化すると、Perl依存モジュールの多くがシステムレポに存在しないかもしれません。Perlモジュールとしてパッケージ化すると、fping、curlなどのsmokepingの最も一般的なプローブが非perlプログラムであり、cpanmではこのrequest_external_binを解決できず、せいぜいエラーを報告して終了するしかないのです。

他の方法もあり、それは少し間抜けですが、問題は解決します。

まず、とにかくサンプルモジュールを作ってみましょう。

コピーコード コードは以下の通りです。

    cpanm Module::Starter Module::Build
    module-starter --module Alien::FPing --author="Jeff Rao" --email="[email protected]" --mb

そして、このディレクトリの中にAlien-FPingディレクトリが作成され、Build.PLなどの独自の良いモジュールファイルが作成されます。Alien:: 名前空間は微妙なルールとしてここで使われています。Cソースライブラリやヘッダに依存するいくつかのプロジェクトはPerlパッケージレイヤーでインストールされ、この空間の下に置かれます。例えば、Alien::V8, Alien::Gearmand, Alien::IE7 などです。

では、fpingのソースコードをダウンロードし、モジュールに入れましょう。

コピーコード コードは以下の通りです。

mkdir Alien-FPing/src
    wget http://www.fping.org/dist/fping-3.4.tar.gz -O Alien-FPing/src/fping-3.4.tar.gz

次はBuild.PLを書くべきでしょう。しかし、Build.PLをできるだけきれいに見せ、一目で目的がわかるようにすることです。ビルド操作が使用するモジュールは別に定義した方がよいでしょう。

コピーコード コードは以下の通りです。

 package Alien::FPing::Build;
    use base qw(Module::Build);
    use File::Spec;
    use Archive::Tar;
    my $RootDir = File::Spec->rel2abs(". ");
    my $SrcDir = File::Spec->catdir($RootDir, "src");
    my $FPingVersion = '3.4';
    my $FPingName = "fping-${FPingVersion}";
    my $FPingSrc = "${FPingName}.tar.gz";
    sub ACTION_build {
        my $self = shift;
        chdir($SrcDir);
        if ( ! -x "/usr/sbin/fping" and ! -d $FPingName ) {
            my $tar = Archive::Tar->new();
            $tar->read($FPingSrc);
            $tar->extract();
            chdir($FPingName);
            system('. /configure', '--prefix=/usr/', '--enable-ipv6');
            system('make');
            system('make install');
        }
        $self->SUPER::ACTION_build();
    };
    1;

これは、Module::Buildがサブクラス用に定義したメソッドで、実際には.NETで見られるすべてのアクションが含まれます。/Buildヘルプで見ることができるすべてのアクションに同様のメソッドがあります。

次に、Build.PLを以下のように少し修正します。

コピーコード コードは以下の通りです。

use 5.006;
    use strict;
    use warnings FATAL => 'all';
    use lib 'inc';
    use Alien::FPing::Build;
    my $builder = Alien::FPing::Build->new(
        module_name => 'Alien::FPing',
        license => 'perl',
        dist_author => q{Jeff Rao <[email protected]>},
        dist_version_from => 'lib/Alien/FPing.pm',
        release_status => 'stable',
        configure_requires => {
            'Module::Build' => 0,
        },
        build_requires => {
            'Test::More' => 0,
        },
        requires => {
            #'ABC' => 1.6,
            #'Foo::Bar::Module' => 5.0401,
        },
        add_to_cleanup => [ 'Alien-FPing-*' ],
        create_makefile_pl => 'traditional',
    );
    $builder->create_build_script();

Module::Build を Alien::FPing::Build に置き換えて、他はそのままにします。

では、試してみてください。

コピーコード コードは以下の通りです。

cd Alien-FPing
    perl Build.PL
    . /Build

コンパイルされた出力と、/usr/sbin/fpingでインストールが成功したのをご覧ください。これでパッケージ化できました。なお、デフォルトで生成される ignore.txt は inc ディレクトリを除外しているので、これを削除して MANIFEST ファイルを修正し、 inc と src のファイルを含めるようにしてから、Perl モジュールを直接使用できるようにパッケージングする必要があります。

コピーコード コードは以下の通りです。

sed -i '/inc/d' ignore.txt
    echo 'inc/Alien/FPing/Build.pm' >> MANIFEST
    echo 'src/fping-3.4.tar.gz' >> MANIFEST
    . /Build dist