Windows 10＋Anaconda＋Python 3.7でCythonを使う

人からもらったCythonを使っているコードから「Cythonが入ってないからPure Pythonで走るよ、でも遅くなるよ」という警告が出たのでCythonを入れた。
去年同じことをPython 2.7でやったときは、すごく面倒くさかった覚えがあるけど、最新環境でやってみたらあっさり出来た。
めっちゃ昔の情報が錯綜しているので、最短手順を記事にすることにした。

# 最短手順

さらに下に自分の試行錯誤の過程を自分用メモとして書くが、現状の最短手順は以下のようだ。

- 公式サイトから Anaconda をインストール
  https://www.anaconda.com/distribution/
  2019.10 for Windows Installer / Python 3.7 version / 64-bit Graphical Installer
  Anaconda3-2019.10-Windows-x86_64.exe
 
- MSのサイトからVS2019無償版をダウンロード
    Visual Studio 2019 バージョン16.3 Community
    https://visualstudio.microsoft.com/ja/downloads/
    vs_community__1003684730.1571390167.exe

- VSのインストーラーを起動し「Python開発」をインストール

- 同じサイトからVSビルドツールをダウンロード、インストール

 - VS2019と同じサイトに行く
   https://visualstudio.microsoft.com/ja/downloads/

 - 下の方のVisual Studio 2019のツール＞Build Tools for Visual Studio 2019をダウンロード、インストール
    vs_buildtools__1793116473.1569973929.exe

- 以下のファイルを作成し、helloworld.pyxとして保存する

```helloworld.pyx
print("Hello World")
```

- 以下のファイルを作成し、setup.pyとして保存する

```setup.py
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
    
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("helloworld.pyx")
)
```

- 以下のコマンドを実行する

```
python setup.py build_ext --inplace --compiler=msvc
```

- 以下のようなメッセージが出たら成功。

```
C:\work\cython>python setup.py build_ext --inplace --compiler=msvc
running build_ext
building 'helloworld' extension
…中略…
コード生成しています。
コード生成が終了しました。
copying build\lib.win-amd64-3.7\hellowold.cp37-win_amd64.pyd ->
```

# 試行錯誤

上のまとめとめっちゃダブるけど、試行錯誤の過程を書く。
エラーメッセージなどで検索してここに来た人の参考になれば。
OSはWindows 10 Pro (64bit)です。

## Anacondaのインストール

- 公式サイトから Anaconda をインストール
  https://www.anaconda.com/distribution/
  2019.10 for Windows Installer / Python 3.7 version / 64-bit Graphical Installer
  Anaconda3-2019.10-Windows-x86_64.exe

- conda listですでにcythonパッケージは入っていることが分かった
- 目的のコードを実行したが、依然として「Cythonが入ってないから遅くなるよ」という警告が出た。

## VSのインストール

- MSのサイトからVS2019無償版をダウンロードした。
    Visual Studio 2019 バージョン16.3 Community
    https://visualstudio.microsoft.com/ja/downloads/
    vs_community__1003684730.1571390167.exe

- VSのインストーラーを起動し「Python開発」をインストールした。

## setup.pyを起動→vcvarsall.batがないと怒られる

以下のコードを書いた。

```helloworld.pyx
print("Hello World")
```

で、これを以下のコードでCython化しようとしたが、失敗した。

```setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("helloworld.pyx")
)
```

以下の有名なエラーが出た。

```
C:\work\cython\>python setup.py build_ext --inplace --compiler=msvc
…中略…
building 'hello' extension
error: Unable to find vcvarsall.bat
```
## ソースの改変→ビルドツールを入れろエラー

- 以下のサイトを参考にsetup.pyを改変した。
    https://github.com/cython/cython/wiki/CythonExtensionsOnWindows

```setup.py
#from distutils.core import setup

#https://github.com/cython/cython/wiki/CythonExtensionsOnWindows
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
    
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("helloworld.pyx")
)
```

実行したが以下のようなエラーになった。

```
C:\work\cython>python setup.py build_ext --inplace --compiler=msvc
running build_ext
building 'hello' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/
```

## Build Toolsのセットアップ

ビルドツールをインストールした。

- VS2019と同じサイトに行く
  https://visualstudio.microsoft.com/ja/downloads/

- 下の方のVisual Studio 2019のツール＞Build Tools for Visual Studio 2019をダウンロード、インストールした。
　vs_buildtools__1793116473.1569973929.exe

実行したらなんか成功した。

```
C:\work\cython>python setup.py build_ext --inplace --compiler=msvc
running build_ext
building 'helloworld' extension
…中略…
コード生成しています。
コード生成が終了しました。
copying build\lib.win-amd64-3.7\hellowold.cp37-win_amd64.pyd ->
```

なお、C:\work\cythonに、以下のファイル／フォルダーが生成された。

- hello.cp37-win_amd64.pyd
- build
- helloworld.c

## 成功

目標のコードを再実行したら「コード生成しています。／コード生成が終了しました。」というメッセージが表示され、警告なしに実行された。

**（この項終わり）**