2
0

More than 1 year has passed since last update.

clang-cl + cmake + ninja で Windows バイナリのコマンドラインビルド, クロスコンパイルのメモ

Last updated at Posted at 2021-04-15

背景

  • clang(-cl) を Windows コマンドライン, Linux(WSL) で動かし, MSVC 互換でコンパイルしたい
  • ビルドには cmake, ninja を使う

Windows バイナリのビルドは, llvm-mingw がおすすめですが, MSVC 互換オプションでビルド確認したい, MSVC ビルドの補助として clang-cl でビルド CI を構築したい, etc など, clang-cl を使いたいときもあります.

clang-cl とは?

の windows prebuilt や, Visual Studio インストーラー, C++ Build Tools インストーラーとかでもインストールできます.

clang での, MSVC の引数(と, MSVC 用 ABI とか?)の互換性のあるコンパイルモードです.
ただ, コンパイル自体は MSVC 互換というわけではないため, 細かいところでは違いがあります(builtin 命令とか)
icc(Intel C Compiler)みたいな感じで使う感じでしょうか.

動作モードは, --drver-model もしくはコマンドの起動名(exe 名)で MSVC モードにするかどうか判断しています.

したがって, clang --driver-mode=cl でも MSVC モードになりますす.

--driver-mode は引数のどの位置にあっても大丈夫そうです.

clang /I. --driver-mode=cl muda.cc

もいけました.

clang 自体が target 設定で cross-compile できますので, クロスコンパイル時(Linux/WSL でのビルド時)の clang-cl 自体は Linux binary(ELF)を使うことができます.

Windows SDK

Header やリンクライブラリ(.lib)として, Windows SDK が必要になります.
(MinGW でも行けるかも?)

オンラインに Licensing term が上がっていないのですが, 一応 Windows SDK を, Windows SDK installer で入れて, Licneses フォルダのライセンス条項を見てみました.

Windows 向けのアプリを開発する, 自社(自身)のネットワーク内でエンドユーザーとしての利用にかぎる, 以外は特に制約もない感じでしたので, 少なくとも header/lib のファイル群を Linux に持って行って clang-cl でクロスコンパイルに使うのはライセンス上問題ないでしょう.

Windows 側で作業する場合, Visual Studio 2019 or C++ Build Tools https://visualstudio.microsoft.com/visual-cpp-build-tools/ でも Windows SDK をインストールできます.

デフォルトでは, C:¥Program Files (x86)¥Windows Kits¥10 にインストールされます.

Microsoft STL

なぜか無駄に新しい環境を要求されます(e.g. cmake 3.16)

boost 依存(!)してつらいのですが, 実際に利用しているのは math 関数での特殊関数を(e.g. bessel)を実装しているところだけです. したがって bcp あたりで math 部分だけ抜き出した boost パッケージでうまくビルドできるのではないかと思います.

boostの一部のみを使う
https://qiita.com/kk-river/items/999dd21adaddd7d53b81

Boost を Android 向けに bjam ビルドするテクニック(NDK r19c or later)
https://qiita.com/syoyo/items/dbc063a54554be9226a5

残念ながら, 現状 Cmake では clang-cl でのビルドには対応していません.
いろいろ頑張れば clang-cl でもコンパイルできるかもしれません
(MSVC headers/lib も必要)

MSVC headers/sdk

あたりを参考にして, aka.ms あたり経由でオフラインバッチで Windows SDK と MSVC headers/sdk 落とせます.

ただ, MSVC headers/sdk 含め, MSVC standalone compiler(C++ Build Tools)も落とせますが, これは Visual Studio のライセンスと一緒に使うときのみライセンス許諾なので注意ください.

Microsoft C++ Build Tools (2019) not allowed for use with Visual Studio Code?
https://law.stackexchange.com/questions/49477/microsoft-c-build-tools-2019-not-allowed-for-use-with-visual-studio-code

にあるように, Microsoft 自身がライセンス違反をしてそうなチュートリアル公開していますがどうなんでしょうかね?

MSVC headers/libs だけ clang-cl で利用する場合はどうなるかな?

CMake

単に clang-clCMAKE_CXX_COMPILER にしても, 通常の gcc/clang モードと判定されてしまします.

cmake では, MSVC 用の環境変数などが設定さているかどうかで, MSVC モードかどうかを判定しているようです(詳細は cmake のソースコードを解析すればいけるが, 面倒なので見調査)

環境設定(MSVC 利用)

今までは vcbarsall.bat が使われていたようですが, VS2017 くらいから vsdevcmd.bat が推奨になっているようです.

バッチスクリプトでは, 以下のように call コマンドを使います.

call <msvcpath>¥vsdevcmd.bat

<msvcpath>は VS ごとに変わります. C++ Build Tools(2019) だと, デフォルトでは

C:¥Program Files (x86)¥Microsoft Visual Studio¥2019¥BuildTools¥Common7¥Tools

あたりにあります.

環境設定(MSVC を利用しない版)

を参照ください.

Target triple

`x86_64-windows
T.B.W.

TODO

  • msvc-wine あたりでの設定を参考にして環境変数設定することで, vsdevcmd.bat を呼ばずにビルドできるようにする.
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0