ClangのWindowsネイティブ版clang-cl
ねんがんの ウインドウズClang をてにいれたぞ!
http://isocpp.org/blog/2014/01/llvm-3.4
clang3.4からWindowsネイティブを吐くバイナリが作れるようになりました。
clang-cl
clang自体にWindows用のバイナリをはき出すモードがつきましたが、お手軽に使えるように「clang-cl」という専用の実行ファイルがありますのでそれを使います。
「clang-cl」はVCのコンパイラである「cl.exe」と互換があるように作られていて、オプション・ABI互換があるそうです。
その代わり、clang-clのC++11/14対応はVCと進度を合わせているようです(VCでの実装仕様公開待ちしてるということっぽい?)。そのため、clang3.4の目玉であるC++14への完全対応はclang-clでは行われていません。コンパイルオプションで「-std=C++1y」を指定してもはじかれます。(そもそも-stdオプションが使えません)
使い方
VS2012のToolChainをバックグラウンドで使うので、VS2012がインストールされている必要があります。
VS2012がインストールされていたら、お馴染み「vcvars32.bat」を叩いてパスを通すか、スタートメニューから「VS2012 の開発者コマンド プロンプト」を起動します。
あとは、Clangへのパスが通ってれば、
clang-cl cppファイル <オプション>
でコンパイルリンクされ実行ファイルができます。
コンパイルオプション
基本的には、VCのコンパイルオプションを使います。まだすべてに対応しているわけではありませんが、良く使うものにはほぼ対応してるので、よほど特殊なことをしてない限りは困らないと思います。
対応してるコンパイルオプションは、
clang-cl /?
で見るか、
http://llvm.org/releases/3.4/tools/clang/docs/UsersManual.html#clang-cl
に載ってます。
他にもclangコアオプションに対応してるとあったので、-W系あたりはなんでも使えそうです。
WindowsSDKへのパス
WindowsSDKへのパスはインクルードパスは通ってますので、windows.h も普通にincludeすれば使えます。しかし、ライブラリパスは通ってないので、ライブラリはフルパスで指定する必要があります。
「/LIBPATH:」はまだ対応されてないので、
/link /I <ライブラリパス>
とかしてみたのですが、上手く動きませんでした。
テストコード
実行すると左上にtestと表示されたウインドウが生成されるだけ
// a.cpp #include <windows.h> #include <stdio.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; ::ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(wc); wc.hInstance = hInstance; wc.lpfnWndProc = &WndProc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hIcon = NULL; wc.hIconSm = NULL; wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "clang-cl test"; ::RegisterClassEx(&wc); HWND hWnd = ::CreateWindowEx(0, wc.lpszClassName, wc.lpszClassName, WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100,100, 654, 494, NULL, NULL, hInstance, NULL); ::ShowWindow(hWnd, SW_SHOWNORMAL); while(1) { MSG msg; LRESULT r = ::GetMessage(&msg, NULL, 0, 0); if(r==0||r==-1) { return 1; } else { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } return 0; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_PAINT: { HDC hDC = ::GetDC(hWnd); ::TextOut(hDC, 0, 0, "test", 4); ::ReleaseDC(hWnd, hDC); } return 0; case WM_DESTROY: PostQuitMessage( 0 ); return 0; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }
clang-cl a.cpp "<WindowsSDKへのパス>User32.lib" "<WindowsSDKへのパス>Gdi32.lib"
a.exe ができます。
プロジェクト
さすがにプロジェクトファイルを渡してのビルドはできないようですので、makeの力を借りる必要があるようです。誰かがVS上でclang-clを叩けるようにするアドインを作ってることを期待
アドインなしでVSからclang-clを叩くようにするバッチが元々付いてたようです。
詳しくは↓の記事