北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

サブディレクトリのMakefile.PL

必要に迫られて Module::Install と ExtUtil::MakeMaker 関連を調べる羽目になったのでメモ。

ExtUtil::MakeMakerでは、DIRパラメータがない場合には、Makefile.PLがあるサブディレクトリを自動で再帰的に処理してくれます。この挙動は、NORECURSの値で制御できます。

    # We run all the subdirectories now. They don't have much to query
    # from the parent, but the parent has to query them: if they need linking!
    unless ($self->{NORECURS}) {
        $self->eval_in_subdirs if @{$self->{DIR}};
    }

# MakeMaker.pm より引用

ところが、 Module::Install 経由でExtUtil::MakeMakerが使われる場合は、サブディレクトリには潜ってくれなくなります。これは、Module::Install側の Module::Install::Makefile->write メソッド内で、

	my $subdirs = ($args->{DIR} ||= []);
	# (... 中略 ...)
	my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
	# (... 中略 ...)
	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);


# Makefile.pm より引用

とExtUtil::MakeMakerに渡すDIRパラメータをundefではなく空の配列で初期化していることと、DIRパラメータの省略時にこれを自動でセットしてくれる ExtUtil::MM_Unix の init_dirscan メソッドの実装が、

    $self->{DIR} ||= [sort keys %dir];

# MM_Unix.pmより引用

と言う風にDIRパラメータが入力された場合は上書きをしない作りになっていることが原因です。


これを、Module::Installでもサブディレクトリに勝手に潜って処理してくれるような方法を調べたのですが、あまりいい方法が浮かびませんでした。現状では、Makefile.PL側で、

makemaker_args 'DIR' => ['subdir1', 'subdir2', ... ];

と言う感じでDIRパラメータを明示的に指定するしかないといったところでしょうか。

つまり、自動を諦めて手動でやってるんで、結局これってなんの解決にもなってないですorz