現在位置: ホーム メモ WindowsでFreeなCモジュールビルド環境

WindowsでFreeなCモジュールビルド環境

— カテゴリ:

Microsoftが公式に提供している無料のビルド環境を使って、PythonのCモジュールをビルドします。

このネタの発端は [Python-ml-jp 3324] での発言です。Windows上で、Cで書いたPythonモジュールを手軽に作成&配布できれば、ちょっとした用途でのPythonの使い勝手がかなりあがりますが、そのために有償の環境が必要になってしまっては、誰でも、という訳にいかなくなります。

そこで、Microsoftが無償配布している Microsoft .NET Framework SDK を利用してPythonのCモジュールビルド環境を構築してみます。

必要なパッケージ

以下のパッケージをインストールします。ダウンロードサイズだけで結構な大 きさです。さらにインストール用の容量も必要になるので、HDDの空き容量に は気をつけてください。

Version 13.10.3077 のコンパイラ)を使う問題点

.NET Framework SDK に付属しているcl.exeはVisualStudio.NET 2003のものと 同じもので、Version 13.10.3077、 link.exeは同様に Version 7.10.3077で す。このため、ふつうにビルドした場合に生成されるモジュールは外部依存を static linkしないためmsvcr71.dll等に依存してしまいます。VC7.1のDLLがプ リインストールされているWindowsはほとんど無いため、依存するDLLを作成し たモジュールの配布時に同梱する必要があります [1]

リンカオプションでスタティックリンクするか、あきらめて同梱するか‥‥。 配布相手の事も考えると、PCにVC7.1関連DLLを入れてもらった方が良いと思い ますが、どちらにしろ面倒かもしれません。

[1]Python2.3の場合。Python2.4であればPython自体がVersion 13.10.3077でビルドされているため、Cモジュールを同梱するしない以前に必須です。

パス設定を直接埋め込んでしまう版パッチ

パス設定を直接埋め込んでいるため、環境ごとにパスを書き換える必要がある かもしれません。その代わり、パッチコード自体は単純な作りになっています。

パス埋め込み版パッチをDownload

Python2.3付属の python/lib/distutils/msvcompiler.py (Rev 1.57.6.1) 用 パッチです。Python2.4でも利用は可能です。

一応コード解説

# if cannot find path informatin in registory...
> <span># NEED MICROSOFT SDKs. (VC tookkit, Platform SDK, .NET Framework SDK)
> <span>if 1:
> &nbsp;&nbsp;&nbsp;&nbsp;<span>PlatformSDKDir  = r"C:\Program Files\Microsoft Platform SDK"
> &nbsp;&nbsp;&nbsp;&nbsp;<span>FrameworkSDKDir = r"C:\Program Files\Microsoft.NET\SDK\v1.1"
> &nbsp;&nbsp;&nbsp;&nbsp;<span>VSInstallDir    = r"C:\Program Files\Microsoft Visual Studio .NET 2003"
> &nbsp;&nbsp;&nbsp;&nbsp;<span>dirs = {
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>"path dirs": [
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>PlatformSDKDir  + r"\bin",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>VSInstallDir    + r"\Vc7\bin",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>VSInstallDir    + r"\Common7\IDE",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>FrameworkSDKDir + r"\bin",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>],
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>"library dirs": [
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>PlatformSDKDir + r"\lib",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>VSInstallDir   + r"\Vc7\lib",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>],
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>"include dirs": [
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>PlatformSDKDir + r"\include",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>VSInstallDir   + r"\Vc7\include",
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>],
> &nbsp;&nbsp;&nbsp;&nbsp;<span>}
> &nbsp;&nbsp;&nbsp;&nbsp;<span>return dirs[path]
> <br>
# MSVC 6 seems to create the registry entries we need only when
> <span># the GUI is run.
> <span>if self.__version == 6:

get_msvc_paths() の実装に上記コードを追加します。これで、Pythonが必要 とするVisualStudioのインストール情報がレジストリ上に見つからなかった場 合に、ビルドに必要なパスを設定させることができます。ただ、Python2.3の 場合はVisualStudio6が必要になりますが、今回は強制的にVC7.1相当の環境の パスを返しているため、このあたりで問題が起きる可能性もあり、ある意味よ くないパッチなのかもしれません。

ところで、 Microsoft Visual Studio .NET 2003 というパスがありますが、 これは .NET Framework SDK インストール時に自動的にインストールされたも ので、Visual Studio .NET 2003 をインストールしてあるわけではありません。

動作確認

dotnetonlybuld/thumb?width=320

このパッチを当てた状態で、 PythonからCで書いたモジュールを使う で 使った mod_sample をビルドしたところ、無事ビルドに成功しました! test.pyも問題なく動作します。

ただし、画面にあるように「cl : コマンド ライン warning D4029 : 標準 の編集コンパイラでは最適化は使用できません。」というwarningが表示さ れ、最適化無しでコンパイルされます。これは、.NET Framework SDK に付 属するcl.exeが Visual C++ Starndard と同じもので、最適化機能が無い バージョンだからです。

ところで、cl.exeのパスが Microsoft Visual Studio .NET 2003 になっ ていますが、これは .NET Framework SDK インストール時に自動的にインス トールされたもので、Visual Studio .NET 2003 をインストールしてあるわ けではありません。

.NET Framework SDK の cl.exe バージョン

> "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin\cl.exe"
Microsoft(R) 32-bit C/C++ Standard Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

おまけ1: 最適化コンパイラでビルドする

以下のパッケージをインストールします。

Microsoft .NET Frameowrk SDK に同梱されているcl.exeは最適化機能が搭載 されていません。そこで、 Visual C++ Toolkit 2003 をインストールしま す。このVC++Toolkitには最適化版コンパイラcl.exeやlink.exeが含まれてい るので、これを使えば最適化されたCモジュールを作成することができます [2]

Vusual C++ Toolkit 2003 の cl.exe バージョン

> "C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin\cl.exe"
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

インストールしたら パス設定を直接埋め込んでしまう版パッチ に VC++Toolkit用のパス設定を追加する必要があります。以下のコードは追加分 のコードの断片です。各行を適切な場所に入れましょう(パッチには以下も含 まれています)。

VCToolkitDir = r"C:\Program Files\Microsoft Visual C++ Toolkit 2003"
> <br>
VCToolkitDir + r"\bin",
> <span>VCToolkitDir + r"\lib",
> <span>VCToolkitDir + r"\include",

あとは同じようにビルドを実行するだけです。

[2]今回のようにPythonからWIN32APIを呼ぶためにCモジュールを作るのであれば、最適化は無くても大丈夫かもしれません。

おまけ2: レジストリを検索してパスを自動設定する版パッチ

レジストリキーを検索してパスを設定するため、汎用性は高くなります。が、 うまく動かない場合面倒かも。(コメント等ほとんど入れてないので)

レジストリ使用版パッチをDownload

Python2.3付属の python/lib/distutils/msvcompiler.py (Rev 1.57.6.1) 用 パッチです。Python2.4でも利用は可能です。

参考: 各レジストリキーの場所

Platform SDK:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\*\Install Dir

.NET Framework SDK:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv1.1

VisualStudio.NET 2003:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\Setup\VS\ProductDir

VC++ Toolkit:

HKEY_CURRENT_USER\Environment\VCToolkitInstallDir
ドキュメントアクション