2014年は何の年〜?

ワールドカップやで!
というわけで明けましておめでたまきん。
ぽっくん日記書くの久しぶりう゛ぁい!
ちゃまちゃまむこう行っとけや!

clangをビルドしてみる

2014年一発目の驚きは,clangの読み方。人と話すことが極端に少ないワタシ。
clangを見たとき,「シーラング」と読んでいました。
んで,昨日youtubeでclangのast紹介かなんかの動画を見ていたら,
講釈垂れているおっさんが「クラング」と発音していた!!
最初clangを使った発表なのに,全然clang出てこないやん。
てかクラングってなんやねん,とか思っていたが,はっと気づいた。


と余計な話しはその辺においといて,llvm3.4のビルド。
環境は,windows xp, cygwin
昔2.xくらいのときにどうやったか覚えてない。
覚えてないので,clangのサイト見ながら,
svnで3.4のfinalをチェックアウトしてconfigureしてmake。


以前ビルドしたときもっそい時間かかったの覚えているからビルドしつつ
英単語の復習などしたり,ニコ生見たり。
途中なんかでエラーがでたけどもっかいmakeしたら動いていたので放置。
そして,リンキングターイム。
リンクにすごい時間がかかるんだねー。へー。
おや? メモリの使用量が半端ないぞ。というか枯渇するぞこれ。
なのでfirefoxを落す。少し復活した。
放置。
ん? エラー発生して終了しとるね。何々? ディスクに空き容量がないだと?
んなあほな。cygwinとか諸々入っているパーティションはたしか10Gくらいは空きあったはず。
見てみると残り300MBくらいになっている。
ほう・・・。
ビルドディレクトリを覗いて見る。
はぁああぁ? clang.exe が1.7GB? えらいこっちゃー。
えーらいこっちゃ えーらいこっちゃ そいそいそいそーい。

ビルドディレクトリはDebug+Assertsになっている。あやしい。
ググってみる。なるほど。デバッグ情報がついているからクソでかくなったのね。
configureからやり直す。あと,ビルドしているときに見ていたけど,powerpcとかなんやら
関係なさそうな文字列が見えていたので,そのへんも気になる。
なので,targetをx86だけにしてみる。これってたぶんllvmのtargetと予想。
んでええ時間だったので寝る準備して,makeして寝る。
おやすみー。


おはよー。
起きたので,どうなったか見てみる。
お!? 無事終わってるやんけ。ないすー。ほいで,clang.exeのサイズはなんぼや?
約51MB。うーんなんかでかい気もするけどまあいいや。
うーん歌舞伎揚げは相変わらずのおいしさだね。バリバリ。
はいmake installどん!

% which clang
/usr/local/bin/clang

% clang --version # ...? 全然帰ってこないお・・・
clang version 3.4 (tags/RELEASE_34/final 198696) (llvm/tags/RELEASE_34/final 198695)
Target: i386-pc-cygwin
Thread model: posix

おせえぇぇぇぇ! すげぇおせえぇ。なんで?
時間計ってみる。

% time clang --version
clang version 3.4 (tags/RELEASE_34/final 198696) (llvm/tags/RELEASE_34/final 198695)
Target: i386-pc-cygwin
Thread model: posix
clang --version  0.06s user 5.20s system 82% cpu 6.359 total

6秒とかすげーなおい。


怖い物見たさでtutorialにあったtest.ccをコンパイルしてみる。
あ,mainはありませんのでコンパイルエラーは気になさらずに。

% cat test.cc
#include <iostream>

int f(int x) {
  int result = (x / 42);
  return result;
}

% time clang++ test.cc
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.16-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
clang++ test.cc  0.65s user 25.85s system 92% cpu 28.734 total

29秒wwww
そら草も生えてまいますわ。


うーん補完関係でちょっとclangを試して見たいなーと思ったんですが,
この29秒がまともな理由での29秒なら使い物にならんど。
で,もちのろんでそんなこたーない。
userではなくてsystemが圧倒的に時間を何かに費やしている。
なんだろう・・・。皆目見当がつかん。

最初,ディスクの断片化で遅くなってるとか思ったけど,
timeで計測してみておそらくそうではないだろうと。
断片化が原因なら実行準備でもっそい時間がかかっているだろうから。


ちなみにg++。

% time g++ test.cc
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.16-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status
g++ test.cc  0.41s user 0.32s system 117% cpu 0.625 total
 

ですよねー。1秒かからないですよね−。


わからん。原因がわからん。見当もつかん。3.3をビルドして試してみる?
いやちょっと待てとclangでコンパイルするときに-vを渡してみた。

% time clang++ -O2 test.cc -v -c
## ここで5秒くらい喰う
clang version 3.4 (tags/RELEASE_34/final 198696) (llvm/tags/RELEASE_34/final 198695)
Target: i386-pc-cygwin
Thread model: posix
Selected GCC installation: 
 "/usr/local/bin/clang" -cc1 -triple i386-pc-cygwin -S -disable-free -main-file-name test.cc -mrelocation-model static -mdisable-fp-elim -fmath-errno -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.22.52.20120326 -v -coverage-file /cygdrive/c/DOCUME~1/whitypig/LOCALS~1/Temp/test-13c83c.s -resource-dir /usr/local/bin/../lib/clang/3.4 -O2 -fdeprecated-macro -fno-dwarf-directory-asm -fdebug-compilation-dir /home/whitypig/prog/tmp/tryclang -ferror-limit 19 -fmessage-length 80 -mstackrealign -fno-use-cxa-atexit -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o /cygdrive/c/DOCUME~1/whitypig/LOCALS~1/Temp/test-13c83c.s -x c++ test.cc
## ここで8秒くらい喰う
clang -cc1 version 3.4 based upon LLVM 3.4 default target i386-pc-cygwin
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.7.3/include/c++"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.7.3/include/c++/i686-pc-cygwin"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.7.3/include/c++/backward"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/i686-pc-cygwin"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/backward"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/c++"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/c++/i686-pc-cygwin"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/c++/backward"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++
 /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/i686-pc-cygwin
 /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/backward
 /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++
 /usr/local/include
 /usr/local/bin/../lib/clang/3.4/include
 /usr/include/w32api
 /usr/include
End of search list.
 "/usr/bin/g++" -O2 -v -c -m32 -o test.o -x assembler /cygdrive/c/DOCUME~1/whitypig/LOCALS~1/Temp/test-13c83c.s
## ここで5秒くらい喰う
Using built-in specs.
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.5.3/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with: /gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3/configure --srcdir=/gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --datarootdir=/usr/share --docdir=/usr/share/doc/gcc4 -C --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --libexecdir=/usr/lib --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,objc,obj-c++ --enable-graphite --enable-lto --enable-java-awt=gtk --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind --with-ecj-jar=/usr/share/java/ecj.jar
Thread model: posix
gcc version 4.5.3 (GCC) 
COLLECT_GCC_OPTIONS='-O2' '-v' '-c' '-m32' '-o' 'test.o' '-shared-libgcc' '-mtune=generic' '-march=i686'
 /usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../i686-pc-cygwin/bin/as.exe -v -o test.o /cygdrive/c/DOCUME~1/whitypig/LOCALS~1/Temp/test-13c83c.s
GNU assembler version 2.22.52 (i686-cygwin) using BFD version (GNU Binutils) 2.22.52.20120326
COMPILER_PATH=/usr/lib/gcc/i686-pc-cygwin/4.5.3/:/usr/lib/gcc/i686-pc-cygwin/4.5.3/:/usr/lib/gcc/i686-pc-cygwin/:/usr/lib/gcc/i686-pc-cygwin/4.5.3/:/usr/lib/gcc/i686-pc-cygwin/:/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../i686-pc-cygwin/bin/
LIBRARY_PATH=/usr/lib/gcc/i686-pc-cygwin/4.5.3/:/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-O2' '-v' '-c' '-m32' '-o' 'test.o' '-shared-libgcc' '-mtune=generic' '-march=i686'
clang++ -O2 test.cc -v -c  0.23s user 20.50s system 89% cpu 23.250 total

gccとの連携で時間喰ってるのかな?
そもそも何故にgccと連携する必要があるのか?
clangだけではネイティブのバイナリを作れないの?
ほしたら,-emit-llvmオプションは何のためにあるんや?
うーんわけわかめ
clangとかllvmのことはほとんど何もわかっちゃいないので,ドキュメントをそのうち読みます。


なーんか設定を忘れている香りがするんだよねー。
でも2.xをビルドして使ったときなんか設定したっけなー?
覚えてねー。んで,そんときは遅くなかった気がするんだよね。
straceでもしたら何かわかるかな?


※師匠へ
年賀状出すの遅くてごめんちゃい。
年賀状自体は手に入れたので,今日書く! はず!

治った!!
% time clang --version
clang version 3.4 (tags/RELEASE_34/final 198696) (llvm/tags/RELEASE_34/final 198695)
Target: i386-pc-cygwin
Thread model: posix
clang --version  0.03s user 0.06s system 14% cpu 0.641 total

http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-April/020646.html
に同じような問題に悩んでいる人がいた。
pseudo-relocが何なのか解りませんが,static linkすればいいみたい。
clangだけをstatic linkにする方法がわからないし,わかったとしてもそれでいいのかどうか
わからなかったので,ええいと,

% LDFLAGS=-static ../llvm/configure --enable-optimized --enable-targets=host

して再ビルド。
一応解決。


解決策見つける前に,straceして眺めてみたけど,環境変数を全部見たり,
Windows特有のパスを修正したり色々していたので,
その辺に原因があるのかなーなんて疑っていました。
よっしゃよっしゃ。
メーリングリストに解決策を投稿してくれた人ありがとう!