某分野ではデファクトスタンダードな Pymol ですが、ソースコード自体はオープンソースなものの、安定版のコンパイル済みバイナリについては有償提供というビジネスモデルで成立しています。
いくらオープンソースといえども金がなければ開発は進まないわけで、お金のある研究室や企業の方々にはライセンスの購入をお勧めしたいところではありますが、実際には不安定版の 0.99 が無償配布されていることもあり、それを使う、もしくは *nix/mac でコンパイルしながら作業されている方も多いかと思います。
で、最新の 1.2 beta で 3D ディスプレイに対応したり、レンダリング速度が向上していたりと何かと改良点が多くなってきたので、ぼちぼち Windows 上で Pymol をコンパイルする際の Tips を纏めておこうと思います。
なお、 Cygwin でコンパイルする際には普通にコンパイルすれば通るので特段注意は必要ありません。が、どうも不安定な気がするので個人的にあまり好きではないのと、 Mingw の sh が未だにメモリリークしまくる印象があるので、今回は無償配布されている "Microsoft Visual C++ 2008 Express Edition" での開発となります。
また、ライセンスについてですが、 Pymol は Python License なのと、コンパイラに関しては
7. Express Edition を商用目的で使用できますか。
http://www.microsoft.com/japan/msdn/vstudio/express/faq/2008/default.aspx
はい。Visual Studio Express Edition を使用して作成したアプリケーションについては、ライセンスの制限はありません。
ということなので、特段問題はないかと。
必要なもの
README を見ればある程度書いてありますが、
- Pymol ソース
- Python バイナリ
(2.5x系列のもの) - libpng
- zlib
- freetype2 (オプショナルとはいえ、導入推奨)
- glut32
- Numpy
- Pmw (Python Mega Widgets)
- Microsoft Visual C++ 2008 Express Edition
となります。
なお、 Tcl/Tk はコンパイルに特に必要無いようなので、準備する必要はないです。
もともと Pymol 自体は VC6 が主開発環境で MFC アプリケーションなのですが、それを .net 環境の VS2008 で作業するため余分なライブラリが必要となり、結構重いライブラリ群を持ってくる必要があります。
また、 Python は既に 3.0 系列がリリースされていますが、Pymol のソースコードの互換性上、2.5 系列までのものでしか正常にコンパイルできません。修正されたようです。1.1 branch では非対応だったようですが、最新の trunk から持ってきたものは 2.6 系でもコンパイル可能なようです。3.0 系で問題ないかどうかは確認していません。
なお、ライブラリ?図書館?とかいうような、コンパイルに関する基礎知識がない状態なら素直にライセンス買った方が早いです。まじで。特にアカデミック向けなら申請だけで無償にて最新版の公式バイナリをダウンロードできるようですので、そちらを強くお勧めします。
コンパイルの実際
VS2008 は非常に使いやすい環境ですので、詳細は割愛します。
先に VC9++、 WSDK、WDK をそれぞれインストールします。なお、 WDK は mfcs42.lib を回収するだけですので、適当な msi を解凍してやってライブラリだけ抽出できればわざわざインストールする必要はありません。これらはどれも非常に重いファイル群なので、それなりのパワーのあるマシンでないとしんどいかもしれません。
で、適当な作業用ディレクトリを作成し、各ソースファイルを持ってきます。Pymol は subversion のブラウジングページから tar ball を引っ張ってきます。Python はインストール用バイナリ (.msi) で構いません。物好きならソースからコンパイルしてもいいと思いますが。 win 向け glut32 も、 libpng/zlib も、VC 向けのプロジェクトファイルが同梱されているので、変換さえ通ればすんなりコンパイルが通るはずです。ライブラリ自体が配布されている場合は直接ライブラリとインクルードファイルを持ってきた方が早いかもしれません。やってないけど。
で、できたライブラリファイルと同梱されてきたインクルードファイル群を一カ所に(lib/inc)纏めます。また、コンパイル時に winappc.h が必要といわれますので、ネットから拾ってきてインクルードファイルのディレクトリに紛れ込ませておきます。
Python
Python のインストールファイルを msiexec で解凍します。
msiexec /a python-2.5.2.msi targetdir=C:\python
最終的に Pymol はこのディレクトリに Python モジュールとしてマージされるので、注意が必要です。また、 distutils の制限回避のため、以下の処置を加えます。
freetype
README では freetype はオプショナル、となっていますが、 Unicode 文字にも対応できるのと、標準ではラベルの文字が汚くてとてもじゃないけど使えたものではありませんので導入することをお勧めします。必要なソースは Freetype プロジェクトの2の方です。 Windows 上で freetype に対応させるには、まず freetype2 をコンパイルするのと、 setup.py に
libs=["freetype2"] def_macros=[("_PYMOL_FREETYPE",None)]
を追加する必要があります。libs にはライブラリディレクトリにコピーした freetype2 のライブラリ(Multithread 対応・非対応どちらでもOK)名を記入。
Pymol
まずは Pymol ソースファイルに含まれている setup.py を書き換えます。
platform == win32 の群で、
("_USRDLL",None), ("_AFXDLL",None)
- ext_link_args に以下を追加
'/LIBPATH:"<WDKのインストールディレクトリ>\\lib\\atl\\i386"','/LIBPATH:"<WDKのインストールディレクトリ>\\lib\\mfc\\i386"','mfcs42.lib','msvcrt.lib'
最終行の
'mfcs42.lib','msvcrt.lib'
は DLLMain の重複宣言回避のため、先に MFC ライブラリを読み込ませた後 C ライブラリを読み込ませるというためのものです。詳細は MSDN を。
リンカ関連の設定は libs/lib_dirs と共通なのでわざわざリンカ引数の形で ext_link_args に書く必要はないです。libs に mfcs42, msvcrt と追記しても通ると思います。ただし、順番を変えるとエラーで填ると思いますので注意。また、パス表記の \ はバックスラッシュと誤認されるのを防ぐため、 \\ と表記するのがよいかと。
下準備
ここまで準備できれば、順次 Pmw と Numpy をインストールします。VS2008 のコマンドプロンプト*1を起動し、各モジュールのソースディレクトリに移動します。
python.exe setup.py install
でコンパイルとインストールが始まります。 Numpy のコンパイルには多少時間がかかりますので、お茶でも飲んで落ち着きましょう。
Pymol のコンパイル
Numpy/Pmw のコンパイルが終われば、いよいよ本丸のコンパイルです。 Pymol ソースディレクトリに移行し、
python.exe setup.py build
でコンパイルが始まります。怒濤の警告表示が出ますが、気にせずスルーしてください。まれにエラーでコンパイルがストップしてしまうことがありますが、上記の設定を見直し、わからなければググってください。
Manifest の埋め込み
できたバイナリ(*.pyd、実態は DLL)にマニフェストを埋め込みます。通常は何もしなくても自動的に埋め込まれるはずですが、○○.dllが見つかりません、などというメッセージが起動時に現れた場合、これを疑ってみてもいいかもしれません。
ビルド後には setup.py に書いてあるように、計九個のバイナリができているはずです。
build\lib.win32-2.5\chempy\champ\_champ.pyd
build\lib.win32-2.5\pymol\_cmd.pyd
build\lib.win32-2.5\pymol\opengl\gl\_opengl.pyd
build\lib.win32-2.5\pymol\opengl\gl\_opengl_num.pyd
build\lib.win32-2.5\pymol\opengl\gl\openglutil.pyd
build\lib.win32-2.5\pymol\opengl\gl\openglutil_num.pyd
build\lib.win32-2.5\pymol\opengl\glu\_glu.pyd
build\lib.win32-2.5\pymol\opengl\glu\_glu_num.pyd
build\lib.win32-2.5\pymol\opengl\glut\_glut.pyd
mt.exe -manifest build\lib.win32-2.5\chempy\champ\_champ.pyd.manifest -outputresource:build\lib.win32-2.5\chempy\champ\_champ.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\_cmd.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\_cmd.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\gl\_opengl.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\gl\_opengl.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\gl\_opengl_num.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\gl\_opengl_num.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\gl\openglutil.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\gl\openglutil.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\gl\openglutil_num.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\gl\openglutil_num.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\glu\_glu.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\glu\_glu.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\glu\_glu_num.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\glu\_glu_num.pyd;2 mt.exe -manifest build\lib.win32-2.5\pymol\opengl\glut\_glut.pyd.manifest -outputresource:build\lib.win32-2.5\pymol\opengl\glut\_glut.pyd;2
を打ち込みます。各々につきコピーライト表記が三行ほど流れ、それ以上何も表示されなければ成功です。
インストール
再び Pymol のソースディレクトリに戻り、
python.exe setup.py install python.exe setup2.py install
でインストールが完了します。Pymol ソースディレクトリに pymol.bat ができているはずですので、これを python ディレクトリに移し、相対パスで起動するように書き換えれば portable な Pymol となります。念のため、再配布する場合は Microsoft Visual C++ 2008 再頒布可能パッケージ (x86) を同梱しておきましょう。 dumpnbin による依存関係情報は
- OPENGL32.dll
- GLU32.dll
- glut32.dll
- MSVCR90.dll
- MFC42.dll
- KERNEL32.dll
- USER32.dll
- ADVAPI32.dll
- python25.dll
となります。VC++ のランタイムと glut32.dll 以外は、ほぼ全て標準でシステムに導入されているものですので大丈夫かと。 glut32.dll は供給元が二カ所ありますが、先にダウンロードした Nate Robbin さんの Windows ポート版、あるいはソースを自分でビルドしたものを同梱しておきましょう。
Unicode ファイル名についての注意
Pymol は非アスキー文字列を含むファイル名を食べさせると親の Python もろともクラッシュしてしまいます。原因が Python/Tk モジュール側なのか、 C の _cmd.pyd モジュール側なのかがわからないので、応急処置として Unicode/UTF-8 文字列を弾いてやります。
\Lib\site-packages\pmg_tk\skins\normal\__init__.py
の def file_open サブルーチン内、544行目の
self.cmd.load(ofile,quiet=0)
を、
regexp = re.compile(r'[^\x20-\x7E]') result = regexp.search(ofile) if result != None : print "Error: Oops! I can't recognize unicode-included file/path name!" else : self.cmd.load(ofile,quiet=0)Loading...
に修正します。インデント注意。
これで完成。
*1:通常の cmd.exe ではないので注意