Python環境でVisual StudioのCコンパイラのエラーに困ったら…

Windows環境でPythonを頑張る皆さんお元気ですか?MinGWのGCCを使わずに努力されている勇者もいるかもしれません。そんな同志のための対策メモ書きです。

想定される場面

  • Visual Studio Build Tool環境で“rc.exe が見つかりません”というエラーが出る
  • CythonでVCコンパイラがエラーをはく
  • SwigでVCコンパイラが文句を言う
  • Jupyterノートブックで%%Cythonマジックが上手く機能しない
  • Chainerなどのインストール時にVisual Studioがイヤイヤ期
  • VCコンパイラがcrtなんやらdllが見つからないとか反抗期

リファレンス環境

  • Windows > 7
  • Python > 3.6.0
  • Anaconda > 5.0
  • Visual Studio 2019 Build Tools
  • Visual Studio 2017 Build Tools
  • Visual Studio 2015 Build Tools(2017と両方入っています)

 

 

vswhereのインストール

Visual Studio 2017以降のインストールパスを探し当てるのが中々面倒なので、コマンドラインツールvswhereを使うmicrosoft/vswhereにはVisual Studio 2017以降標準でついてくるとか書いてあるけど、パスの設定や管理が面倒なので、 scoopを使ってインストールします。公式はchocolateyを使おうとか書いてある。

chocolateyではなく、scoopにした理由はWindows開発環境の構築をChocolateyからscoopに切り替えるに詳しい。

scoopの準備

パッケージ管理が楽になるので Scoopを使います。やさしいインストール手順はWindowsコマンドラインツールScoopのすすめ(基礎編) - Qiitaを参照していただいて、vswhereはextrasのbucketに入っているので、これを追加してからインストール。

scoop bucket add extras
scoop install vswhere

対策

vswhereを使う場合

vswhereなどでvcvarsallのパスを特定し、これを呼び出すバッチを実行する

@setlocal EnableDelayedExpansion
@setlocal ENABLEEXTENSIONS
@echo off

REM 使いたいVisual Studioのバージョンを指定
REM Visual Studio 2017ならば15
REM Visual Studio 2015ならば14
REM Visual Studio 2013ならば12
REM Visual Studio 2011以下は別途改造必要
set MSVC_VERSION=15

REM 環境設定とvcvarsall.batのパス取得
if %MSVC_VERSION% GEQ 15 (
    for /f "usebackq tokens=*" %%i in (`vswhere -latest -products * -property installationPath`) do (
      set batch_file=%%i\VC\Auxiliary\Build\vcvarsall.bat
    )
) else (
    set batch_file=!VS%MSVC_VERSION%0COMNTOOLS!..\..\VC\vcvarsall.bat
)
REM vcvarsall.bat実行
@echo on
call "%batch_file%" %processor_architecture%
REM 以下に実行したいコマンドを追加
REM Swigやjupyter notebook, cythonなど…

vswhereを使わない方法

cmd/poweshell

vswhereを利用できない場合、レジストリに登録されているパスを使う。vswhereを使っている行を書き換えてください。

REM Visual Studio 2017のインストール取得用のキー
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"
set VALUE_NAME=15.0

REM 環境設定とvcvarsall.batのパス取得
if "%MSVC_VERSION%"=="15" (
    for /F "usebackq tokens=1,2,*" %%A in (`REG QUERY %KEY_NAME% /v %VALUE_NAME%`) do (
        set batch_file=%%CVC\Auxiliary\Build\vcvarsall.bat
    )
)

Jupyter Notebookの場合

さきのコマンドを実行してからJupter notebook!

これで、cythonマジックは機能するようになりますが、distutilsが基本的にVS2015までしか対応していないようなので、 VS2017の設定でvcvarsall.batを実行しても、VS2015でビルドがされます。 リンカなどは2017のライブラリなどを参照している可能性がありますが、不思議なことにエラーが出ません。

このバッチをmyjup.cmdなどの名前でshift-JISで作業フォルダ以下に保存して使っています。

@setlocal EnableDelayedExpansion
@setlocal ENABLEEXTENSIONS
@echo off

REM 使いたいVisual Studioのバージョンを指定
REM Visual Studio 2017ならば15
REM Visual Studio 2015ならば14
REM Visual Studio 2013ならば12
REM Visual Studio 2011以下は別途改造必要
set MSVC_VERSION=15

REM Visual Studio 2017のインストール取得用のキー
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"
set VALUE_NAME=15.0

REM 環境設定とvcvarsall.batのパス取得
if "%MSVC_VERSION%"=="15" (
    for /F "usebackq tokens=1,2,*" %%A in (`REG QUERY %KEY_NAME% /v %VALUE_NAME%`) do (
        set batch_file=%%CVC\Auxiliary\Build\vcvarsall.bat
    )
) else (
    set batch_file=!VS%MSVC_VERSION%0COMNTOOLS!..\..\VC\vcvarsall.bat
)
REM vcvarsall.bat実行
@echo on
call "%batch_file%" %processor_architecture%
jupyter notebook

 

参考

No comments:

Post a Comment