インストール不要のEWDKにVisualStudio 2013のビルド環境を追加する

  • 追記: IncludePathは別にWindowsSDK_IncludePathで良いみたいなので変更

Visual Studio 2015以降、MSは.zipを展開するだけで使えるビルド環境であるEWDK(Enterprise WDK)を提供している。

EWDKの.zipにはVC++コンパイラMSBuildWindows 10 SDK一式が含まれており、これを展開するだけでVisual Studioを別途インストールすることなくWindowsコードのコンパイルが可能になる。これが非常に便利で、手元のゲームもこれをCIに使用するワークフローに代えようとしている。
問題は、EWDKはVS2015ベースでVS2013のコンパイラを含んでいないことで、一部のレガシーなミドルウェアがVS2013なのでプロジェクト全体をビルドできないという状況になっていた。というわけで、VS2013のツールを追加する。

Microsoft Build Tools 2013 のインストール (MSBuildを使う場合)

残念ながら、VS2013のMSBuildインストーラ無しで安定して使う方法は見当たらなかった。というわけで、こればっかりはMSからダウンロードしてきて別途インストールしておく必要がある。

これをインストールしないと、

  E:\ewdk\Program Files\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Cpp.targets(67,5): error MSB4062: The "SetEnv" task c
ould not be loaded from the assembly E:\ewdk\Program Files\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Build.CppTasks.Com
mon.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v12.0, Version=12.0.0.0, Culture=neutral, PublicKey
Token=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingT
ask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a pub
lic class that implements Microsoft.Build.Framework.ITask. [E:\sdl2\VisualC\SDLtest\SDLtest.vcxproj]

のように必要なTaskがインスタンシエートできずにビルドに失敗してしまう。
Microsoft Build Tools 2013自体はServer CoreなWindows Serverにも導入できるため、これさえ導入しておけば、後はEWDKの.zipとVS2013のコンパイラだけでビルド環境を構築することができる。またプロジェクトがpure C/C++MSBuildを使わないならインストールする必要はない(= フォルダのコピーだけでビルド環境をdeployできる。なのでMSBuildのためだけにインストーラを使うのが大変しのびない。。)。

VS2013コンパイラの展開と配置

VS2013のインストールDVDを用意し、ファイルを適当な場所にコピーする。インストールDVDには大量の.msiが含まれているが、実際に必要なのは4ディレクトリだけで、これらをmsiexecコマンドで展開する。
DVDのファイルを vs2013 ディレクトリ、ewdkをカレントディレクトリのewdkに配置したとして、

msiexec /a vs2013\packages\vc_compilerCore86\vc_compilerCore86.msi TARGETDIR="%CD%\ewdk"
msiexec /a vs2013\packages\vc_compilerCore86res\vc_compilerCore86res.msi TARGETDIR="%CD%\ewdk"
msiexec /a vs2013\packages\vc_compilerx64nat\vc_compilerx64nat.msi TARGETDIR="%CD%\ewdk"
msiexec /a vs2013\packages\vc_compilerx64natres\vc_compilerx64natres.msi TARGETDIR="%CD%\ewdk"

SDKはEWDKに含まれるものがそのまま使用できる。
... ewdkディレクトリに直接展開していることからわかるように、そもそも、EWDK自体が.msiを展開したそのままのツリーを.zipしたもので構成されている。

環境変数の設定

EWDKにはバッチファイル"LaunchBuildEnv.cmd"が含まれており、これを起動すると必要な環境変数を自動的に設定してくれる。
ただ、このバッチファイルによって設定される環境変数は当然VS2015のコンパイラを使うため、VS2013のコンパイラを使うためには追加の設定が必要になる。

set VCInstallDir_120=%BuildLabSetupFilesRoot%\Microsoft Visual Studio 12.0\VC\
set VCTargetsPath=%BuildLabSetupFilesRoot%\MSBuild\Microsoft.Cpp\v4.0\V120\
set VCTargetsPath12=%BuildLabSetupFilesRoot%\MSBuild\Microsoft.Cpp\v4.0\V120\
set WindowsSDK_LibraryPath_x64=%BuildLabSetupFilesRoot%\Windows Kits\10\Lib\10.0.14393.0\um\x64
set WindowsSDK_LibraryPath_x86=%BuildLabSetupFilesRoot%\Windows Kits\10\Lib\10.0.14393.0\um\x86
set WindowsSDK_IncludePath=%BuildLabSetupFilesRoot%\Windows Kits\10\Include\10.0.14393.0\um;%BuildLabSetupFilesRoot%\Windows Kits\10\Include\10.0.14393.0\shared

LaunchBuildEnv.cmdは自身のパスを BuildLabSetupFilesRoot に設定するため、このパスを起点にVCInstallDir_120等の変数を設定する。
微妙に罠なのは、VCInstallDir_120やVCTargetsPathなどMSBuild内でプロパティとして消費され、かつディレクトリを示す環境変数バックスラッシュで終わる必要がある。これはMSBuildの習慣で、忘れると正常にビルドできない。
IncludePathは本来設定する必要は無い気がするが、上手いことVS2013のtoolsetに伝達させる方法がわからなかったので手を抜いている
ビルドにMSBuildを使わない場合は、WindowsSDK_LibraryPath_x86 や IncludePath の内容をコンパイラに自分で与える必要がある。また、CMake等にコンパイラを自動認識させたい場合は、Pathも編集して%BuildLabSetupFilesRoot%\Microsoft Visual Studio 12.0\VC\bin等を先頭に入れ、目的のプラットフォームのcl.exeが直接起動できるようにしておく。