nDiki : ExtUtils::MakeMaker

ExtUtils::MakeMaker

インストール先

以下、環境によっては違うかも。

Perl 5.005_03の場合

(ExtUtils::MakeMaker 5.4302)

サイトインストール(INSTALLDIRS=site)の場合

アーキテクチャ依存ファイルINSTALLSITEARCH$(LIB)/$arcname
pm 等INSTALLSITELIB$(LIB)
実行可能ファイルINSTALLBIN$(PREFIX)/bin
スクリプトINSTALLSCRIPT$(PREFIX)/bin
man1INSTALLMAN1DIR
man3INSTALLMAN3DIR
perllocal.pod$(INSTALLARCHLIB)

Makefile.PL の PREFIXパラメータだけでは bin 以下のものしか変更されない。 ユーザ権限でホームディレクトリ等にインストールする場合は、PREFIX, LIB, INSTALLMAN1DIR, INSTALLMAN3DIR を指定しておく。

perllocal.pod は $(INSTALLARCHLIB)の下へ追記される。 perllocal.pod への追記の必要がなければ、make install のかわりに、make pure_install する。

Perl 5.6.1 の場合

サイトインストール(INSTALLDIRS=site)の場合

アーキテクチャ依存ファイルINSTALLSITEARCH$(SITEPREFIX)/lib/perl/5.6.1 または $(LIB)/arcname
pm 等INSTALLSITELIB$(SITEPREFIX)/share/perl/5.6.1 または $(LIB)/$
HTMLINSTALLHTMLSITELIBDIR?
HTMLスクリプトINSTALLHTMLSCRIPTDIR?
実行可能ファイルINSTALLBIN$(PREFIX)/bin
スクリプトINSTALLSCRIPT$(PREFIX)/bin
man1INSTALLMAN1DIR$(PREFIX)/share/man/man1
man3INSTALLMAN3DIR$(PREFIX)/share/man/man3
(man1)INSTALLSITEMAN1DIR$(SITEPREFIX)/man/man1
(man3)INSTALLSITEMAN3DIR$(SITEPREFIX)/man/man3
perllocal.pod$(INSTALLARCHLIB)

Makefile.PL の SITEPREFIX と PREFIX を指定する。モジュールのディレクトリを直接指定するなら LIB も使用する。

perllocal.pod は $(INSTALLARCHLIB)の下へ追記される。

Perl 5.8.0 の場合

サイトインストール(INSTALLDIRS=site)の場合

アーキテクチャ依存ファイルINSTALLSITEARCH$(SITEPREFIX)/lib/perl/5.8.0 または $(LIB)
pm 等INSTALLSITELIB$(SITEPREFIX)/share/perl/5.8.0 または $(LIB)/$arcname
実行可能ファイルINSTALLSITEBIN$(SITEPREFIX)/bin
スクリプトINSTALLSCRIPT$(PREFIX)/bin
man1INSTALLSITEMAN1DIR$(SITEPREFIX)/man/man3
man3INSTALLSITEMAN3DIR$(SITEPREFIX)/man/man3
perllocal.pod$(INSTALLARCHLIB)

Makefile.PL の SITEPREFIX でほとんどまとめて指定できる。 INSTALLSCRIPT だけは PREFIX を使用するので、必要があれば指定する。

モジュールのディレクトリを直接指定するなら LIB も使用する。

perllocal.pod は $(INSTALLARCHLIB)の下へ追記される。 perllocal.pod への追記の必要がなければ、make install のかわりに、make pure_install する。

INSTALLDIRS

CGI.pm 等はデフォルトで 'perl' が指定してある。 ホーム以下にインストールするには INSTALLDIRS=site を指定する。

PERL_LIB

例えば File::Spec の最新版をローカルにインストール。 ここで最新の File::Spec を使う File::Temp をインストールするのに PERL5LIB にローカルディレクトリを指定しても、make test では標準ライブラリのディレクトリが -Iオプションで指定されるので、古い版が優先的に使用されテストに失敗してしまう。

この場合 PERL_LIB をでローカルのディレクトリを指定すればとりあえずだませる。

verbose

Makefile.PL

 $ExtUtils::MakeMaker::Verbose = 2;

としておくと 'perl Makefile.PL verbose' より詳細なメッセージが得られる。

2004年1月23日 (金)

[ WiKicker ] eval "use ..."

Devel::SizeDevel::Cycle を埋め込むもののメモリを喰ってそうなところがなかなか見つからず。

デバッグ用コードを書いたり消したりも面倒なので、ビルド時に WIKICKER_DEBUG=1 を指定しておいた時だけ、ExtUtils::MakeMaker の PM_FILTER を使ってソース中の、

 #IFDEBUG: <デバッグコード>

が有効になるようにしておく。

メモリ消費の方だが以前より攻撃的に eval "use ..." で必要な時だけモジュールをロードするように修正。 常にロードしてあった Jcode も必要な時だけに。 これで少しは減ってくれるかな?

[ 1月23日全て ]

2004年6月3日 (木)

Perlプログラムのコードカバレッジ解析

真実32 充分テストをしたとプログラマが自信を持つソフトウェアでも、全パスの50〜60%程度しか網羅していない。 パス・カバレージ・アナライザのような自動化ツールを使うと、網羅率が85〜90%に上がる。しかし、100%のパスを網羅するのは不可能だ。

真実34 ツールを使わないと、不良除去はうまくいかない。デバッガはみんな使うが、カバレージ・アナライザは、ほとんど使わない。

ソフトウエア開発 55の真実と10のウソより。

ということで、Perl 用のカバレッジ分析ツールを探してみる。 CPAN にある Devel::Cover が良さそげ。

Debian BOX にインストール

 apt-get install libtest-differences-perl \
                 libpod-coverage-perl \
                 libtemplate-perl

してから Devel::Cover をインストール

 dh-make-perl --cpan Devel::Cover --build
 dpkg --install libdevel-cover-perl_0.45-1_i386.deb

WiKickerコードカバレッジをチェックしてみる。

WiKickerExtUtils::MakeMaker を使ってパッケージ化しており、テストは t/*.t を使用するようになっているので、そのまま分析をする事ができる。

 perl Makefile.PL
 make
 cover -delete
 HARNESS_PERL_SWITCHES=-MDevel::Cover make test
 cover

出力はこんな感じ

 Reading database from /path/WiKicker/source/cover_db


 ---------------------------- ------ ------ ------ ------ ------ ------ ------
 File                           stmt branch   cond    sub    pod   time  total
 ---------------------------- ------ ------ ------ ------ ------ ------ ------
 blib/lib/WiKicker.pm          100.0    n/a    n/a  100.0    n/a    0.0  100.0
 ...cker/App/Configuration.pm   44.1    0.0    n/a   62.5    n/a    0.0   41.7
 ...icker/App/MarkUpAsHtml.pm   38.1    0.0    0.0   66.7    n/a    0.0   34.8
 ...CGI/AbstractController.pm   24.8    0.0    n/a   47.4    n/a    0.0   23.6
 [snip]
 ...ageHtmlFragmentVisitor.pm  100.0    n/a    n/a  100.0    n/a    0.0  100.0
 ...icker/WikiPage/WriNode.pm   96.4   83.3    n/a   88.9    n/a    0.9   93.0
 .../tDiaryFragmentVisitor.pm   32.3    0.0    n/a   33.3    n/a    0.0   29.8
 Total                          59.2   41.3   31.4   67.5  100.0  100.0   56.7
 ---------------------------- ------ ------ ------ ------ ------ ------ ------


 Writing HTML output to /path/WiKicker/source/cover_db/coverage.html ...
 done.

cover_db/coverage.html に各モジュール毎のコードカバレッジが表示される。 また、各モジュールファイル毎のレポートもHTMLで作成され、プログラムの各行毎のカバレッジがプログラムとともに表示される。

なかなかいい感じ。さすがにパスカバレッジはサポートしていない。

コードカバレッジを上げてもバグ0にはなるとは全然言えないのは承知しているが、テスト漏れを減らすための情報として結構使えそうだ。

[ 6月3日全て ]

2004年6月4日 (金)

Devel::CoverAutoLoader

[ Perl ]

コードカバレッジをチェックするDevel::Coverであるが、AutoSplit / AutoLoader を使っていると分割されたサブルーチンが対象にならない。WiKicker では AutoLoader を多用しているので、ここがチェックされないと意味がない。

ということで Devel::Cover下でテストする時は AutoLoader を使わないようしてみる。

 perl Makefile.PL WIKICKER_NO_AUTOLOAD=1

とした時はExtUtils::MakeMaker::WriteMakefile に PM_FILTER として

 q($(PERL) -e "while (<>) {s!^\\\\s*use\\\\s+AutoLoader.*!!g; s!^__END__!!g; print} print qq(\\n1;\\n); ")

を渡すように Makefile.PL を修正。これで

 perl Makefile.PL WIKICKER_NO_AUTOLOAD=1
 make
 cover -delete
 HARNESS_PERL_SWITCHES=-MDevel::Cover make test
 cover

とすると AutoLoader を使わないバージョンでチェックができる。

[ 6月4日全て ]

2004年11月25日 (木)

nmake で毎回 pl2bat されるのを何とかしたい

EXE_FILES でインストールするスクリプトを指定してある Makefile.PLActivePerl 上で実行して nmake をかける。 また nmake する。

するとソースを書き換えてないにもかかわらず、EXE_FILES指定ファイルの blib/script へのコピーと pl2bat の実行が行われる。 嫌な感じ。

追いかけてみると

  • UNIX上の場合 FIXIN *1blib/script にコピーされたスクリプトを上書きするため更新時刻が変更され、次の make では最新と判断される。
  • Windows上の場合 FIXIN *2blib/script にコピーされたスクリプトからバッチファイルを生成する。このためコピーされたファイルの更新時刻は、ソースと同じのまま。依存関係で指定されている Makefile の方が新しいので次の nmake でも同じ処理が繰り返される。

というわけ。コピーした後 touch するようにすればよい。

 perl -MExtUtils::Command -e touch %1
 pl2bat %1

という内容の touchpl2bat.bat を作って

 nmake FIXIN=touchpl2bat

とすればきちんと更新時刻が反映されビルドは1回だけになる。 毎回指定するのは面倒なので、MSWin32 なら自動的にそうするようにパッケージングしたいのだが nmake で他にうまく FIXIN を上書きする方法がみつからず (MY::postamble で書き出しても、WriteMakefile(macro => {FIXIN => 'touchpl2bat'}, ...) しても駄目)。


[ ExtUtils::MakeMaker ]

*1= perl -MExtUtils::MY -e "MY->fixin(shift)"

*2= pl2bat

[ 11月25日全て ]

2005年4月20日 (水)

SConsGNU Autotools のかわりになるか

NSIS のサイトによるとビルドに「SCons」を使うようしたらしい。

  • クロスプラットフォーム
  • AutoconfAutomake と同様の機能を統合
  • LaTeX もビルトインサポート

と興味深いツールになっているようだ。

現在プロジェクトLaTeXベースのドキュメント生成には GNU Make を使っているのだが、UNIXWindows の両方でビルドできるようにするには ComSpec 環境変数の有無で使用するコマンドを切り換えたり等いろいろ面倒なので、代替ツールとして使えないかなと。

基本的な機能は Make に対する改良がなされているようであるし、コピー等ファイル操作も SCons 自体がもっているのでクロスプラットフォームでビルドできるようにするのも楽そうだ。

一方 Autoconf 系の機能については、インストール済みのライブラリの検出や実装レベルのチェック等を実装しているようである。 make check や make dist、make install 等にあたるターゲットに関する機能(あるいは規約)のようなものは無い。これは非常に残念。 結局自分が Ant を使わなくなったのも GNU Autotools にあるこれらの機能に欠けているからであるし。

実は私がPerl が好きな理由の一つとして、これらサポートが充実しているという点がある。Perl では ExtUtils::MakeMaker (あるいは Module::Build)があり、ビルドからテスト、ソースパッケージのパッケージングまでフレームワークが整っている。

SConsPython ベースで、Makefile にあたるファイルも Python スクリプトである。 SCons が影響を受けた Cons は Perl ベースであったのだが、既に2001年5月ごろから開発が止まってしまっている。残念。

ということで Make の代替には使えそうであるが、GNU Autotools と同じようなことをするにはいろいろ手をかけないといけないといった印象。

[ 4月20日全て ]

2005年8月24日 (水)

Module::Buildソースパッケージング

ExtUtils::MakeMaker

私が Perl が好きな理由の一つに、標準でExtUtils::MakeMakerという Makefile ジェネレータがついているところである。これを使って Makefile.PL を書くと

 perl Makefile.PL
 make manifest
 make
 make test
 make dist

で <pacakge>-<versionno>.tar.gz というソースパッケージを作ることができ、

 tar zxvf <pacakge>-<versionno>.tar.gz
 cd <pacakge>-<versionno>
 perl Makefile.PL
 make
 make test
 make install

という手順でインストールする事ができるようになる。 パッケージの作り方が確立されているので、容易に新しいパッケージを開発しはじめられる。

逆に Java でプログラムを書くのが億劫なのは、このあたりの準備が面倒だからである。 Ant を使っても結局ここら辺自分でやらなければならないし。

ちょっとしたアーカイブの作成

ちょっとしたパッケージを作りたいと思うことは良くある。 例えばいくつかのデータファイルと、READMEファイルなんかをひとまとめにしてアーカイブにするとか。

本当にちょっとしたであれば、手動でアーカイブすれば良いのだが、

  • アーカイブしたいファイル群がバージョン管理下にあって、CVS ディレクトリや .svn ディレクトリがある (除外してアーカイブする必要がある)
  • 同じディレクトリにある、作業用のファイルはアーカイブしたくない (除外してアーカイブする必要がある)
  • アーカイブする前に、チェック用のリグレッションテスト一式を走らせたい (リグレッションテストをかけられるようにする)
  • UNIX でも Windows でもアーカイブ化できるようにしたい。

あたりを考慮しなければならない時は面倒くさくなってくる。

自動化としては

あたりがぱっと思い浮かぶ。 しかし、最初の2つは毎回同じようなものを書くのが面倒だし保守もしにくい。 GNU Autotools はちょっとごっつすぎだし、Windows での環境構築も面倒。

ExtUtils::MakeMaker の欠点

ということで最初は ExtUtils::MakeMaker を使うという線で考えてみた。 もともと Perl モジュール用で汎用用途にはちょっと邪魔な振舞いもあるが、使えないことはないと思う。 しかし make (GNU Make あるいは nmake など) に依存しているという欠点がある。

Module::Build

ということで ExtUtils::MakeMaker の代替である Module::Build ベースで汎用用途に使えないか検討してみた。こちらは pure Perl で make を必要としない。

Module::BuildPerl モジュールビルドにあわせた振舞いがあるものの、ちょっとカスタマイズすれば使えそうだ。 で、いろいろいじった結果、次のような感じにすると使いやすそうだ。

 use Module::Build;
 my $class = Module::Build
   ->subclass(class => 'NonmoduleBuilder',
              code => q{
                        # Don't make blib
                        sub ACTION_code {};
                        # Don't make blib
                        sub ACTION_docs {};
                        # Don't make META.yml
                        sub ACTION_distmeta {
                          # no warning on ACTION_distdir
                          $_[0]->{metafile} = 'MANIFEST';
                        };
                        # Don't add MEATA.yml to MANIFEST
                        sub ACTION_manifest {
                          $_[0]->{metafile} = 'MANIFEST',
                          $_[0]->SUPER::ACTION_manifest(@_);
                        };
                       });

 # Set your archive name and version.
 $class->new(dist_name => 'mypackage',
             dist_version => '1.0.2',
             )->create_build_script;

カスタマイズした部分は以下(Module::Build 0.26 で動作確認)。

  • Perl モジュールビルドに特有の blib ディレクトリを作らないようにする。
  • META.yml を生成しないようにし、アーカイブに含まれないようにする。

上記のようなファイルを Build.PL という名前で作っておけば

 perl Build.PL
 ./Build manifest
 ./Build
 ./Build test
 ./Build dist

等として、アーカイブ作成が容易にできるようになる。

しばらくこの方法でいろいろ試してみることにしてみよう。

[ 8月24日全て ]

2006年2月10日 (金)

WiKickerMakefile.PLModule::Install ベースに

WiKicker には依存している Perl モジュールとして、必須なものとオプションなものがある。 必須なものは例えば Log::Log4perl など。 一方 Cache::MemcachedHTML::Scrubber などは、追加機能を使用したい場合のみ必要である。

一般的な Perl モジュールパッケージと同様、WiKicker では Makefile.PLExtUtils::MakeMaker を使っている。 必須な依存 Perl モジュールは PREREQ_PM に指定してあるが、オプションのものについては独自にチェックして警告をするにとどめていた。 しかしこれだと、オプションのものは CPAN.pm を使って自動的にインストールすることができない。

ということで検討した結果、Module::Install を用いることにした。 Module::Install を用いて Makefile.PL を作成すると、

  • 依存モジュールを、それぞれ必須のもの・ビルドのみ時に必要なもの・推奨のものと分けて処理できる。
  • Makefile.PL 実行時に、未インストールの依存モジュールを CPAN からインストールできる。
  • 依存モジュールを feature 別にまとめて、ビルド時に未インストールのものをインストールするか対話的に選択できる。

などの機能が使えるようになる。

Module::Install の実行に必要なファイルはパッケージの inc ディレクトリ以下に自動的にコピーされ配布パッケージに含められるので、インストールする側はそのために余分なインストールを強いられることもない。

最終的に内部で ExtUtils::MakeMaker を使っているので、それの機能はほぼ全て使える。

Perl のバージョンも 5.004 から使えるとのことで、Perl 5.005_03 以上を対象としている WiKicker で使っても問題なし。

ということで、Makefile.PL をさらっと書き換え。

合わせて WiKicker に含まれていた実験的な機能を削除して、(オプションな)依存モジュールも減らすことにした。

次回のリリース版から、Module::Install ベースだ。

[ 2月10日全て ]

2006年4月29日 (土)

最新の Module::InstallPerl 5.005_03 ステ?

ゴールデンウィークに突入。 9連休を利用して、一気に WiKicker コーディングを企んでいる。

さっそくちょこちょこ修正してパッケージングし、www.naney.org へインストール。 …… Perl Makefile.PL でコケる。

どうも use inc::Module::Install; でエラーを起してしまっているようだ。 Makefile.PL は変更していないので、そうすると Module::Install の問題っぽい。

tarball をパッケージングするホスト側の Module::Install を 0.57 まで落としたところ、Perl 5.005_03 でも通るようになった。

Module::Install is a package for writing installers for CPAN (or CPAN-like) distributions that are clean, simple, minimalist, act in a strictly correct manner with both the ExtUtils::MakeMaker and Module::Build build systems, and will run on any Perl installation version 5.004 or newer. (Module::Install 0.61 より)

とあるように古い Perl もサポートにも気を払っているのが気にいって ExtUtils::MakeMaker から移行しただけにちょっと残念。

今後また 5.005_03 でも動くようになるのか、それとも捨てられるのか要チェック。

[ 4月29日全て ]

2007年7月31日 (火)

Windows 向けソフトウェア開発者はソースパッケージを作る習慣がない

GNU AutotoolsExtUtils::MakeMaker (とその仲間たち)で make dist するのがあたり前になっている自分には、気持ち悪い。

ビルドの自動化とソースパッケージ作成の自動化・バージョン管理のセットアップは、最初の仕事だと思うのだが。

[ 7月31日全て ]

2007年8月16日 (木)

Module::BuildZIP ファイルを作る

Module::Build 0.26 には ExtUtils::MakeMaker のように zipdist ターゲットがないので ACTION を追加してみた。

 use Module::Build
 my $class Module::Build->subclass(
   class => 'Packager',
   code  => q {
     sub ACTION_zipdist {
       my ($self) = @_;
       my $dist_dir = $self->dist_dir;
       $self->depends_on('distdir');
       print "Creating $dist_dir.zip\n";
       system("zip -r $dist_dir.zip $dist_dir") == 0 or die $?;
       $self->delete_filetree($dist_dir);
     }
   });

これで ./Build zipdist できるようになる。

[ 8月16日全て ]

About

Naney Naneymx

Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。

※本サイトの内容は個人的見解であり所属組織とは関係ありません。

Process Time: 0.025316s / load averages: 0.18, 0.18, 0.19