cpanコマンドによるPerlモジュールのローカルインストール

今時Perlを使った開発はあまりない。しかし,既存のソフトウェアがPerlを使っているために,Perlの開発環境が必要になることがある。

Perlのパッケージ管理にはいくつかの方法が存在するようだ。今回はその中でPerl標準コマンドであるcpanコマンドを使ったPerlモジュールのローカルインストール方法をまとめる。

cpanの初回起動時動作

cpanコマンドは,CPANモジュールを使い引数に指定したPerlモジュールをPerlのパッケージリポジトリーのCPAN (The Comprehensive Perl Archive Network) からインストールするコマンドだ。引数に何も指定しなければ,対話シェルが起動し,そこでCPANモジュールの対話コマンドを実行でき,細かい設定などができる。

なお,以下のようにperlからCPANモジュールを使ってインストールする方法もある。

perl -MCPAN -e "install module-name"

結局はcpanコマンドもCPANモジュールを使っているので,やっていることは同じだ。しかし,わざわざ専用のcpanコマンドが存在しており,こちらを使ったほうがわかりやすいので,cpanコマンドだけを使うことにする。

cpanの初回起動時はcpanの設定を行う。まず,cpanの初回起動時設定を確認・把握し,その後のインストール手順を整理する。この節は参考情報であるため,実際に実行する必要はない。

まず,以下のコマンドでcpanを起動できる。

cpan

cpanを引数なしで起動すると,対話シェルが起動し,初回起動時は以下の設定を自動で行うかの質問が表示される。

cpanの雑多な初期設定の質問
Loading internal null logger. Install Log::Log4perl for logging messages
Sorry, we have to rerun the configuration dialog for CPAN.pm due to
some missing parameters. Configuration will be written to
 <</home/senooken/.cpan/CPAN/MyConfig.pm>>


CPAN.pm requires configuration, but most of it can be done automatically.
If you answer 'no' below, you will enter an interactive dialog for each
configuration option instead.

Would you like to configure as much as possible automatically? [yes] 

角括弧 ([]) の中身がデフォルトだ。これはyesでよいので,そのままEnterを入力する。noを選択した場合,ミラーサイトの設定などを行うことになる。

なお,表示されているとおり,cpanの設定は,Ubuntu 16.04 (cpan 1.61, Perl 5.22.1) では~/.cpanディレクトリーに格納される。Ubuntu 18.04 (cpan 1.64, Perl 5.26.1) だと~/.local/share/.cpanだった。

cpan関係の設定で困ったら,最悪これらのディレクトリーを削除すればやり直せる。また,cpanの設定は対話シェルでo conf initコマンドにより再設定できる。

cpanコマンドやcpanの対話シェルでの操作はそれぞれ「cpan – perldoc.perl.org」と「CPAN – perldoc.perl.org」に記載がある。

続いて,インストール方法の質問が表示される。

インストール方法の質問
Use of uninitialized value $what in concatenation (.) or string at /usr/share/perl/5.22/App/Cpan.pm line 633, <STDIN> line 1.
 <install_help>

Warning: You do not have write permission for Perl library directories.

To install modules, you need to configure a local Perl library directory or
escalate your privileges.  CPAN can help you by bootstrapping the local::lib
module or by configuring itself to use 'sudo' (if available).  You may also
resolve this problem manually if you need to customize your setup.

What approach do you want?  (Choose 'local::lib', 'sudo' or 'manual')
 [local::lib] 

ここのデフォルトがlocal::libとなっている。自分の知る限り,Ubuntu
14.04からはすでにcpanでのパッケージ管理にはlocal::libが標準となっているようだ。ここもそのままで問題ない。すると,インターネットからlocal::libのインストールが始まる。

local::libの自動インストールにより,以下のファイル群がインストールされる。

local::libのインストールファイル
Installing /home/senooken/perl5/lib/perl5/lib/core/only.pm
Installing /home/senooken/perl5/lib/perl5/POD2/DE/local/lib.pod
Installing /home/senooken/perl5/lib/perl5/POD2/PT_BR/local/lib.pod
Installing /home/senooken/perl5/lib/perl5/local/lib.pm
Installing /home/senooken/perl5/man/man3/local::lib.3pm
Installing /home/senooken/perl5/man/man3/lib::core::only.3pm
Installing /home/senooken/perl5/man/man3/POD2::DE::local::lib.3pm
Installing /home/senooken/perl5/man/man3/POD2::PT_BR::local::lib.3pm
Appending installation info to /home/senooken/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/perllocal.pod

インストールが終わると,最後に以下の質問が表示される。

local::libの環境変数追記の質問
local::lib is installed. You must now add the following environment variables
to your shell configuration files (or registry, if you are on Windows) and
then restart your command line shell and CPAN before installing modules:

PATH="/home/senooken/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/senooken/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/senooken/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/senooken/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/senooken/perl5"; export PERL_MM_OPT;

Would you like me to append that to /home/senooken/.bashrc now? [yes] 

ここでは,local::libモジュールを~/perl5にインストールしたので,そこへのPATHの設定を~/.bashrcに追記するか質問している。ひとまずデフォルトのyesでよいだろう。この質問が最後だ。

これでcpanの初回起動時設定が完了となる。

cpanの初期設定の問題

cpanの初回起動時設定の動作をひと通り記した。

ここで,cpanの初回起動時設定が全て標準の設定だと問題がある。Perlモジュールのインストール場所が$HOME/perl5となってしまい,勝手にそこにlocal::libモジュールがインストールされてしまうからだ。

stowによるローカルパッケージ管理」に記した通り,他のパッケージとの整合性を取るために,パッケージのローカルインストールは,~/.local配下に行いたい。また,環境を汚したくないので,初回のlocal::lib~/.localにインストールされるようにしたい。

調べたところ,local::libのインストールの質問は以下の2条件が満たされた場合にのみ発生する。

cpanコマンド実行時のlocal::libのインストールの質問の発生条件
  1. .cpanディレクトリーの不在
  2. PERL_MM_OPT環境変数の未定義

そこで,local::libで使用する変数を利用し,cpanの初期設定を工夫する。

cpanの推奨設定とインストール手順

まず,事前に以下の環境変数を設定して,~/.profile~/.bashrcにも記載しておく。

cpanの推奨初期設定
export LOCAL="$HOME/.local"
export PATH="$LOCAL/bin${PATH+:$PATH}"
export PERL_LOCAL_LIB_ROOT="$LOCAL${PERL_LOCAL_LIB_ROOT+:PERL_LOCAL_LIB_ROOT}"
export PERL5LIB="$LOCAL/lib/perl5${PERL5LIB+:$PERL5LIB}"
export PERL_MB_OPT="--install_base '$LOCAL'"
export PERL_MM_OPT="INSTALL_BASE=$LOCAL"

その後,以下のコマンドでlocal::libモジュールをインストールする。

echo | cpan local::lib

上記コマンドにより,local::libモジュールが~/.localにインストールされる。なお,cpan初回起動時の質問を回答するために,echoコマンドで標準入力を渡している。

local::libのインストール後は,cpanでインストールするPerlモジュールも~/.localにインストールされる。上記のLOCAL環境変数を変更すれば,任意のディレクトリーにPerlモジュールをcpanでインストール可能だ。

例えば,GNU Stowでmake checkに必要なIO::ScalarモジュールとTest::Outputモジュールは以下のコマンドでインストールできる。

cpan IO::Scalar Test::Output

これでcpanによるPerlのローカルインストールが可能となる。

モジュールのアンインストール

cpanでインストールしたモジュールのアンインストール方法はやや手間がかかる。

以下の回答の通り,cpanは基本的にMakefileを使ってインストールするため,ビルドディレクトリーでmake uninstallによりアンインストールする。

もしcpanコマンド使ってであるとすると、それは実際にはMakefileでのコンパイル&installになります。
で。
make install系の、これは最大の欠点といわれているのですが。「自力で手動で探し出す以外に削除手段はない」です。
# rpm系の唯一にして最大の利点がココの部分の解消ですね。

cpanでのinstallですと、どこか(多分 /root あたり)に.cpan/build/というディレクトリがありまして、その下にソースが展開されているので。
ソースはそこから。.soファイルは…Makefile解析するか、findあたりで探すか、で削除するしかないです。

CPANでインストールしたモジュールの削除方法 -CPANであるモジュールを- ネットワーク | 教えて!goo

~/.cpan/build~/.local/share/.cpan/buildに,cpanでのインストール時のビルドディレクトリーが存在する (例: Test-Output-1.031-ovRQ3A)。アンインストール対象のパッケージのビルドディレクトリーにcdコマンドで移動し,以下のコマンドを実行することでアンインストールを実現する。

make uninstall SITEARCHEXP="$LOCAL/lib/perl5/x86_64-linux-gnu-thread-multi"

ここでは,Makefile内のSITEARCHEXP変数を引数で上書きしている。Makefile内ではここが/usr/local/lib/perl5/x86_64-linux-gnu/perl/5.22.1などになっている。make uninstall時に,ここに格納されているファイルをアンインストールしようとして,ファイルが存在しないために以下のエラーが出ていたため,上書きした。

make uninstall時のエラー
Uninstall is unsafe and deprecated, the uninstallation was not performed.
We will show what would have been done.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: no packlist file found: '/usr/local/lib/x86_64-linux-gnu/perl/5.22.1/auto/Test/Output/.packlist' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Makefile:790: recipe for target 'uninstall_from_sitedirs' failed make: *** [uninstall_from_sitedirs] Error 2

なお,buildディレクトリーにパッケージのディレクトリーが存在しない場合,再度cpanで該当パッケージをインストールして,パッケージディレクトリーを用意して対応する。

また,Module::Buildを使っているパッケージなどはこの方法ではアンインストールできない。cpanでインストールしたモジュールのアンインストールはやっかいな問題だ。cpanminusパッケージなどをインストールして対応すればよさそうだ。気が向いたら,cpanモジュールのアンインストール方法だけ別の記事にまとめる。

local::libの環境変数

最後にlocal::libで使用している環境変数をまとめる。

local::libの参照環境変数
環境変数 説明
PATH コマンドのパス (:区切り)。
PERL5LIB Perlの@INCの対象パスのリスト (:区切り)。
PERL_LOCAL_LIB_ROOT local::libの有効なパスのリスト (:区切り)。
PERL_MB_OPT ExtUtils::MakeMakerのPREFIXを上書き。
PERL_MM_OPT Module::Buildの–prefixオプションを上書き。

これらの環境変数は以下のサイトで説明されている。

PERL_MM_OPTとPERL_MM_OPTはそれぞれExtUtils::MakeMakerとModule::Buildと競合するのでインストール時に問題が発生した場合に注意する。

  • Conflicts with ExtUtils::MakeMaker‘s PREFIX option. local::lib uses the INSTALL_BASE option, as it has more predictable and sane behavior. If something attempts to use the PREFIX option when running a Makefile.PL, ExtUtils::MakeMaker will refuse to run, as the two options conflict. This can be worked around by temporarily unsetting the PERL_MM_OPT environment variable.

  • Conflicts with Module::Build‘s --prefix option. Similar to the previous limitation, but any --prefix option specified will be ignored. This can be worked around by temporarily unsetting the PERL_MB_OPT environment variable.

LIMITATIONS | local::lib – create and use a local lib/ for perl modules with PERL5LIB – metacpan.org
まとめ

cpanによるPerlモジュールのローカルインストール方法を記した。これで新しくPerlモジュールが必要になっても,cpanでローカルにインストールして解決できるだろう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です