2010年03月09日

Clang を VisualStudio 2008 でビルドしてみる

Clang (クラン(グ)) は、C/C++/Objective-C のコンパイラフロントエンドです。バックエンドに LLVM (Low-Level Virtual machine) を使います。(GCC をバックエンド(アセンブラ & リンカ代わり) として使い、通常の実行形式を生成することもできます。逆に、GCC のミドルエンド以降を LLVM 向けに改造した llvm-gcc というフロントエンドも存在します。)

ライセンスが BSD ライク なので、FreeBSD が Clgan で GCC を置き換えようとする動きがあったりと、徐々に注目を集めています。

Getting Started: Building and Running Clang を見る限り、Windows 上では VisualStudio 2005/2008 でビルドできるそうなので、さっそく試してみました。



ソース取得のために Subversion、VS solution/project ファイルの生成のために cmake が必要です。

(テストを走らせるためには、Python と GnuWin32 tools も必要です。MinGW や cygwin の grep では上手く動かないそうです。)

LLVM と Clang をチェックアウトします。レポジトリが 2 つに分かれています。svn update などの際も両方で update する必要があります。
C:\>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
C:\>cd llvm\tools
C:\llvm\tools>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
LLVM リビジョン 97702、Clang リビジョン 97700 でチャレンジ。

LLVM のディレクトリトップで LLVM.sln を作ります。
C:\llvm\tools>cd ..
C:\llvm>cmake -G "Visual Studio 9 2008"
LLVM.sln を普通に VS 2008 で開いてビルドします。
今回は clang プロジェクト(フロントエンドとコンパイラドライバ)のみを右クリックでビルドしました。
特に問題なくビルドできました。(MinGW や cygwin でビルドする際には、注意深く関連するパッケージ群のバージョンを揃える必要があるようで、なかなか大変そうです。)

今回はバックエンドの LLVM をビルドしていないので、アセンブリプログラムの生成までですが、ちゃんと LLVM のアセンブリプログラムが生成されていることが確認できます。
C:\llvm>cd bin\Debug\
C:\llvm\bin\Debug>cat t.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("hello, world\n");
    return 0;
}

C:\llvm\bin\Debug>clang -S -emit-llvm -o - t.c
; ModuleID = 't.c'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
2:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"

target triple = "i686-pc-win32"

@.str = private constant [14 x i8] c"hello, world\0A\00" ; <[14 x i8]*> [#uses=1
]

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
  %retval = alloca i32, align 4                   ; <i32*> [#uses=3]
  %argc.addr = alloca i32, align 4                ; <i32*> [#uses=1]
  %argv.addr = alloca i8**, align 4               ; <i8***> [#uses=1]
  store i32 0, i32* %retval
  store i32 %argc, i32* %argc.addr
  store i8** %argv, i8*** %argv.addr
  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.
str, i32 0, i32 0)) ; <i32> [#uses=0]
  store i32 0, i32* %retval
  %0 = load i32* %retval                          ; <i32> [#uses=1]
  ret i32 %0
}

declare i32 @printf(i8*, ...)


トラックバックURL

コメントする

名前
URL
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード