目次

前のトピックへ

日本語検索強化

このページ

Sphinx on windows (Admin権限なし版)

残念な環境(windows7 Admin権限なし)にある人の為の sphinx Install 術です。

とりあえず、PythonとSphinxのインストールまではAdmin権限なしで行けそうですが、 MeCabのインストール以降については、Admin権限が必要な場合があります。

なお、Sphinx側の制約だが、同じファイルパスであれば、Adminがとれる環境でビルドして、他のマシンにディレクトリごとファイルをコピーしても動作した。(但しこの場合、レジストリが設定されていないので、代わりに環境変数の設定が必要)

構成

Windows環境下で、以下3つのソフトを導入し、sphinxの日本語関連検索を強化する事を目指す。なるべくAdmin権限は使用しない。

Portable Python の Install

Portable Python をダウンロードし、インストールアプリケーションを実行。

PortablePythonのインストーラで、インストール先を変更できる。

仮にInstall 先を %UserProfile%\Tools\PortablePython27 とするとユーザのカレントディレクトリ配下の ~\Tools\PortablePython27 にインストールされるが、PortablePython のインストーラは %UserProfile% を上手く扱ってくれないので、すなおにディレクトリを指定します。

C:\Users\Username\Tools\PortablePython27

ってかんじ。

ノート

以下では Username を sphinx として進めます。 つまり、ユーザのカレントディレクトリは C:\Users\sphinx\ です。

インストールが完了すれば、C:\Users\sphinx\Tools\PortablePython27のAppディレクトリ内にあるPythonが利用できる。

環境変数設定

以下のPathを設定する。

  • 追加設定するpythonへのPATH
    • %UserProfile%\Tools\PortablePython27\App
    • %UserProfile%\Tools\PortablePython27\App\Scripts

マイコンピュータ右クリックから環境変数を設定 する事で、pythonのバイナリへのPATHを定義できるが、権限がないなどの理由でその方法が利用出来ない場合は コマンドプロンプトでPATHの設定をする必要がある。

C:\Users\sphinx>set path=%path%;%UserProfile%\Tools\PortablePython27\App;%UserProfile%\Tools\PortablePython27\App\Scripts

C:\Users\sphinx>path
PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32
\WindowsPowerShell\v1.0\;C:\Users\sphinx\Tools\PortablePython27\App;C:\Users\sphinx\Tools\PortablePython27\App\Scripts

なお、都度設定をするのが面倒な場合は setx コマンド で設定ができる (次回cmdを開いたタイミングから反映される) が、このコマンドはレジストリの HKEY_CURRENT_USER\Environment に書き込んじゃうので、自己責任でやること。

C:\Users\sphinx>setx PATH "%UserProfile%\Tools\PortablePython27\App;%UserProfile
%\Tools\PortablePython27\App\Scripts"

成功: 指定した値は保存されました。

ノート

ちなみに、次の環境変数は設定必要か不明だが、とりあえず定義していない。 PYTHONPATH=%UserProfile%\Tools\PortablePython27\App\Lib\site-packages

Sphinx のインストール

Portable Python がインストールされ、PATHが上手く通っていれば

> easy_install sphinx

でok

とりあえずこれで sphinx-quickstart が使える様になる。

日本語ファイル名への対応

Sphinx 1.1.3 では、windows環境の日本語ファイル名に対応しておらず、たとえば マルチバイト.rst なんてファイルがあると、make html 時に以下の様なエラーが表示される。

    pub.set_source(None, src_path.encode(fs_encoding))
UnicodeDecodeError: 'ascii' codec can't decode byte 0x83 in position 36: ordinal not in range(128)

対処のためには、Sphinx の Source のあるディレクトリ(C:\Users\sphinx\Tools\PortablePython27\App\Lib\site-packages\Sphinx-1.1.3-py2.7.egg\sphinx など) にて以下の通り各ファイルに Patch を当てる必要が有る。

Binary files sphinx_old/.DS_Store and sphinx_new/.DS_Store differ
diff -u sphinx_old/cmdline.py sphinx_new/cmdline.py
--- sphinx_old/cmdline.py      2012-05-21 05:50:23.000000000 +0900
+++ sphinx_new/cmdline.py      2012-05-21 15:49:36.000000000 +0900
@@ -65,7 +65,7 @@
     try:
         opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:ng:NEqQWw:P')
         allopts = set(opt[0] for opt in opts)
-        srcdir = confdir = path.abspath(args[0])
+        srcdir = confdir = unicode(path.abspath(args[0]), sys.getfilesystemencoding())
         if not path.isdir(srcdir):
             print >>sys.stderr, 'Error: Cannot find source directory.'
             return 1
@@ -74,7 +74,7 @@
             print >>sys.stderr, ('Error: Source directory doesn\'t '
                                  'contain conf.py file.')
             return 1
-        outdir = path.abspath(args[1])
+        outdir = unicode(path.abspath(args[1]), sys.getfilesystemencoding())
         if not path.isdir(outdir):
             print >>sys.stderr, 'Making output directory…'
             os.makedirs(outdir)
diff -u sphinx_old/config.py sphinx_new/config.py
--- sphinx_old/config.py       2012-05-21 05:50:23.000000000 +0900
+++ sphinx_new/config.py       2012-05-21 15:50:34.000000000 +0900
@@ -186,7 +186,7 @@
         self.values = Config.config_values.copy()
         config = {}
         if dirname is not None:
-            config_file = path.join(dirname, filename)
+            config_file = path.join(dirname.encode(sys.getfilesystemencoding()), filename)
             config['__file__'] = config_file
             config['tags'] = tags
             olddir = os.getcwd()
diff -u sphinx_old/environment.py sphinx_new/environment.py
--- sphinx_old/environment.py  2012-05-21 05:50:23.000000000 +0900
+++ sphinx_new/environment.py  2012-05-21 15:52:54.000000000 +0900
@@ -461,7 +461,7 @@
         elif base is None:
             return docname + suffix
         else:
-            return path.join(base, docname) + suffix
+            return path.join(base, docname.encode(sys.getfilesystemencoding())) + suffix

     def relfn2path(self, filename, docname=None):
         """Return paths to a file referenced from a document, relative to
@@ -1321,7 +1321,7 @@
         def _entries_from_toctree(toctreenode, parents,
                                   separate=False, subtree=False):
             """Return TOC entries for a toctree node."""
-            refs = [(e[0], str(e[1])) for e in toctreenode['entries']]
+            refs = [(e[0], e[1]) for e in toctreenode['entries']]
             entries = []
             for (title, ref) in refs:
                 try:

これで日本語ファイル名での make html も対応できるはず。 これでも治らない場合は、Portable Python の標準エンコーディング指定を変更してみる。

方法は、以下のファイルを Portable Python の site-packages 配下に追加することで出来ます。

ファイル名は: sitecustomize.py

import sys
sys.setdefaultencoding('utf-8')

動作確認は以下の様にして出来ます。

設定前

> python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>>

設定後

> python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>

MeCAB のインストール

MeCAB からダウンロードした windows 版バイナリは UAC のお陰で Admin 権限が必要っぽい? ぐぬぬ..

とりあえず、なんとか Admin 権限を得て以下条件で Install した事を前提に続きを書きます。(別途 Admin がとれるマシンでビルドしてから、そのファイルを持ち込む事でも対応できますが、そん場合は後述の環境変数定義が必要です)

  • 文字コード : UTF-8
  • Install先 : %UserProfile%\Tools\MeCab
  • レジストリ : HKEY_CURRENT_USER\software\mecab\mecabrc

文字コードはMeCab正式のwindows用インストーラを使用すれば、インストーラ画面で選択できる。(デフォルトはShift_JIS) また、レジストリもwindows用インストールを使えば設定される。

警告

sphinxでMeCabを使う場合、文字コードは UTF-8 にしておかないといけない。でないとsphinx側で文字コードエラーがでる。

他所からバイナリファイルを持ち込んだ場合

インストールを使わずに、他所からバイナリを持ち込んだ場合は、環境変数 MECABRC を定義する必要が有ります。

環境変数 MECABRC で mecabrc ファイル (mecabをインストールしたディレクトリの etc\mecabrc ファイル) を明示してあげればよい。

C:\Users\sphinx> setx MECABRC "C:\Users\sphinx\Tools\MeCab\etc\mecabrc"

成功: 指定した値は保存されました。

ノート

MeCab 0.90 における mecabrc ファイルの優先順位 が参考になりました。

動作確認

MeCabのカレントディレクトリ下の bin\mecab を実行することで、動作確認できる。

_images/fig-MeCab_win.png

MeCab の Python へのバンディング

VisualC++ 2008 Express Edition

さて、MeCabをpythonへバインディングするために、結局ビルドが必要となる。

なので、windows環境のビルドツール VisualC++ 2008 Express Edition を入手し、Install しておきます。

ノート

C言語何でもサイト でもInstall手順が分かります

ビルドとバインド

MeCAB から mecab-python-ほにゃらら をダウンロードして適当な場所に展開 (Lhaplusとかで展開できます)

取得した Source ( mecab-python-0.993 時点 ) では、windows環境が考慮されておらず、そのままではビルドできないので、以下の通り setup.py を訂正します

--- setup.py   2012-02-11 01:46:45.000000000 +0900
+++ setup.py_win       2012-05-20 12:44:11.000000000 +0900
@@ -1,21 +1,14 @@
 #!/usr/bin/env python

-from distutils.core import setup,Extension,os
-import string
-
-def cmd1(str):
-    return os.popen(str).readlines()[0][:-1]
-
-def cmd2(str):
-    return string.split (cmd1(str))
+from distutils.core import setup,Extension

 setup(name = "mecab-python",
-      version = cmd1("mecab-config --version"),
+      version = '0.993',
       py_modules=["MeCab"],
       ext_modules = [
               Extension("_MeCab",
                       ["MeCab_wrap.cxx",],
-                      include_dirs=cmd2("mecab-config --inc-dir"),
-                      library_dirs=cmd2("mecab-config --libs-only-L"),
-                      libraries=cmd2("mecab-config --libs-only-l"))
+                      include_dirs=[r"C:\Users\sphinx\Tools\MeCab\sdk"],
+                      library_dirs=[r"C:\Users\sphinx\Tools\Mecab\sdk"],
+                      libraries=['libmecab'])
                       ])

ちなみに直した setup.py はこんな感じ

#!/usr/bin/env python

from distutils.core import setup,Extension

setup(name = "mecab-python",
       version = '0.993',
       py_modules=["MeCab"],
       ext_modules = [
               Extension("_MeCab",
                       ["MeCab_wrap.cxx",],
                       include_dirs=[r"C:\Users\sphinx\Tools\MeCab\sdk"],
                       library_dirs=[r"C:\Users\sphinx\Tools\Mecab\sdk"],
                       libraries=['libmecab'])
                       ])

警告

include_dirsとlibrary_dirsのパスは環境に合わせて適宜訂正してください

cmd で、展開したディレクトリにて build と install

>python setup.py build
running build
running build_py
creating build
creating build\lib.win32-2.7
copying MeCab.py -> build\lib.win32-2.7
running build_ext
building '_MeCab' extension
creating build\temp.win32-2.7
creating build\temp.win32-2.7\Release
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox
/MD /W3 /GS- /DNDEBUG -IC:\Users\sphinx\Tools\MeCab\sdk -IC:\Users\sphinx\Tools\
PortablePython27\App\include -IC:\Users\sphinx\Tools\PortablePython27\App\PC /Tp
MeCab_wrap.cxx /Fobuild\temp.win32-2.7\Release\MeCab_wrap.obj
MeCab_wrap.cxx
MeCab_wrap.cxx(3466) : warning C4530: C++ 例外処理を使っていますが、アンワインド
セマンティクスは有効にはなりません。/EHsc を指定してください。
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\link.exe /DLL /nologo
/INCREMENTAL:NO /LIBPATH:C:\Users\sphinx\Tools\Mecab\sdk /LIBPATH:C:\Users\sphin
x\Tools\PortablePython27\App\libs /LIBPATH:C:\Users\sphinx\Tools\PortablePython2
7\App\PCbuild libmecab.lib /EXPORT:init_MeCab build\temp.win32-2.7\Release\MeCab
_wrap.obj /OUT:build\lib.win32-2.7\_MeCab.pyd /IMPLIB:build\temp.win32-2.7\Relea
se\_MeCab.lib /MANIFESTFILE:build\temp.win32-2.7\Release\_MeCab.pyd.manifest
ライブラリ build\temp.win32-2.7\Release\_MeCab.lib とオブジェクト build\temp.
win32-2.7\Release\_MeCab.exp を作成中

>python setup.py install
running install
running build
running build_py
running build_ext
running install_lib
copying build\lib.win32-2.7\MeCab.py -> C:\Users\sphinx\Tools\PortablePython27\A
pp\Lib\site-packages
copying build\lib.win32-2.7\_MeCab.pyd -> C:\Users\sphinx\Tools\PortablePython27
\App\Lib\site-packages
byte-compiling C:\Users\sphinx\Tools\PortablePython27\App\Lib\site-packages\MeCa
b.py to MeCab.pyc
running install_egg_info
Writing C:\Users\sphinx\Tools\PortablePython27\App\Lib\site-packages\mecab_pytho
n-0.993-py2.7.egg-info

なお、別のマシンでビルドして、上記 MeCab.py と _MeCab.pyd mecab_python-0.993-py2.7.egg-info を持ち込んでも動作します。

libmecab.dll を site-packages 配下へ copy

MeCabがデフォルトのディレクトリにインストールされていない場合、Pythonがlibmecab.dllを見つけきれない様なので、C:\Users\sphinx\Tools\MeCab\bin 下の libmecab.dll ファイルを Python の Site-packages ( C:\Users\sphinx\Tools\PortablePython27\App\Lib\site-packages ) に copy してあげる。

> copy C:\Users\sphinx\Tools\MeCab\bin\libmecab.dll C:\Users\sphinx\Tools\PortablePython27\App\Lib\site-packages\

なお、別のマシンでビルドして、上記 libmecab.dll を持ち込んでも動作します。

Sphinx で MeCabを利用する

conf.py に 以下の設定を追加して make.bat html するだけ。

html_search_language = 'ja'
html_search_options = {'type':'mecab'}

設定前後では例えば なんとなく といった、これまで検索できなかったセンテンスが検索できる様になります。