Text::MeCab を x86_64 環境でインストールする方法
mecab 標準の mecab-perl より高速とのことで、モジュールの安定性を待っている間にすっかり忘れてしまった Text::MeCab ですが、突然思い出したので使ってみようかと思いインストールしてみたところ、make test にてエラー。
う〜ん・・・たぶん x86_64 環境だからだろうと推測し情報集め。
取りあえずでているエラーはこんな感じ。エラーを書いても意味がないけど、同じ現象になった方が検索でココに辿り着くようにとの意味で。
t/01-sanity..................
# Failed test 'use Text::MeCab;'
# in t/01-sanity.t at line 7.
# Tried to use 'Text::MeCab'.
# Error: Can't load '/root/.cpan/build/Text-MeCab-0.15/blib/arch/auto/Text/MeCab/MeCab.so' for module Text::MeCab: /root/.cpan/build/Text-MeCab-0.15/blib/arch/auto/Text/MeCab/MeCab.so: u
ndefined symbol: _ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_ at /usr/local/lib/perl5/5.8.7/x86_64-linux-thread-multi/DynaLoader.pm line 230.
# at /usr/local/lib/perl5/5.8.7/x86_64-linux-thread-multi/XSLoader.pm line 26
# BEGIN failed--compilation aborted at t/01-sanity.t line 7.
# Compilation failed in require at (eval 3) line 2.
# BEGIN failed--compilation aborted at (eval 3) line 2.
Bareword "MECAB_NOR_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 11.
Bareword "MECAB_UNK_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 12.
Bareword "MECAB_BOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 13.
Bareword "MECAB_EOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 14.
Execution of t/01-sanity.t aborted due to compilation errors.
# Looks like you failed 1 test of 1.
# Looks like your test died just after 1.
t/01-sanity..................dubious
Test returned status 255 (wstat 65280, 0xff00)
DIED. FAILED test 1
Failed 1/1 tests, 0.00% okay
さて、解決方法です。Makefile.PL を以下のように編集。赤い部分が追記部分です。
WriteMakefile ( 'DISTNAME' => 'Text-MeCab', 'NAME' => 'Text::MeCab', 'VERSION_FROM' => 'lib/Text/MeCab.pm', 'PREREQ_PM' => {}, 'INSTALLDIRS' => 'site', 'LIBS' => [ split(/\s+/, $result->{libs}) ], 'CCFLAGS' => $result->{cflags}, 'LD' => `mecab-config --cxx`, 'INC' => `mecab-config --cflags`, 'clean' => { FILES => 'MeCab.xs' } );
これで無事に make test もとおります。
PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01-sanity..................ok
t/02-basic...................ok
t/03-free....................ok
t/04-dclone..................ok
t/05-format..................ok
t/90-regression_tomi_args....skipped
all skipped: TODO
t/99-pod-coverage............ok
t/99-pod.....................ok
All tests successful, 1 test skipped.
Files=8, Tests=492, 1 wallclock secs ( 0.41 cusr + 0.10 csys = 0.51 CPU)
tools/benchmark.pl で簡単なベンチマークが計測できるのでやってみる。
perl benchmark.pl Rate mecab text_mecab mecab 27.7/s -- -71% text_mecab 97.1/s 250% --
と言うことで、約 2.5 倍ほど高速になるみたいです。日本語処理を伴うサービスの場合、mecab-perl を Text::MeCab に置き換えるだけでそれなりの負荷低減が見込めそうです。Amazon Search とかも久々に手を入れるとするかなぁ・・・。
文章が大きくなると Text::MeCab は遅くなる場合もあるようです。(あったようです?)
一応自分でも計測してみました。ベンチの話は環境依存が多分にあるので皆様も是非鵜呑みにせず自分の環境でベンチ下さい。ウチの環境ではこんな感じ。
wget http://www.aozora.gr.jp/cards/000125/files/1317_23268.html time mecab -Owakati < 1317_23268.html > /dev/null real 0m0.317s user 0m0.236s sys 0m0.004s time perl wakati-mecab.pl < 1317_23268.html > /dev/null real 0m0.252s user 0m0.145s sys 0m0.086s time perl wakati-text-mecab.pl < 1317_23268.html > /dev/null real 0m0.228s user 0m0.133s sys 0m0.094s wget http://www.aozora.gr.jp/cards/000096/files/2381_13352.html time mecab -Owakati < 2381_13352.html > /dev/null real 0m0.012s user 0m0.008s sys 0m0.003s time perl wakati-mecab.pl < 2381_13352.html > /dev/null real 0m0.035s user 0m0.024s sys 0m0.011s time perl wakati-text-mecab.pl < 2381_13352.html > /dev/null real 0m0.061s user 0m0.051s sys 0m0.010s
となって大きな文章でも問題なく?ってか mecab-perl も Text::MeCab も同じ速度でした。小さな文章はやっぱり高速みたい?と思ったら逆だった。mecab-perl の方が速いじゃん!!
あれー??ってかよくベンチスクリプト見たら、Text::MeCab の方、perl の push やら join で処理時間くってないかい?ってことで、今日はここまで。
コメントやシェアをお願いします!
まる
御世話になっております。
先にお送りした質問についての環境等お送り申し上げます。
※長文となり、申し訳ございません。
環境:
CentOS release 5.5 (Final)
Kernel 2.6.18-194.el5 #1 SMP Fri Apr 2 14:58:14 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
glib2-2.12.3-4.el5_3.1
glibc-2.5-81.el5_8.2
glibc-common-2.5-81.el5_8.2
gcc-4.1.2-52.el5_8.1
gcc-c++-4.1.2-52.el5_8.1
compat-libgcc-296-2.96-138
libgcc-4.1.2-52.el5_8.1
perl-5.8.8-27.el5
実行結果:
cpan -i Text::MeCab
------- 中略 --------------------------------
Path to mecab config? [/usr/local/bin/mecab-config]
detected mecab version 0.993
Using compiler flags '-I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993'...
Using linker flags '-L/usr/local/lib -lmecab -lstdc++'...
Text::MeCab needs to know what encoding you built your dictionary with
to properly execute tests.
Encoding of your mecab dictionary? (shift_jis, euc-jp, utf-8) [euc-jp] utf-8
Using utf-8 as your dictionary encoding
Detected the following mecab information:
version: 0.993
cflags: -I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993 -I src
libs: -L/usr/local/lib -lmecab -lstdc++
include: /usr/local/include
reading /usr/local/include/mecab.h to find all constants
Writing ppport.h
Checking if your kit is complete...
Looks good
Writing Makefile for Text::MeCab
Writing MYMETA.yml and MYMETA.json
cp lib/Text/MeCab/Dict.pm blib/lib/Text/MeCab/Dict.pm
cp lib/Text/MeCab/Node.pod blib/lib/Text/MeCab/Node.pod
cp lib/Text/MeCab.pm blib/lib/Text/MeCab.pm
gcc -c "-I." "-I/usr/local/include" "-I." -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993 -I src -Wall -Wextra -Wdeclaration-after-statement -Wc++-compat -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DVERSION=\"0.20013\" -DXS_VERSION=\"0.20013\" -o xs/text-mecab-node.o -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE" -DUSE_PPPORT -DTEXT_MECAB_ENCODING='"utf-8"' -DTEXT_MECAB_CONFIG='"/usr/local/bin/mecab-config"' xs/text-mecab-node.c
xs/text-mecab-node.c:7 から include されたファイル中:
xs/text-mecab.h:120:30: 警告: ファイル末尾に改行がありません
/usr/bin/perl "-Iinc" /usr/lib/perl5/5.8.8/ExtUtils/xsubpp -typemap /usr/lib/perl5/5.8.8/ExtUtils/typemap xs/MeCab.xs > xs/MeCab.xsc && mv xs/MeCab.xsc xs/MeCab.c
gcc -c "-I." "-I/usr/local/include" "-I." -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993 -I src -Wall -Wextra -Wdeclaration-after-statement -Wc++-compat -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DVERSION=\"0.20013\" -DXS_VERSION=\"0.20013\" -o xs/MeCab.o -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE" -DUSE_PPPORT -DTEXT_MECAB_ENCODING='"utf-8"' -DTEXT_MECAB_CONFIG='"/usr/local/bin/mecab-config"' xs/MeCab.c
xs/MeCab.xs:1 から include されたファイル中:
xs/text-mecab.h:120:30: 警告: ファイル末尾に改行がありません
xs/MeCab.xs:64: 警告: 構造体初期化子内の要素が多すぎます
xs/MeCab.xs:64: 警告: (near initialization for ‘TextMeCab_vtbl’)
xs/MeCab.c: In function ‘XS_Text__MeCab__Node__Cloned_format’:
xs/MeCab.c:1066: 警告: ‘mecab’ may be used uninitialized in this function
xs/MeCab.c: In function ‘XS_Text__MeCab__Node_format’:
xs/MeCab.c:676: 警告: ‘mecab’ may be used uninitialized in this function
xs/MeCab.c: In function ‘XS_Text__MeCab_parse’:
xs/MeCab.c:303: 警告: ‘mecab’ may be used uninitialized in this function
gcc -c "-I." "-I/usr/local/include" "-I." -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993 -I src -Wall -Wextra -Wdeclaration-after-statement -Wc++-compat -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DVERSION=\"0.20013\" -DXS_VERSION=\"0.20013\" -o xs/text-mecab.o -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE" -DUSE_PPPORT -DTEXT_MECAB_ENCODING='"utf-8"' -DTEXT_MECAB_CONFIG='"/usr/local/bin/mecab-config"' xs/text-mecab.c
xs/text-mecab.c:7 から include されたファイル中:
xs/text-mecab.h:120:30: 警告: ファイル末尾に改行がありません
xs/text-mecab.c: In function ‘TextMeCab_create’:
xs/text-mecab.c:48: 警告: データ型の範囲制限によって、比較が常に false となります
xs/text-mecab.c: In function ‘TextMeCab_create_from_av’:
xs/text-mecab.c:71: 警告: データ型の範囲制限によって、比較が常に false となります
xs/text-mecab.c:114:30: 警告: ファイル末尾に改行がありません
xs/text-mecab.c:61: 警告: ‘argv’ may be used uninitialized in this function
gcc -c "-I." "-I/usr/local/include" "-I." -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -I/usr/local/include -DMECAB_MAJOR_VERSION=0 -DMECAB_MINOR_VERSION=993 -I src -Wall -Wextra -Wdeclaration-after-statement -Wc++-compat -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DVERSION=\"0.20013\" -DXS_VERSION=\"0.20013\" -o xs/text-mecab-clone.o -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE" -DUSE_PPPORT -DTEXT_MECAB_ENCODING='"utf-8"' -DTEXT_MECAB_CONFIG='"/usr/local/bin/mecab-config"' xs/text-mecab-clone.c
xs/text-mecab-clone.c:7 から include されたファイル中:
xs/text-mecab.h:120:30: 警告: ファイル末尾に改行がありません
Running Mkbootstrap for Text::MeCab ()
chmod 644 MeCab.bs
rm -f blib/arch/auto/Text/MeCab/MeCab.so
LD_RUN_PATH="/usr/local/lib:/usr/lib64" gcc -shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic xs/text-mecab-node.o xs/MeCab.o xs/text-mecab.o xs/text-mecab-clone.o -o blib/arch/auto/Text/MeCab/MeCab.so \
-L/usr/local/lib -lmecab -lstdc++ \
chmod 755 blib/arch/auto/Text/MeCab/MeCab.so
cp MeCab.bs blib/arch/auto/Text/MeCab/MeCab.bs
chmod 644 blib/arch/auto/Text/MeCab/MeCab.bs
Manifying blib/man3/Text::MeCab::Dict.3pm
lib/Text/MeCab/Dict.pm:161: Unknown command paragraph "=encoding UTF-8"
Manifying blib/man3/Text::MeCab::Node.3pm
Manifying blib/man3/Text::MeCab.3pm
/usr/bin/make -- OK
Running make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'blib/lib', 'blib/arch')" t/*.t t/*/*.t
t/01-sanity.t ................ 1/42 Bareword "MECAB_NOR_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 11.
Bareword "MECAB_UNK_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 12.
Bareword "MECAB_BOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 13.
Bareword "MECAB_EOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 14.
Execution of t/01-sanity.t aborted due to compilation errors.
# Looks like you planned 42 tests but ran 1.
# Looks like your test exited with 9 just after 1.
t/01-sanity.t ................ Dubious, test returned 9 (wstat 2304, 0x900)
Failed 41/42 subtests
t/node/01_load.t ............. ok
t/node/02_api.t .............. ok
t/node/03_clone.t ............ ok
t/node/04_clone_free.t ....... ok
t/node/05_format.t ........... ok
t/regression/01_tomi_args.t .. skipped: SWIG MeCab not available
t/tagger/01_load.t ........... ok
t/tagger/02_api.t ............ ok
t/tagger/03_basic.t .......... ok
Test Summary Report
-------------------
t/01-sanity.t (Wstat: 2304 Tests: 1 Failed: 0)
Non-zero exit status: 9
Parse errors: Bad plan. You planned 42 tests but ran 1.
Files=10, Tests=2336, 2 wallclock secs ( 0.20 usr 0.01 sys + 0.42 cusr 0.05 csys = 0.68 CPU)
Result: FAIL
Failed 1/10 test programs. 0/2336 subtests failed.
make: *** [test_dynamic] エラー 255
/usr/bin/make test -- NOT OK
Running make install
make test had returned bad status, won't install without force
以上です。
すみません、よろしくお願い申し上げます。
まる
はじめまして。まると言います。
「Text::MeCab を x86_64 環境でインストールする方法」を参考にx86_64環境にて構築しています。
同様なmake testエラーで悩んでおります。使用しているSourceは以下の通りです。
mecab-0.993.tar.gz
mecab-ipadic-2.7.0-20070801.tar.gz
こちらで書かれている対処方法について展開したmecab-0.993のソースを覗いてみましたがMakefile.PLファイル中に示されているコードが見つかりません。
具体的には「WriteMakefile」なる箇所はコメントアウトされており、将来的にはこの部分を削除する旨コメントがございました。
このような場合どのような対処が考えられますでしょうか。
恐縮ですがアドバイス頂ければ幸いです。