Python の distutils で VS2008 を使ってモジュールをコンパイル

Python の distutils でモジュールをコンパイルする際には、 Python のコアコンポーネントコンパイルされた環境と同一のコンパイラがなければコンパイルできない、という非常に鬱陶しい有名な仕様が存在します。

が、今時 VS2003/2005 をわざわざ導入する気にはなれないのと、 distutils モジュールのソースをいろいろいじくるのは面倒くさいので、以下の設定を行うことでこの制限を回避することができます。

  1. 『HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework』に sdkInstallRootv1.1 を空白文字列でエントリ作成
  2. 環境変数 DISTUTILS_USE_SDK=1 と MSSDK=1 を作成
  3. python setup.py build

追記

これで、無償配布されている VC9 / VC++ 9 Express Edition を使ったモジュールコンパイルが可能となりますが、モジュールによっては VC9 でコンパイルを行った際にマニフェストファイルが要求される場合があります(参照: Visual C++ ライブラリの共有 side-by-side アセンブリとしての配布)。

特に、 distutils は標準でコンパイラオプションに /Md を付与するので、標準 C ランタイムライブラリを利用する場合はエラーに遭遇する可能性が高く(参考: C ランタイム ライブラリ)、同じフォルダに MSVCR90.dll/MSVCP90.dll を配置しても正常にランタイムライブラリを読み込めなかったと怒られることがあります。

[Microsoft Visual C++ Runtime Library]
Runtime Error!

Program: C:\python\python.exe

R6034

An application has made an attempt to load the C runtime library incorrectly. Please contact the application's support team for more information.

C ランタイム エラー R6034

この場合、生成されたモジュールのバイナリファイルに対してマニフェストを埋め込むことで、依存関係を明示し、問題解決に至る場合があります。大抵の場合、 *.pyd という実態は DLL のバイナリを生成することになると思うので、 VS2008 の方のコマンドから

mt.exe -manifest *.pyd.manifest -outputresource:*.pyd;2
方法 : マニフェストを C/C++ アプリケーションに埋め込む

を入力することで、警告は解消されます。

また、コンパイル済みモジュールを再配布する場合は Microsoft Visual C++ 2008 再頒布可能パッケージ (x86) も同梱することを検討する必要があります。コンパイルされたバイナリファイルがどの DLL に依存しているかは、

>dumpbin /dependents *.pyd

でチェックすることができます。