背景
-
Windows native の clang-cl では, Windows filesytem 上では case insensitive であるが, しかし case sensitive なファイル名を使わないとワーニング or error が出たりする(e.g.
windows.h
ではなくWindows.h
が正しい) -
Linux 上の clang-cl で, Windows アプリをクロスコンパイルする場合, Linux のファイルシステムが case sensitive(e.g. Ubuntu + EXT4)のため, 一部ファイルが読めないケースがある.
たとえば Windows SDK にあるヘッダファイルだと, 必ずしも include が case sensitive を考慮して記述されているわけではない
(e.g. Windows.h
内で include される SpecString.h
はファイルシステム上は specstring.h
)
-ivfsoverlay
1 の制約および多くの Linux 環境でクロスコンパイルのため Case sensitive でヘッダファイル名を記述します.
しかし, 2 の Windows SDK ヘッダの問題から, 一部 case insensitive で扱わねばらならないケースが出てきます.
clang 独自で, ファイルの扱いを制御できます. ここで case sensitive かどうかも設定できます.
(本来は, VFS(Virtual File System)用で特定のファイルを別のファイルにリダイレクトとかするのに使われるっぽい)
ちょっとめんどいですが, 以下のように yaml に制御したいファイルパス列挙と, case sensitive: false
を記入し
version: 0
case-sensitive: false
roots:
- name: "/mnt/c/winsdk/Include/10.0.18362.0/um"
type: directory
- name: "Windows.h"
type: file
external-contents: "/mnt/c/winsdk/Include/10.0.18362.0/um/Windows.h"
...
clang 独自オプションの -ivfsoverlay
で yaml ファイルを指定します.
-Xclang -ivfsoverlay -Xclang vfs_overlay.yaml
clang 独自オプションの場合は 毎回 -Xclang
を prefix として付与が必要です(後続のオプションが clang 独自のオプションであることを指定)
yaml の作り方など詳細は LLVM の WinMsvc.cmake generate_winsdk_vfs_overlay を参照ください.
MinGW との兼ね合い
ちなみに MinGW gcc/clang の場合は全部小文字でないとだめかもしれません(clang VFS overlay 的な機能は無さそうなので).
現状, mingw gcc, llvm-mingw など MinGW ヘッダベースのコンパイラ環境は, ヘッダファイルを全部小文字化しているため,
#ifdef __MINGW32__ // mingw gcc, llvm-mingw(clang)
#include "windows.h"
#else // MSVC, clang-cl
#include "Windows.h"
#endif
のようにして切り分けで対応するしかなさそうです.