LLVM Clang の Windows へのインストールと使い方

C, C++ 言語のコンパイラーといえば、 Windows では Visual Studio 、 Unix 系では gcc(g++) というのが多いです。 そんな中、最近 Clang があちこちで使われ始めるようになってきました。
今回はこの Clang の Windows へのインストール方法と使い方について説明します。

Clang とは

ClangLLVM で作られた C, C++, Objective-C, Objective-C++ のコンパイラーです。 LLVM(Clang) の開発には Apple や Google などの企業も参加、資金提供しています。
Clang はgcc の代替を狙っており、 Apple の後押しが大きく、 Mac ではすでに主要なコンパイラーとなっているらしいです。さらに Mac だけでなく、Unix や Windows などクロスプラットホームで使われるようになってきました。

因みに Clang の発音は「クラン」が近いみたいです。 最後の g は HongKong(香港)や Erlang(アーラン)のように日本人にはほとんど聞き取れない音です。

Clang を使うメリット

Clang のメリットとしてよく言われるのが、エラーメッセージが分かりやすいという点です。
C++ では STL などのテンプレートを使った際のコンパイルエラーのメッセージがわかりづらく、 メッセージを見ても、どこが悪いのか、どう直せばいいのか、といったことがわからないといったことが発生します。 それが解消されるということです。

ただ、個人的には Visual Studio のエラーメッセージと違い、英語になってしまうので、 それはそれでつらいかなとは思います。

Clang が広まる意義

前節のメリットを聞いても、そこまで「よし、 Clang に変えよう」と思う人は少ないかもしれません。 しかし、 Clang が広く使われるようになることの意義は単に C++ のコンパイラーの選択肢が増えるということに留まりません。

それは LLVM がコンパイラー基盤といって、これが実はかなり有益な仕組みであるためです。 Clang は正確にいうと LLVM のフロントエンドプログラムにあたります。 LLVM については上記の記事に説明を書いているので、 ここでは簡単に説明します。
LLVM では仮想マシン(VM)のようにソースの解析後、一旦中間コードにします。 それを LLVM が提供する機能を使って、 最適化実行ファイルの生成 を行います。

フロントエンドは最初のソースの解析から中間コードへの変換を主に担当し、 その C++ 用のものが Clang です。
vm_llvm.png



Clang がエラーメッセージがいくら分かりやすくなっているからといっても、 やはり gcc の最適化の能力と広く移植されている点はすごいものです。 gcc は多くの人が長い時間を書けて作っているのですから、それも当然です。

Clang も広く使われるようになり、開発が進んで、 gcc と同等の最適化や移植性もつことを想像してみてください。
Clang がその能力を持つということは LLVM がその能力を持つということを意味します。 新しい言語を作ろうと思った場合、一人で gcc ばりの最適化や移植は不可能です。 しかし、 LLVM では中間コードを生成するところまで作れば、 その能力を手にしたコンパイラーを作ることができます。

Microsoft や Google といった大企業や GNU のような大きなコミュニティーでなくてもいいわけですから、 一人のセンスのいいプログラマーがいれば、優れたコンパイラーをもった言語ができます。 素晴らしい言語が次々生まれる予感がして、 言語好きとしてはワクワクしてしまいます。

C++11, C++14 対応

そうしたわけで、 Clang はぜひ広まって欲しいと思っています。 ただ、「では自分は」というと、いろんなシガラミもあり、そうそうコンパイラーを変更することはできません。
しかし、 Clang はもう一つ大きな利点があります。 それは Clang がいち早く C++11, C++14 に対応した点です。 C++14 を一足先に試してみたいということで Clang を使ってみました。

C++ の言語仕様は長らくあまり変わっていなかったのですが、 C++11 で大きな機能追加があり、 C++14 でその補足的な機能追加がありました。
C++14 の 14 は 2014 年のことで、つい最近です。 C++11 の変更が大きく、他のコンパイラーがその対応もおぼつかない中、 C++14 の対応は異常だと感じるほどでした。

ただ、この利点はしばらくしたら、なくなってしまう利点です。 実際、 GCC も最近 5.1 で C++11 に完全対応し、実験的位置づけですが C++14 にも対応しました。
とはいえ C++17 など C++ の今後もっとよくなっていく気配を感じると Clang の対応の早さは期待が持てます。

因みに Visual Studio に関しては C++11 もまだまだという感じです。

gcc 互換か VS 互換か

Clang は gcc 互換を目標に開発されていますが、 同様に Visual Studio (Visual C++)互換も開発されています。

VS での C++ のコンパイルには内部で cl.exe を使用しています。 これと互換の clang-cl があります。
ただし、 clang-cl では C++11/14 への対応も cl に合わせているため、 C++14 対応の恩恵は得られません。


この記事では gcc 互換、 VS 互換の両方を解説していきます。

インストール

事前準備

gcc 互換 として使用する場合は MinGW (Windows 用 gcc) のインストールが必要です。
Clang は gcc を置き換えて使うようになっています。 Clang をインストールしてもコンパイラーと Clang 専用のヘッダー、ライブラリーがインストールされるだけで、 iostream のヘッダーすらインストールされません。 それらの基本ライブラリーは gcc のものを使うため、 MinGW のインストールが必要となります。

MinGW のインストールに関しては以前の記事を参考にして下さい。
なお、 インストール先のフォルダーはデフォルト(C:\MinGW)から変更してはダメです。 変更するとclang はヘッダー等を見つけられなくなります。 VS 互換 の場合には Visual Studio があらかじめインストールされている必要があります。

ダウンロード

LLVM のダウンロードサイトから Windows 用のバイナリーをダウンロードします。 lang_clang_dl.png

ダウンロードされるファイルは LLVM-X.X.0-win32.exe というインストーラーです。 clang ではなく LLVM という名前ですが、ちゃんと Clang がインストールされます。

インストール

インストーラーを実行するとウィザードが表示され、それに従えばインストールは完了します。

この際、実行ファイルの場所を環境変数 PATH に追加するかどうかの選択があるので、 ここは追加するようにしておきましょう。

lang_clang_inst.png

あと変えるとしたら、インストール先のパスぐらいではないでしょうか。

lang_clang_inst_path.png




なお、 VS をインストールしていないか、バージョンが古い(.NET 4.0 以上に対応していない)場合、 コンソールのエラーが出て止まります。 これは [Enter] を押せば、閉じて継続します。

lang_clang_vs.png

gcc 互換として利用する場合は関係ないので、特に気にする必要はありません。
後から VS 互換を使いたいといった場合は VS のインストール後、 (インストール先フォルダー)\tools\msbuild\instal.bat を実行して下さい。失敗したインストール処理を行います。

使い方

gcc 互換

gcc 互換の場合は、 gcc をそのまま置き換えれるようになっているので、 使い方は gcc と同じです。
各実行ファイルの対応は次の様になっています。

機能 GCC Clang
C コンパイラー gcc clang
C++ コンパイラー g++ clang++


例えば、 C++14 規格でコンパイルする場合は次のようになります。

hello.cpp :
#include <iostream>

int main()
{
    std::cout << "Hello world!" << std::endl;
    return 0;
}
~/lang/cpp $ clang++ -std=c++1y hello.cpp 
~/lang/cpp $ ./a.exe 
Hello world!
gcc の基本的な使い方についても MinGW の記事をご覧ください。 なお、 C++14 規格でコンパイルするためのオプションは正しくは -std=c++14 です。 しかし、このオプションをつけると clang++ から呼び出される g++ のエラーが発生します。
最初に GCC は C++14 に対応したと書きましたが、 MinGW の GCC のバージョンは少し遅れていて、 ちゃんと C++14 を試すためにはもう少し待つ必要があります。


ここでは基本的なコンパイルのやり方しか示しませんが、本格的なアプリを作る場合には Autogen のようなビルドツールを使うことになります。
Unix 系のビルドツールの場合は C コンパイラーは CC 、 C++ コンパイラーは CPP の変数で定義されていることが多いです。 その場合は CC=clang 、 CPP=clang++ という様に変更すれば、 Clang が使用されます。

VS 互換

VS 互換の場合は C++ のプロジェクトファイル(vcproj) のプロパティー画面を表示し、 [プラットホームツールセット] の項目で [LLVM-vs20XX] を選択します。

lang_clang_vs.png

この選択ができるようになっているのは、インストール時にツールセット用のファイルを作成したためです。 先ほど書いたコンソールのエラーは、この作成に失敗すると出ます。
ツールセットを設定し、プロジェクトをビルドすれば、コンパイルに clang-cl が使われるようになります。
ただし、 clang-cl の場合、 iostream のヘッダーをインクルードするとコンパイルエラーとなり、 Hello world すら作れません。 printf を使えば作れるのですが、 VS 互換に関してはまだまだといった感じです。


スポンサーサイト
 

C# でファイル開くなら using を使おう

C# でファイルを開くときなどに using を使っていますか?
紛らわしいのですが、 using といっても名前空間で使用するものとは別ものです。 今回は using の使い方と何故使うべきなのかについて説明したいと思います。

using を使わない場合

ファイルオープンの問題点

あるファイルに書き込みを行い、次にそれを読み取る処理を考えます。
 {
     StreamWriter sw = new StreamWriter("TestFile.txt");
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }
 // ファイルの読込
 StreamReader sr = new StreamReader("TestFile.txt");
ファイルへの書き込みを行うオブジェクト sw はブロックを抜けると、 必要がなくなり解放されます。この時ファイルのクローズが行われます。
ただし、解放の後処理をガベージコレクション(GC)任せにしていると、 ファイルが閉じられる前にアクセスして、不測の結果を招きかねません。


そこで、今度はちゃんとファイルのクローズも呼び出してみます。
C# では IO ストリーム系のクラスはファイルのクローズ Close() とリソースの解放 Dispose() が同じ処理です。 ここではクローズの処理として Dispose() を使用します。
 {
     StreamWriter sw = new StreamWriter("TestFile.txt");
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 
     sw.Dispose();               // sw.Close() と同じ
 }

例外への対応

先ほどの対応で OK としたいところですが、 書き込みの処理が複雑になってくると例外の発生を考慮する必要がでてきます。
途中の処理で例外が発生して、抜けることになっても Dispose() は呼び出さないといけません。

これを try, catch, finally で書くと次のようになります。
 StreamWriter sw = new StreamWriter("TestFile.txt");
 try
 {
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }
 catch( Exception e )
 {
     // 例外処理
 }
 finally
 {
     // 常に行う終了処理
     sw.Dispose();
 }
しかし、これでは記述が若干面倒です。 これを簡易的に記述するのが using です。

using の使用

using を使った記述

using は次のように使用します。
 using (IDisposableを継承したオブジェクト)
 {
     // 処理
 }
 // ブロックを抜けるときにオブジェクトの Dispose() メソッドを呼び出す。
先ほどの記述を using を使って書きなおしてみます。 例外で記述したのと比べると大分簡単に書けるようになります。
 using (StreamWriter sw = new StreamWriter("TestFile.txt"));
 {
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }

何故、 using を使うのか

実際には何度もアクセスするということがなければ、 ファイルのクローズも GC まかせでも問題はないかもしれません。
しかし、修正等でいざアクセスすることになったとき、 GC まかせなので、 環境によって出たり出なかったりする たちの悪いバグ になる可能性があります。

using を使うのは、 後処理のタイミングを管理し、 なおかつ例外の発生にも対処ためです。

using を使う対象

これまでファイルを開くときに using を使うと書いてきましたが、 この using は何にでも使えるわけではありません。
foreach を使えるのが IEnumerable インターフェースを継承したクラスであるように、 using を使えるのは IDisposable インターフェースを継承したクラスです。 どういったものが IDisposable を継承しているかというと ファイルや C++ 由来のものといったアンマネージリソースを扱っているクラスが多いです。

これは逆にいうと IDisposable の継承は後処理のタイミング管理が必要というサインです。 IDisposable を継承したクラスでは必ず using を使うというように心がけた方がいいでしょう。

using 使用時の注意点

using を使った方がいいと言いましたが、 無理して using を使って using のブロックが異常に長くなるのは、 コード的に良くありません。
そういった場合は using で開いた後のオブジェクト(サンプルでは sw) をメソッドの引数として渡すなどして、処理を分割していきます。

しかし、それでは上手く行かず、クラスのメンバーとして IDisposable 継承したクラスのオブジェクトを持ちたい場合もあります。 そういう時はそのクラスも IDisposable を継承し、後処理を行うようにした方がいいでしょう。 そして、そのクラスをインスタンス化する時に using を使うようにします。

IDisposable インターフェースの実装方法については以前の記事をご覧ください。 ちなみに、今回の記事は上記の記事で書いてあったものを 検索と広告対策で抜粋、加筆修正して別記事としたものです。



 

MinGW(gcc) の Windows へのインストールと使い方

Windows で C, C++ 言語のコンパイラー である gcc(g++) を使いたい場合は MinGW をインストールします。 今回はこの MinGW のインストール方法と gcc の使い方について説明します。

MinGW とは

MinGW は "Minimalist GNU for Windows" の略で、ネイティブの Windows アプリを開発するために必要な最小限の環境を提供するツールセットです。

ここでネイティブのアプリというのはコンパイルして作るマシン語の実行ファイルで、 C, C++ 言語だけではなく、 Ada, Fortran, Objective-C といった言語のコンパイラーを使うこともできます。 因みにネイティブでないものといえば、 仮想マシン(VM)やスクリプト言語のアプリですが、 違いについて詳しく知りたい方は以前の記事を見て下さい。 なお、 Windows で gcc のような GNU ツールを使いたい場合には Cygwin という手もあります。
Cygwin も GNU やオープンソースのツールを使うための環境を提供するツールセットというのは同じですが、 POSIX に準拠したライブラリーやシステム環境を作った上でアプリを動作させます。 POSIX というのは Unix 系 OS の API やアプリの動作を規定した規格です。 これはいわば、 Windows 上に Linux を乗っける感じです。

これはこれですごいものなのですが、単に Windows 上でアプリを作りたいという時には大仰です。
MinGW はアプリのビルドに最小限のツールを集めたツールセットとして Cygwin から派生しました。

また、 Cygwin で開発する場合、 Unix のシステムコールの呼び出しコードなどを変更なくそのままビルドできますが、そのかわりに作成したアプリは Cygwin のライブラリーが必須となり、 Cygwin 上で動作させなければなりません。
それに対して MinGW の場合、 デフォルトではサードパーティ製のライブラリーを何も使わず、 Windows のシステムランタイムのみ依存したアプリを作れるようになっています。

ダウンロード

インストールするためには MinGW のホームページからインストーラーをダウンロードします。 lang_mingw_dl.png


ホームページの [Download Installer] をクリックすると、 SourceFoge のページに飛び、ダウンロードが始まります。

インストール

ダウンロードロードしたファイル(mingw-get-setup.exe) は正確には mingw-get というパッケージ管理ツールのインストーラーです。 そのため、 GCC のインストールには次の手順を踏みます。
  1. パッケージ管理ツールのインストール
  2. 管理ツールで GCC のパケージを選択してインストール
  3. 環境変数 PATH の設定

パッケージ管理ツールのインストール

インストーラー(mingw-get-setup.exe)を実行するとウィザードが表示されます。

lang_mingw_inst.png

基本的にデフォルトの設定のままで問題ありません。必要があればインストール先を変更するぐらいでしょう。
ただし、 Clang を使用するためにはデフォルトのインストール先から変更してはいけません。 mingw-get 自体はコマンドラインツールですが、それを GUI で使えるフロントエンドもついてきます。 最初のチェックはそれをインストールするかどうかです。
また、作成されるショートカットはその GUI フロントエンドのショートカットで、 gcc 等のショートカットではありません。ただ、何故か私が試した場合スタートメニューの方のショートカットは作成されませんでした。

パッケージのインストール

パッケージ管理ツールのインストールが終了すると自動的にそれが起動されます。 ここで必要なパッケージを選択して、インストールします。
このパッケージ管理ツールはネットワーク対応で、 選択したパッケージをネットワークから取ってきてインストールしてくれます。

lang_mingw_inst_select.png

パッケージは次の中から選択します。
パッケージ 説明
mingw32-developer-toolkit MinGW 自体の開発者用のツール群
mingw32-base make などのビルドに必要な基本ツールセット
mingw32-gcc-ada Ada コンパイラー
mingw32-gcc-fortran Fortran コンパイラー
mingw32-gcc-g++ C++ 言語コンパイラー
mingw32-gcc-objc Objective-C コンパイラー
msys-base "Minimal SYStem" Cygwin の簡易版
bash と grep、 awk などの基本的な Unix ツール群のセット

C および C++ 言語を使うだけであれば、 migw32-base, mingw32-gcc-g++ の 2 つで十分です。
後から欲しくなった場合も、前節で作成したショートカットや以下の実行ファイルから起動できるので、選択に神経質になる必要はありません。
  • (インストール先フォルダー)\libexec\mingw-get\guimain.exe
このパッケージ管理ツールはインストールだけでなく、アップグレードの時にも使うので、 起動方法は覚えておいた方がいいでしょう。



選択後、実際にインストールする場合にはメニューの [Installation] → [Apply Changes] を実行します。

lang_mingw_inst_select2.png

ダイアログが出てくるので、 [Apply] を選択するとインストールが実行されます。

lang_mingw_inst_select3.png

環境変数 PATH の設定

インストールが完了したら、以下のフォルダーを環境変数 PATH に追加します。
  • (インストール先フォルダー)\bin
    デフォルトであれば C\MinGW\bin
MSYS のパッケージをインストールした場合は "(インストール先フォルダー)\msys\(バージョン番号)\bin" のフォルダーも追加しておきます。

gcc の使い方

gcc には数多くの機能があります。 ここでは C, C++ 言語でプログラミングをする上で、最初に覚えておくべき使い方についてのみ説明します。

なお、 C 言語の場合 gcc、 C++ 言語では g++ のコンパイラーを使いますが、 内部的には同じもので、使い方も一緒です。

コンパイル

プログラムを作成する場合、 以下の形式でコンパイルします。
g++ [オプション] ソースファイル [...]
~/lang/cpp/sample $ g++ hello.cpp 
hello.cpp :
#include <iostream>

int main()
{
    std::cout << "Hello world!" << std::endl;
    return 0;
}
実行ファイルはオプションで指定しなければ、 a.exe のファイル名となります。
~/lang/cpp/sample $ ./a.exe 
Hello world!
実行ファイル名は -o オプションで指定します。 また、 ソースファイルは複数指定することもできます。
~/lang/cpp/sample $ g++ -o hello.exe main.cpp hellofunc.cpp

オプション

基本的なオプションを以下の表に挙げておきます。
オプション 説明
--help ヘルプ(Usage)を出力
-o 出力ファイル名の指定
-D define 定義の追加
-DFOO と指定するとコード中で #define FOO と定義したのと同じになる。
-g デバッグモードでのコンパイル
デバッガー(gdb) でデバッグするのに必要な情報を付けて実行ファイルを作る。
-I インクルードファイルの検索パスの追加
-l ライブラリーの指定
-L ライブラリーの検索パスの追加
-std 規格の指定

インクルードファイル というのはヘッダーなどのファイルで、 先ほどのサンプルでは iostream がそれにあたります。 ただ、 iostream のような標準のヘッダーのパスは指定する必要はありません。
別途インストールしたヘッダーや自作ヘッダーを使いたい場合に -I オプションを使います。 例えば、カレントフォルダーのヘッダーを使いたい場合には -I. と指定します。


ライブラリー とここで言っているのは静的ライブラリーといってコンパイル時に結合するライブラリーです。 例えば libm.a という数値演算用のライブラリーを使いたければ、 lib と .a をとって -lm と指定します。
~/lang/cpp $ g++ -lm mathsamp.cpp 
こちらも標準のライブラリーはパスを特に指定する必要はありません。それ以外のところにあるライブラリーを使い時に -L オプションを使います。

因みにライブラリーとしてよく聞く dll は動的ライブラリーといって、実行時に呼び出して使うのですが、 ちょっと扱いが違うので、今回は割愛します。


規格の指定というのは C++11, C++14 といった規格です。
C++ の言語仕様は長らくあまり変わっていなかったのですが、 C++11 で大きな機能追加があり、 C++14 でその補足的な機能追加がありました。それらの新しい規格で書きたい場合には -std のオプションで指定する必要があります。

オプション 規格 備考
-std=c++11 C++11 Ver. 5.1 以降ではデフォルト
-std=c++14 C++14  
-std=c++1y 提案時代の C++14 将来は廃止予定

なお、現時点(2015-05-28)の GCC の最新版は Ver. 5.1 ですが、 MinGW の GCC は 4.8 と若干追いついておらず、 c++14 ではなく、 c++1y を使う必要があります。
Cygwin の説明で出てきた POSIX ですが、コマンドラインオプションの付け方にも規格があります。 また、 その上に GNU のスタイルガイドもあります。
-std など違反しているのも混じってますが、概ね gcc はその規格に則っています。UNIX 系のオプションの指定の仕方に慣れてない方は以前の記事が役に立つかもしれません。

環境変数

ライブラリー等をインストールした場合、毎回 -I や -L で指定するのは面倒です。 そのため、環境変数で検索用のパスを追加することができます。
指定する場合には環境変数 PATH のように ;(セミコロン) で区切って複数追加できます。

環境変数 説明
CPATH C, C++ 言語共通のインクルードファイルの検索パス
C_INCLUDE_PATH C 言語のインクルードファイルの検索パス
CPLUS_INCLUDE_PATH C++ 言語のインクルードファイルの検索パス
LIBRARY_PATH ライブラリーファイルの検索パス

オブジェクトファイルの作成

実際、アプリを作る場合にはソースファイルが大量になるのが普通です。 最後にそういう開発の さわり だけ説明しておきます。

ソースファイルを指定すると一気にやってしまうのですが、内部的には以下の手順で実行ファイルを作成します。
  1. ソースファイルからオブジェクトファイル(.o)を作成
  2. オブジェクトファイルをリンカーで結合して実行ファイルを作成
-c オプションを使うとオブジェクトファイルを作成だけになります。 また、リンカーは内部的に呼び出してくれるので、 gcc や g++ で結合できます。
~/lang/cpp/sample $ g++ -c hellofunc.cpp
~/lang/cpp/sample $ g++ -c main.cpp 
~/lang/cpp/sample $ ls
hellofunc.cpp  hellofunc.o  main.cpp  main.o
~/lang/cpp/sample $ g++ -o hello.exe hellofunc.o main.o 
何故、こういった手順で行うかというと、修正後のビルド時間を短縮するためです。 例えば、 hellofunc.cpp を修正した場合、 そのファイルのコンパイルだけをして main.cpp をコンパイルすることなく、実行ファイルが作成できます。

通常、こういったビルド作業は手間なので Makefile というファイルにビルドのルールを書いて make でビルドを行います。 ただ、この Makefile を書く作業も大変なので、最近では Autogen のように Makefile も自動生成させるようなツールを使うようなことも多くなってきています。


 
このページをシェア
アクセスカウンター
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

04月 | 2015年05月 | 06月
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。