昔 Windows 上での Visual C++ と GCC/Clang の相互運用という記事を書いてましたが、さっき調べたらオリジナルの LLVM (Clang/C2 ではない)を Visual Studio のプラットフォームツールセットとして使うことができて MSVC とちゃんと互換性があるということを知りました。
まず LLVM のダウンロードページで pre-built binary を取ってきてインストールして、 Visual Studio Marketplace にある LLVM Compiler Toolchain をインストールします(現時点では VS2019 preview には未対応らしい)。こうすると Visual Studio のプロジェクトの「プラットフォームツールセット」のところに LLVM が出てきます。
LLVM を選択すると LLVM のバイナリを使うかどうかとその場所を指定するページが追加されます。 pre-built binary だけでなく自分でビルドしたものを指定することもできるようです。
互換性についてですが、 Visual Studio Extension のページにはこう書いてあります。
- プリコンパイルヘッダを無効にする必要があるかもしれない。
- LTCG (Link-Time Code Generation: リンク時コード生成)と PGO (Profile Guided Optimization: ガイド付き最適化)とは互換性が無いので無効にする必要がある。(訳注:LTCG などを有効にしたスタティックライブラリとリンクすることはできない、ぐらいの意味だと思われるが、LLVM の LLD ではなく Microsoft の LINK を使えばリンクだけならできる気がする)
- cl.exe の不明な(訳注:文書化されていない、ぐらいの意味だと思われる)オプションはサポートされない。
いくつか気になる点を非常に軽く確認してみたところ、
- 呼び出し規約には互換性がある(当たり前だ)
- C++ 名前修飾にも互換性がある
- 例外を投げても互換性がある
- デバッグ情報にも互換性がある
という感じで文句がありません。
一方、以下の(マイナーな)問題にぶつかりました。
- Visual Studio のプロパティページ上では拡張命令セットの指定が SSE/SSE2/AVX/AVX2 しかないので、例えば SSSE3 までの intrinsic を有効にしたい場合は手書きで
-mssse3
といったオプションを指定する必要がある。 cl.exe の場合は SSE2 を指定しても SSE4.2 までの intrinsic が使えてしまう。 - 出力ディレクトリや中間ディレクトリのデフォルト値が異なる。 x64 の場合、 cl.exe だと出力ディレクトリが $(SolutionDir)$(Platform)\$(Configuration)\ となるが、 LLVM だと $(SolutionDir)$(Configuration)\ となり $(Platform)\ が入らない。結果として x86 と x64 で混ざってしまう。(明示的に指定すれば問題は無い)
- ARM64 をターゲットとしたクロス開発はできない。(自前で頑張ってツールセットをビルドして…とかやらないといけない)
Ut Video Codec Suite ではインラインアセンブラを使うために一部のソースファイルは Cygwin の GCC でコンパイルするようにしてあって若干気持ち悪いのですが、全体を Clang でビルドすればそんなことしなくて良くなるわけで、こっちの方がいいのでは…? という気がしています。
ちなみに GCC で同じレベルで Visual Studio への統合ができるのかですが、雑にググった限りでは公式では用意されていないようです。もちろん自前でツールセット定義を書けばある程度いけるんでしょうけど、名前修飾にすら互換性が無いので C ならともかく C++ では使い物になりません。
no comment untill now