アゲイン、あんどなでじゃーぶ。
Mecab-python、natto-py に失敗した話、の続きというか。
- natto-py など、すぐに手に入るヤツが Windows で全滅だった
- mecab 公式のレポジトリにある python バインディングが保守されてない
- 幸いmecab 公式のpython バインディングは(素の) swig なので
「生成し直しちゃいなよ」、まる。
mecab 公式レポジトリにある「swig による生成物」は、古い swig と古い python (2.6 以下)によるものなのだが、インターフェイス(*.i)の仕様が変わってないんであれば、「新しい swig で」生成し直せば、望みの python 用になるであろう、と。
これも幸いというかなんというか、mecab 公式レポジトリにある「swig による生成物、をインストールするための setup.py」はほんっと最小限のことしかしてないんで、自力で全部書き下してしまったほうが早いと思われる。
つーわけで。
さて、swig は確か前に持ってきてたよなぁ…、と探すも、見つからない。うーん、かなり前だからなぁ、もしかして、今の PC の前のヤツだった頃か? とすりゃ、もう6年以上前だわ。なので http://www.swig.org/download.html より swigwin-4.0.1 をダウンロード。「インストール」の公式な方法ってのはなさげね。バイナリ一個をぺろっと好きな場所に置くだけ、か。
んで、必要なのは「mecab のソースパッケージ」ね。GitHub からか 公式ドキュメント のどっちからでもいいけど、それの mecab/swig が目的のもの。
1 [me@host: mecab-0.996]$ mkdir python
2 [me@host: mecab-0.996]$ cd swig
3 [me@host: swig]$ make SWIG=../../swigwin-4.0.1/swig.exe python
4 c:/Users/hhsprings/swigwin-4.0.1/swig.exe -python -shadow -c++ MeCab.i
5 ..\src\mecab.h(136) : Warning 302: Identifier 'surface' redefined by %extend (ignored),
6 MeCab.i(74) : Warning 302: %extend definition of 'surface'.
7 ..\src\mecab.h(848) : Warning 302: Identifier 'set_sentence' redefined by %extend (ignored),
8 MeCab.i(95) : Warning 302: %extend definition of 'set_sentence'.
9 mv -f MeCab_wrap.cxx ../python
10 mv -f MeCab.py ../python
11 [me@host: swig]$ ls -lh ../python
12 total 277K
13 -rw-r--r-- 1 hhsprings Administrators 13K Nov 20 21:05 MeCab.py
14 -rw-r--r-- 1 hhsprings Administrators 264K Nov 20 21:05 MeCab_wrap.cxx
とここまでが、前回の「失敗談の前置き」。
「「MeCab 自身の 64bit 対応が出来てないので、CPython amd64 版は(MeCab 自身の改変なしでは)不可能」」はガセだった。しっかり「HAVE_UNSIGNED_LONG_LONG_INT
」で措置されていた。
というわけで、こんな setup.py を書けばビルド出来る:
1 # -*- coding: utf-8 -*-
2 import re
3 from distutils.core import setup, Extension
4
5
6 _OBJS = """feature_index.obj param.obj learner.obj string_buffer.obj \
7 char_property.obj learner_tagger.obj tagger.obj \
8 connector.obj tokenizer.obj \
9 context_id.obj dictionary.obj utils.obj \
10 dictionary_compiler.obj viterbi.obj \
11 dictionary_generator.obj writer.obj iconv_utils.obj \
12 dictionary_rewriter.obj lbfgs.obj eval.obj nbest_generator.obj"""
13 _SRCS = ["../src/{}".format(obj.replace(".obj", ".cpp"))
14 for obj in re.split(r"\s+", _OBJS)] + ["../src/libmecab.cpp"]
15 setup(
16 name="mecab-python",
17 version="0.996",
18 py_modules=["MeCab"],
19 ext_modules=[
20 Extension(
21 "_MeCab",
22 _SRCS + ["MeCab_wrap.cxx",],
23 extra_compile_args=[
24 # "-GA", "-Zi",
25 "-wd4800", "-wd4305", "-wd4244",
26 "-wd4267",
27 ],
28 define_macros=[
29 ("HAVE_STDINT_H", "1"),
30 ("_CRT_SECURE_NO_WARNINGS", "1"),
31 ("_CRT_SECURE_NO_DEPRECATE", "1"),
32 ("HAVE_UNSIGNED_LONG_LONG_INT", "1"),
33 ("MECAB_USE_THREAD", "1"),
34 ("HAVE_GETENV", "1"),
35 ("HAVE_WINDOWS_H", "1"),
36 ("DIC_VERSION", '102',),
37 ("VERSION", '"\\"0.996\\""'),
38 ("PACKAGE", '"\\"mecab\\""'),
39 ("UNICODE", "1"),
40 ("_UNICODE", "1"),
41 ("MECAB_DEFAULT_RC", '"\\"c:/Program\\032Files\\032(x86)/MeCab/etc/mecabrc\\""'),
42 ],
43 undef_macros=[
44 "DLL_EXPORT",
45 ],
46 include_dirs=["../src"],
47 library_dirs=["../src"],
48 libraries=["advapi32"],
49 )
50 ])
まだ「ビルド出来た、あーんど、インストールしてモジュールインポートまではうまくいった」が出来ただけなので、何にも保障はしないけれど、ともあれ前進は前進。あと、前回書いた通りこれは「抱え込み」なので、仮に MeCab 公式のバージョンアップがあって libmecab.dll が更新されたとしてもそこから置いてけぼりになることには注意。
あと、Python 2.7 用のは…、興味ある? 欲しい? ワタシはいらんなぁ。いくら「Python 2.7 を 2025 年までは見捨てない」と言ったからといって、さすがに C 拡張を伴うものまではやってらんない。挙げた setup.py のままで行ければ行けるだろうし、行けなきゃいけない。というか少なくとも stdint.h はないので、HAVE_STDINT_H は外さないとダメだろうね。外すだけで行けるかもしれん。どうかな。やってはみないけど、どうしてもという人は、是非奈落に落ちてみればいいと思う。
にしても、作ったはいいが、使い方がまったくわからん。natto-py から使い方を探るしかないかなぁ。