形態素解析エンジン MeCab 0.97 とその Python バインディングを MinGW でビルドする
環境は Windows XP, Python 2.5.2(公式サイトのインストーラーより)。この環境に MinGW, msys をセットアップし、これを用いて MeCab 0.97 をビルド。その後 MeCab Python バインディングをビルドした際の手順についてのメモ。
のまえにバイナリが欲しい方へ(2010/8/10 追記)
msys インストール
インストール中に以下のように聞かれるので y で答え、 MinGW を入れたディレクトリを入力する(デフォルトの場合 c:/MinGW)。
C:\msys\1.0\postinstall>PATH ... ... C:\msys\1.0\postinstall>..\bin\sh.exe pi.sh This is a post install process that will try to normalize between your MinGW install if any as well as your previous MSYS installs if any. I don't have any traps as aborts will not hurt anything. Do you wish to continue with the post install? [yn ]
環境変数設定
gcc, g++ で C, C++ コードのコンパイルができるところまで持っていく。http://www.knatech.info/Dev-mingw-install.html の自動設定スクリプト env_set_mingw.js を使用するとすばやく終了できる(ただし PATH 以外のユーザー環境変数を上書きするので下記変数になんらかの値を設定済みの人は注意)。このスクリプトが設定する内容は以下のとおり。
MINGW_HOME | (MinGW インストール先, 例 C:\MinGW) |
MSYS_HOME | (MSYS インストール先, 例 C:\MSYS) |
GCC_VER | (GCC バージョン, 例 3.4.5) |
GCC_EXEC_PREFIX | %MINGW_HOME% |
PATH | MSYS_HOME%\bin; %MINGW_HOME\bin; %MINGW_HOME%\libexec\gcc\mingw32\%GCC_VER%; (既存の文字列) |
C_INCLUDE_PATH | %MINGW_HOME%\include; %MINGW_HOME%\lib\gcc\mingw32\%GCC_VER%\include |
CPLUS_INCLUDE_PATH | %C_INCLUDE_PATH%; %MINGW_HOME%\include\c++\%GCC_VER%; %MINGW_HOME%\include\c++\%GCC_VER%\mingw32 |
LIBRARY_PATH | %MINGW_HOME%\lib; %MINGW_HOME%\lib\gcc\mingw32\%GCC_VER% |
さらに、Python バインディングのビルドに備えるため、以下を加える。
C_INCLUDE_PATH | (Python 2.5.2 インストール先\include, 例 C:\Python25\include) |
LIBRARY_PATH | (Python 2.5.2 インストール先\libs, 例 C:\Python25\libs) |
MeCab のビルド
MeCab のサイト より mecab-0.97.tar.gz, mecab-ipadic-2.7.0-20070801.tar.gz, mecab-python-0.97.tar.gz を用意する。これを展開する。場所はどこでもよいがスペースの入ったパスは避けるのが無難か。msys 上におけるホームディレクトリ、 (msys インストールディレクトリ\1.0\home\ユーザー名)に置くと楽。
tar を展開する。
$ tar -zxvf mecab-0.97.tar.gz $ cd mecab-0.97
MeCab 0.97 を MinGW でビルドするにあたって mecab.h, libmecab.cpp に問題があるので次のパッチ mecab-0.97_mingw.patch を当てる。
$ cd src $ patch < ../../mecab-0.97_mingw.patch $ cd ..
*** libmecab.cpp Mon Nov 26 02:27:12 2007 --- libmecab.cpp Fri Nov 07 11:10:13 2008 *************** *** 50,56 **** #if defined(_WIN32) && !defined(__CYGWIN__) HINSTANCE DllInstance = 0; ! #ifdef __cplusplus extern "C" { #endif BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID) { --- 50,56 ---- #if defined(_WIN32) && !defined(__CYGWIN__) HINSTANCE DllInstance = 0; ! #if defined(__cplusplus) && !defined(__MINGW32__) extern "C" { #endif BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID) { *************** *** 62,68 **** std::locale::global(loc); return TRUE; } ! #ifdef __cplusplus } #endif #endif --- 62,68 ---- std::locale::global(loc); return TRUE; } ! #if defined(__cplusplus) && !defined(__MINGW32__) } #endif #endif *** mecab.h Sun Jan 20 22:47:06 2008 --- mecab.h Fri Nov 07 10:35:45 2008 *************** *** 127,133 **** extern "C" { #endif ! #ifdef _WIN32 #include <windows.h> # ifdef DLL_EXPORT # define MECAB_DLL_EXTERN __declspec(dllexport) --- 127,133 ---- extern "C" { #endif ! #if defined(_WIN32) && !defined(__MINGW32__) #include <windows.h> # ifdef DLL_EXPORT # define MECAB_DLL_EXTERN __declspec(dllexport) *************** *** 250,256 **** virtual ~Tagger() {} ! #ifndef SIWG static Tagger* create(int argc, char **argv); static Tagger* create(const char *arg); #endif --- 250,256 ---- virtual ~Tagger() {} ! #ifndef SWIG static Tagger* create(int argc, char **argv); static Tagger* create(const char *arg); #endif
いざビルド。 configure に --enable-utf8-only オプションをつけると扱える文字コードが UTF-8 のみになる代わりにバイナリサイズが小さくなる。つけるかどうかは好みで。
$ ./configure --enable-utf8-only $ make $ make install $ cd ..
MeCab 辞書のビルド
続けて辞書のビルド。 --with-charset=utf8 オプションをつけると辞書の文字コードが UTF-8 になる。つけなければデフォルトの EUC-JP になる。ここも好みで。 mecab.exe をコマンドプロンプトから多用するのならば --with-charset=sjis で Shift-JIS にしておくと便利。
$ tar -zxvf mecab-ipadic-2.7.0-20070801.tar.gz $ cd mecab-ipadic-2.7.0-20070801 $ ./configure --with-charset=utf8 $ make $ make install
MeCab Python バインディングのビルド
$ tar -zxvf mecab-python-0.97.tar.gz $ cd mecab-python-0.97
setup.py の中で呼び出されている mecab-config がうまく動作しないので書き換える。各パスを直接指すように。
setup( name = "mecab-python", version = "0.97", py_modules=["MeCab"], ext_modules = [ Extension("_MeCab", ["MeCab_wrap.cxx",], include_dirs=[r"C:\msys\1.0\local\include"], library_dirs=[r"C:\msys\1.0\local\lib"], libraries=["libmecab"]) ])
ビルド
$ setup.py build -c mingw32
Python バインディングを使ってみる
- (msys インストールディレクトリ)\1.0\local\bin\libmecab-1.dll
をパスの通ったディレクトリへコピー。
- (msys インストールディレクトリ)\1.0\local\etc\mecabrc
- (msys インストールディレクトリ)\1.0\local\lib\mecab\dic ディレクトリ
- (Python バインディング、ビルドディレクトリ)\build\lib.win32-2.5\_MeCab.pyd
- (Python バインディング、ビルドディレクトリ)\build\lib.win32-2.5\MeCab.py
の4つを同一ディレクトリにコピー(空白文字を含むパス禁止)。このディレクトリに次の test.py を作成。6行目を辞書の文字コーディングとそろえる。実行。
test.py
# coding: utf-8 import os import MeCab encoding = 'utf-8' def main(): sentence = u"太郎はこの本を二郎を見た女性に渡した。".encode(encoding) try: print MeCab.VERSION root_dir = os.path.dirname(__file__) mecabrc = os.path.join(root_dir, 'mecabrc') dicdir = os.path.join(root_dir, 'dic','ipadic') t = MeCab.Tagger('-r %s -d %s' % (mecabrc, dicdir)) print t.parse(sentence).decode(encoding) m = t.parseToNode(sentence) while m: print m.surface.decode(encoding), print u"\t".decode(encoding), m.feature.decode(encoding) m = m.next print u"EOS" n = t.parseToNode(sentence) len = n.sentence_length; for i in range(len + 1): b = n.begin_node_list(i) e = n.end_node_list(i) while b: print u"B[%d] %s\t%s" % (i, b.surface.decode(encoding), b.feature.decode(encoding)) b = b.bnext while e: print u"E[%d] %s\t%s" % (i, e.surface.decode(encoding), e.feature.decode(encoding)) e = e.bnext print u"EOS"; d = t.dictionary_info() while d: print u"filename: %s" % d.filename print u"charset: %s" % d.charset print u"size: %d" % d.size print u"type: %d" % d.type print u"lsize: %d" % d.lsize print u"rsize: %d" % d.rsize print u"version: %d" % d.version d = d.next except RuntimeError, e: print "RuntimeError:", e; if __name__ == '__main__': main()
参考サイト
これらのサイトからの情報なくしてはビルド完了までこぎつけることは出来ませんでした。ありがとうございます。