Visual Studio (up to 2019) のコマンドラインでの C/C++ コンパイル環境

[nim](https://nim-lang.org/) が VC++ コンパイラ `cl.exe` を見つける方法を調べる過程で、Visual Studio のコマンドライン C/C++ コンパイル環境について分かったことをまとめておきます。

# 概要

VC++ の C/C++ コンパイラは `cl.exe` という名前のコンソールプログラムですが、`cl.exe` の位置を調べて起動すればすんなりコンパイルできるという訳ではありません。

というのも、Windows で C/C++ のプログラムを開発する場合は、いわゆる標準の C/C++ プログラムを記述することはむしろ稀で、多くの場合、Win32 API や .NET Framework なども利用します。

このとき、これらの SDK のヘッダファイルやライブラリファイルを見つけられるように、`INCLUDE`, `LIB`, `LIBPATH` といった環境変数を適切に定義した上で `cl.exe` を呼び出す必要があります。

Visual Studio には、`vcvarsall.bat` というバッチファイルが含まれており、このバッチファイルを実行することで、`INCLUDE` などの環境変数が定義された状態のコマンドプロンプトを起動できます。
![2019-06-21_10-56-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35311/9ca49999-78d4-9d39-da48-40ef7304e095.png)
そういうわけで、Visual Studio の C/C++ ビルド環境を準備するには、`vcvarsall.bat` を見つけて実行するのが、おそらく最も簡単かつ一般的な方法だと思います。

ただし、ターゲットが 64/32 ビット、ビルド環境が 64/32 ビット、といった複数のビルド環境の組み合わせが存在するため、バッチファイル `vcvarsall.bat` には、それらを指定するための引数も渡すことに注意して下さい。

また、Visual Studio のバージョンによって、バッチファイルの名前や呼び出し方など、若干異なる可能性もありますので、そのような場合は本記事に書かれていることを状況に応じて読み替えて下さい。

# ショートカット利用

`vcvarsall.bat` を実行するには、Visual Studio インストール時に作成されたショートカットを使うのが多分一番簡単です。
![2019-06-21_11-18-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35311/7becb5e4-4a47-a83c-c1c3-d7636796c73e.png)
ショートカットがいくつもありますが、現在の OS のアーキテクチャと、ビルドしたいプログラムのターゲットアーキテクチャの組み合わせで

* 64 ビット OS で 64 ビットプログラムをビルドするなら **x64 Native**
* 32 ビット OS で 32 ビットプログラムをビルドするなら **x86 Native**
* 64 ビット OS で 32 ビットプログラムをビルドするなら **x64 x86 Cross Tools**
* 32 ビット OS で 64 ビットプログラムをビルドするなら **x86 x64 Cross Tools**

を選択します。

# 自分でバッチファイルを呼び出す

上記のショートカットを利用する方法が使えない場合（例えば何らかのビルドプロセスに `vcvarsall.bat` の呼び出しを組み込まざるをえないケース）には、`vcvarsall.bat` の場所を見つけ出す必要があります。

## Visual Studio 2008-2015

バージョン 2015 以前の Visual Studio のインストーラは、システム起動時に `VS*COMNTOOLS` という環境変数が定義されるように、システム設定を変更していました。

定義される環境変数名と Visual Studio バージョンの対応は以下の通りです：

* `VS90COMNTOOLS` = Visual Studio 2008
* `VS100COMNTOOLS` = Visual Studio 2010
* `VS110COMNTOOLS` = Visual Studio 2012
* `VS120COMNTOOLS` = Visual Studio 2013
* `VS140COMNTOOLS` = Visual Studio 2015

たとえば、 Visual Studio 2015 の `VS140COMNTOOLS` の場合、デフォルトのインストール場所であれば

```
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\
```

のような値が設定されているはずです。

この環境変数が指し示すディレクトリにも `vsvars32.bat` というそれっぽいバッチファイルがありますが、これはひとまず無視して、ディレクトリ階層を二つ上がったところにある `VC` というディレクトリを見て下さい。

```
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\..\..\VC

つまり

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
```

ここにお目当ての `vcvarsall.bat` があります。

あとは、例によって、現在の OS のアーキテクチャと、ビルドしたいプログラムのターゲットアーキテクチャの組み合わせで

* 64 ビット OS で 64 ビットプログラムをビルドするなら `vcvarsall.bat amd64`
* 32 ビット OS で 32 ビットプログラムをビルドするなら `vcvarsall.bat x86`
* 64 ビット OS で 32 ビットプログラムをビルドするなら `vcvarsall.bat amd64_x86`
* 32 ビット OS で 64 ビットプログラムをビルドするなら `vcvarsall.bat x86_amd64`

のようにすれば適切なビルド環境（環境変数）が手に入ります。

## Visual Studio 2017-2019

Visual Studio 2017 以降（本記事執筆時点では Visual Studio 2019 まで確認）からは、`VS???COMNTOOLS` という環境変数がインストーラによって設定されなくなったので[^1]、前節のテクニックは使えません。

デフォルトでは（エディションの部分は適宜読み替えてもらう必要がありますが）

```
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC

や

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC
```

あたりに VC++ がインストールされているので、その下の `Auxiliary\Build` というディレクトリ、すなわち

```
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build

や

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build
```

を探せば、`vcvarsall.bat` が見つかります。
![2019-06-21_11-45-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35311/9bd94b9d-7eba-4bda-e479-6980740ea777.png)
ご丁寧にも、プラットフォームの組み合わせに応じた個別のバッチファイルすら用意されているので、`vcvarsall.bat` の代わりに、適切なプラットフォームのバッチファイルを引数無しで実行しても構いません。

なお、VC++ をデフォルト以外の場所にインストールした場合には、[vswhere](https://github.com/Microsoft/vswhere) というツールで VC++ のインストール場所を表示させることも出来ます。

2017 以降の Visual Studio がインストールされているなら、`C:\Program Files (x86)\Microsoft Visual Studio\Installer` 以下に `vswhere` もインストールされているはずです。

`vswhere` を単純に実行すると大量の情報が表示されてしまうので、インストール場所だけ抽出表示するには、以下のようにします：

```
vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
```

すると、こんな感じで、VC++（というか VS）のインストール場所が表示されます。
![2019-06-21_11-48-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35311/2ac02cdf-4eef-1812-8aa1-59380b0e4a24.png)

あとは、その下の `VC\Auxiliary\Build` というディレクトリを辿れば、`vcvarsall.bat` ファミリーが見つかります。

[^1]: インストール時には `VS*CMNTOOLS` という環境変数は設定されませんが、`vcvarsall.bat` を実行した後には、VS 2017 なら `VS150COMNTOOLS`、VS 2019 なら `VS160COMNTOOLS` という環境変数が定義されているようです。