本文を読み飛ばす

「corecrt.hが(あるのに)見つからない」ためBoostビルド不可、を解決

先日の CMake と Boost の記事を書くために色々と試行錯誤する中で、Visual Studio 2015 をアップデートしたり古い Windows 10 SDK をアンインストールしたりした結果、いつの間にか Boost をビルドできなくなっていた。対策に時間を取られた「b2 の罠」と対策について備忘録。なおビルドできないというのは、具体的には b2 を実行すると次のように corecrt.h が見つからない」というエラーが出る状態のこと:

C:\...\boost_1_63_0>b2 --with-system
...
compile-c-c++ bin.v2\libs\system\build\msvc-14.0\debug\link-static\threading-multi\error_code.obj
error_code.cpp
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\crtdefs.h(10): fatal error C1083: include ファイルを開けません。'corecrt.h':No such file or directory

まず corecrt.h は Windows 10 SDK (ユニバーサル Windows アプリの SDK)に含まれるファイルなのだけれど、自分の環境では次の通り INCLUDE 環境変数に登録されたディレクトリに存在している:

C:\...\boost_1_63_0>where $INCLUDE:corecrt.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt\corecrt.h

問題のファイルは存在しており、そこへのパスが INCLUDE に設定されているのに、見つけられない。ワケが分からない。ともあれ、このままでは困るので、Visual Studio 2015 を丸ごと再インストールしたり、Windows 10 の SDK だけ再インストールしたり、はたまた Microsoft が単独配布している SDK を使ってみたりしたけれど、一向に解決しない。困り果ててインターネット上で情報を探し回ったところ、以下のページで答えを見つけることができた。

いわく %TEMP% ディレクトリの b2_msvc_14.0_vcvarsall_amd64.cmd といった名前のファイルを削除すれば直るとのこと。調べると、確かにそんなファイルが作られていた:

C:\...\boost_1_63_0>dir /s /b %TEMP%\b2*.cmd
C:\Users\suguru\AppData\Local\Temp\b2_msvc_14.0_vcvarsall_amd64.cmd
C:\Users\suguru\AppData\Local\Temp\b2_msvc_14.0_vcvarsall_x86.cmd
C:\Users\suguru\AppData\Local\Temp\b2_msvc_14.0_vcvarsall_x86_arm.cmd

これらの中を読んでみればすぐ分かるけれど、どうやら b2 は毎回これらを内部的に実行することで INCLUDE 環境変数などを適切に切り替えるようだ。そして、自分の環境に残っていたこれらはすでにアンインストールして削除された古い Windows 10 SDK のヘッダーファイル置き場を INCLUDE に指定する内容になっていた。なるほど、そりゃあ存在しないディレクトリを検索対象にしていたって、見つからないね。こういうカラクリで「corecrt.h が見つからない」などという不可解なエラーが出ていたわけか。納得。いろいろ気に入らないけれど理屈は納得。

これらの .cmd ファイルは、各 toolset を初めて使うときに作成され、以後は使い回されるようだ(このあたりの挙動は b2--debug-configure オプションを使うと確認できる)。そして b2 コマンドにこれらを再作成する機能は無い(らしい)。ということは、SDK を新しくインストールしたり、アンインストールしたりした場合はこれらを毎回削除して再作成させた方が良さそうだ。

しかし、b2--reconfigure などのオプションを付けても当該ファイルを更新してくれない。そもそもビルド用のワークディレクトリ以外の場所でワークファイルを作るなよ…と思う。正直、思想レベルでの設計不良という気もするのだけれど、まあ文句言っても仕方がないので注意点として頭の片隅にとどめておこうと思う。