clangのGCC Emulation Driverを使ってみる。

clangを試してみる。 - 並列メモ?に続いて、clangのGCC Emulation Driverであるcccを使ってみる。これはgccが内部でコンパイラやらリンカやらを色々使って実行ファイルまで作ってくれるのと同様に、clangやらllvm-ldやらを使って実行ファイルまで作ってくれるpythonスクリプト。そんなわけでpythonが必須。

cccはmake installではインストールされないようなので、まずは手動でコピーする。

cp tools/clang/utils/ccc ~/opt/bin/

前回同様の何もしない関数をccc_test.cに保存。

int main(void)
{
        return 0;
}

なにも考えずにcccでコンパイル

$ ccc ccc_test.c
ccc_test.c
clang -emit-llvm-bc -o ccc_test.o ccc_test.c
llvm-ld -native -disable-internalize -o a.out ccc_test.o

a.outとa.out.bcという2個のファイルが出来上がる。実行されてるコマンド見るかぎりPPUでコンパイルされているっぽいが、一応確認。

$ file a.out
a.out: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped

当然ながらPowerPC。SPUの指定はどうやるんだろ?-archに指定してもダメっぽいし…そのうち探すか。
ついでにhellow worldも書いてみる。

#include 

int main(void)
{
	printf("Hellow, world.\n");
	return 0;
}

をccc_test2.cに保存して、コンパイル

$ ccc ccc_test2.c
clang -emit-llvm-bc -o ccc_test2.o ccc_test2.c
llvm-ld -native -disable-internalize -o a.out ccc_test2.o

実行するとちゃんと動く。

$ ./a.out
Hellow, world.

特に指定はしなかったが、GLIBCのprintf()がリンクされるようだ。

$ readelf -s a.out

Symbol table '.dynsym' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     2: 100008e8     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
     3: 10000840   172 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.4 (3)
     4: 10000830   364 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)

... 略 ...