Windows での Python 2.7, 3.4, 3.5 の拡張モジュールビルド環境


Windows 用に Python のバイナリパッケージを作成するときに知っておいたほうがいい基礎知識や便利情報をまとめて書いていきます。

## Windows でのバイナリパッケージの重要性について

Windows 上で Python を使っているユーザーは、 Python の拡張モジュールをビルドする環境を持っている可能性はとても低いです。
もともと Mac に比べてコンパイラをインストールしているユーザーが少ない上に、 Mac 版では OS のバージョンごとにコンパイラが固定されるのに対して、 Windows では OS ではなく Python のバージョンによってコンパイラのバージョンが決まるという事情もあり、自分で調べて Python の開発環境を揃えている人以外が適切なコンパイラをセットアップしている可能性はゼロに近いです。

一方で Windows では python.org が提供する公式バイナリが強い標準になっており、サードパーティが配布している Python 環境もほぼバイナリ互換になっているため、バイナリパッケージを配布することでユーザーが自分でビルドすること無く Python の拡張モジュールを利用することができます。
コンパイラのバージョンがOSに紐付かないというのも、バイナリパッケージの提供側にとっては複数のOSバージョンを用意しなくていいというメリットになります。

そこで、拡張モジュールを含むパッケージの提供者は、できれば Windows のバイナリパッケージを用意することが推奨されます。

最近では、自分の Windows に Windows SDK や Visual Studio みたいな重いツールをインストールしたくないという人でも、 EC2 や Azure、 GCP などで、 Atom などより強力なCPUを使った Windows 環境を時間課金で利用できます。

## 複数バージョンの Python のインストールと py コマンドについて

標準のインストール先ディレクトリは、 Python 3.4 であれば `C:\\Python34` の様になっています。変更することも可能ですが、スペースを含むディレクトリはトラブル回避のために避けておきましょう。

64bit 版と 32bit 版両方をインストールする場合は、デフォルトのインストール先が同じになっているので、片方を `C:\\Python34_amd64` などと変更しておきましょう。インストールオプションで IDLE や TK, tests, ドキュメント などを外しておけば少し軽量になります。

Python 3.3 以降をインストールするときに、 `py` という Python ランチャーがインストールされます。
このランチャーは `py -3.4` とすると 64bit 版の Python 3.4 が、 `py -2.7-32` とすると 32bit 版の Python 2.7 が起動します。
これを使うと、長いフルパスを何度も入力したり、 PATH の設定をビルドごとに切り替えたりしないでいいので便利です。 `setup.py` を実行するときだけでなく、 `pip` コマンドを実行するときも `-m` オプションと合わせて `py -2.7-32 -m pip` のように実行できます。

## Wheel について

Python は標準でインストーラー (exe や msi) 形式のバイナリパッケージをビルドすることができます。
しかしこの形式のパッケージは pip install できませんし、 virtualenv の中にインストールすることもできません。 (そのことに目をつむれば、 Windows に慣れたユーザーにとっては良い配布方法です)

現在推奨されている、 pip install できるバイナリパッケージは [wheel](https://pypi.python.org/pypi/wheel) になります。

wheel をビルドするには、 `pip install -U wheel setuptools` で最新版の wheel と setuptools を用意したうえで、 `python setup.py bdist_wheel` というコマンドを利用します。

なお、 wheel はバイナリパッケージですが、 pure Python のライブラリを配布する場合も `.tar.gz` よりインストールが速いなどのメリットがあるので積極的に使っていきましょう。

## MSVCRT について

C言語やC++言語で書かれたプログラムを動かすときに、そのランタイムライブラリと呼ばれるライブラリが必要になります。このライブラリには fopen や malloc といった標準ライブラリ関数などが格納されています。

Visual C++ コンパイラが利用しているランタイムライブラリが MSVCRT です。これはコンパイラバージョンごとに用意されています。
VC のバージョンは VS のバージョン (年号) と一致しないので注意が必要です。

1つのプロセスが複数の MSVCRT のバージョンを同時に利用することは可能ですが、できれば統一しておいたほうが安全です。
そのため、 Python の拡張モジュールをビルドするときは、公式の Windows 版 Python をビルドするのに利用された VC を利用するべきです。

| VSバージョン | VCバージョン | Python |
|:----------:|:-----------|:-------|
| 2008       | 9          | 2.7    |
| 2010       | 10         | 3.4    |
| 2012       | 11         |        |
| 2013       | 12         |        |
| 2015       | 14         | 3.5    |


## Python 2.7

Python 2.7 用の VC はもう5年も前のものなので、今さら用意するのが面倒でした。

幸いなことに、今年 Microsoft が [Microsoft Visual C++ Compiler for Python 2.7](http://www.microsoft.com/en-us/download/details.aspx?id=44266)
を提供してくれるようになったので、これをインストールするだけで Python 2.7 の拡張モジュールのビルド環境ができあがります。

ビルドするときは、特に環境変数等気にしなくてもレジストリから探して利用してくれるので、普通にコマンドプロンプトからコマンドを実行するだけです。次の例では、 32bit 版と 64bit 版それぞれに wheel を作っています。作られた wheel は `dists/` ディレクトリ配下にあり、 `pip install` 可能です。

```console
> py -2.7-32  setup.py bdist_wheel
> py -2.7-x64 setup.py bdist_wheel
```


## Python 3.4

無料で VC を手に入れる手段として、 Visual Studio の Express Edition や最近出た Community Edition があります。

残念ながら Community Edition で入手できる VC は 11 なので、 Python 3.5 を待つ必要があります。
Visual Studio 2010 Express Edition もそろそろ入手経路を探すのが面倒になってきています。軽くぐぐっても上位には 2012 のサイトしかありません。
また、 VS 2010 Express Edition では 64bit コンパイラが使えないという制限がありました。これでは 64bit 版 Python のバイナリパッケージを用意することができません。

そこで、 Visual Studio ではなく [Windows SDK 7.1](http://www.microsoft.com/en-us/download/details.aspx?id=8279) をインストールしておきましょう。インストール時にインストールする部品を選択できるので、 x86 と amd64 の C++ コンパイラだけ選択しましょう。

Windows SDK を使う場合、Visual Studio と違って Python が自動的にレジストリからコンパイラを検出してくれないので、環境変数を設定しておく必要があります。
SDK をインストールした時にスタートメニューに "Windows SDK 7.1 Command Prompt" というコマンドプロンプトのショートカットが作られるので、それをコピーして、 Python 拡張ビルド用のショートカットを用意しておきましょう。ショートカットの"リンク先"を下記の用に設定し、作業フォルダーは自分の作業するフォルダーに指定しておきます。

リンク先 (Windows SDKのインストール先を変更した場合はその部分を書き換えてください):

```console
> # 32bit版
> C:\Windows\System32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /Release /x86
> # 64bit版
> C:\Windows\System32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /Release /x64
```

あとは、それぞれのショートカットから起動して、 2.7 のときと同じようにコマンドを実行するだけです。

```console
> # 32bit版
> py -3.4-32  setup.py bdist_wheel
> # 64bit版
> py -3.4-x64 setup.py bdist_wheel
```

## Python 3.5

Visual Studio Community Edition が使えます。 Python 2.7 と同じく何の苦労もなく拡張モジュールをビルドすることができます。

また、 [Visual C++ Build tools](http://blogs.msdn.com/b/vcblog/archive/2015/11/02/announcing-visual-c-build-tools-2015-standalone-c-tools-for-build-environments.aspx) のベータ版が発表されました。
未検証ですが、これを使えば Python 2.7 と同じように重量級の Visual Studio をインストールしなくても必要なコンパイラーなどのツール一式が手に入ると思います。

## 動作確認とアップロード

できた wheel は、 `pip install` でインストールしてテストしてから PyPI にアップロードしましょう。
PyPI にアップロードするには、 `py -3.4-32 setup.py bdist_wheel upload` のように setup.py を使う手段もありますが、テストしたあとに wheel を作り直す事になってしまいます。

[Pytohn Packaging User Guide](https://packaging.python.org/en/latest/current.html) によれば、現在推奨されるパッケージのアップロード手段は [twine](https://pypi.python.org/pypi/twine) になります。 twine は1つの Python にだけインストールするだけで、全ての Python 用のパッケージをアップロードできます。

```console
> py -3.4 -m pip install -U twine
> py -3.4 -m twine upload dist/yourpackage-1.2.3-*.whl
```

## まとめ

* python.org が配信している、最新版の Python 2.7 と Python 3.x を、32bitと64bit版両方インストールしておこう
* 複数バージョンの Python を利用するのには py ランチャーが便利
* Python 2.7 用に Microsoft Visual C++ Compiler for Python 2.7 をインストールしよう。
* Python 3.4 用に Windows SDK 7.1 をインストールしよう。利用時に設定が必要なのでショートカットを作っておくと便利
* Python 3.5 用には Visual Studio Community Edition (あるいは Visual C++ Build tools) をインストールしよう。
* setuptools と wheel の最新版をインストールしておき、 `setup.py bdist_wheel` で wheel 形式のパッケージを作ろう
* 動作確認後、 twine を使って PyPI にアップロードしよう。