libmecab < 0.90 (debianのaptとかは0.80)は内部構造がだいぶ違ってエラーになる罠:
./Build lib/Text/MeCab.xs -> lib/Text/MeCab.c /usr/bin/perl "-I/usr/lib/perl/5.8" "-I/usr/share/perl/5.8" "/usr/share/perl/5.8/ExtUtils/xsubpp" -noprototypes -typemap "/usr/share/perl/5.8/ExtUtils/typemap" "lib/Text/MeCab.xs"cc -I/usr/lib/perl/5.8/CORE -fPIC -c -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -o lib/Text/MeCab.o lib/Text/MeCab.c MeCab.xs: In function `init_constants': MeCab.xs:44: error: `MECAB_NOR_NODE' undeclared (first use in this function) MeCab.xs:44: error: (Each undeclared identifier is reported only once MeCab.xs:44: error: for each function it appears in.) MeCab.xs:45: error: `MECAB_UNK_NODE' undeclared (first use in this function) MeCab.xs:46: error: `MECAB_BOS_NODE' undeclared (first use in this function) MeCab.xs:47: error: `MECAB_EOS_NODE' undeclared (first use in this function) MeCab.xs: In function `XS_Text__MeCab__Node_rlength': MeCab.xs:228: error: structure has no member named `rlength' MeCab.xs: In function `XS_Text__MeCab__Node_enext': MeCab.xs:286: error: structure has no member named `enext' MeCab.xs:289: error: structure has no member named `enext' MeCab.xs: In function `XS_Text__MeCab__Node_bnext': MeCab.xs:307: error: structure has no member named `bnext' MeCab.xs:310: error: structure has no member named `bnext' MeCab.xs: In function `XS_Text__MeCab__Node_rcattr': MeCab.xs:348: error: structure has no member named `rcAttr' MeCab.xs: In function `XS_Text__MeCab__Node_lcattr': MeCab.xs:359: error: structure has no member named `lcAttr' MeCab.xs: In function `XS_Text__MeCab__Node_isbest': MeCab.xs:381: error: structure has no member named `isbest' MeCab.xs: In function `XS_Text__MeCab__Node_alpha': MeCab.xs:392: error: structure has no member named `alpha' MeCab.xs: In function `XS_Text__MeCab__Node_beta': MeCab.xs:403: error: structure has no member named `beta' MeCab.xs: In function `XS_Text__MeCab__Node_prob': MeCab.xs:414: error: structure has no member named `prob' MeCab.xs: In function `XS_Text__MeCab__Node_wcost': MeCab.xs:426: error: structure has no member named `wcost' error building .o file from 'lib/Text/MeCab.c' at /usr/local/share/perl/5.8.4/Module/Build/Base.pm line 2534.
報告by miyagawaさん。0.80と0.90ではだいぶ内部構造に差があるらしい。これ、Build.PLからprobe_mecab.plってのを呼んで、バージョン情報をclibsに渡す事で回避することにする:
# Build.PL my $result = do 'probe_mecab.pl'
probe_mecab.plはこんな感じ(あとでModule::Buildへの依存をなくす):
use strict; use File::Spec; use Module::Build;# try probing in places where we expect it to be
my $mecab_config;
foreach my $path qw(/usr/bin /usr/local/bin) {
my $tmp = File::Spec->catfile($path, 'mecab-config');
if (-f $tmp && -x _) {
$mecab_config = $tmp;
last;
}
}if (my $tmp = Module::Build->prompt("Path to mecab config? [$mecab_config]")) {
$mecab_config = $tmp;
}if (!-f $mecab_config || ! -x _) {
print STDERR "Can't proceed without mecab-config. Aborting...\n";
exit 1;
}my $version = `$mecab_config --version`;
chomp $version;
print "detected mecab version $version\n";
if ($version < 0.90) {
print " + mecab version < 0.90 doesn't contain some of the features\n",
" + that are available in Text::MeCab. Please read the documentation\n",
" + carefully before using\n";
}my($major, $minor, $micro) = split(/\./, $version);
my $cflags = `$mecab_config --cflags`;
chomp($cflags);$cflags .= " -DMECAB_MAJOR_VERSION=$major -DMECAB_MINOR_VERSION=$minor";
print "Using compiler flags '$cflags'...\n";my $libs = `$mecab_config --libs`;
chomp($libs);
print "Using linker flags '$libs'...\n";return { cflags => $cflags, libs => $libs };
で、実際のコンパイルするときは、こんな感じでpreprocessorレベルでコードを変更:
#if MECAB_MAJOR_VERSION > 1 || MECAB_MINOR_VERSION >= 0.90
... 0.90以降に使える機能 ...
#endif
なんかあとで細かく見るので0.03は明日あたりにリリース予定。