自由なUNIXに似たシステムのパッケージシステムは、Autotoolsの分厚い皮がすこし日焼けしたようなものだ。魔法の四行詩(たいていの場合、make checkは抜かすだろうけれど)を諳んじるのだ。
./configure make make check make install
この四行はUNIXの範疇にある。shが実行され、makeが実行される。それらが呼び出すコマンドがUNIXの範疇にあるかどうかは保証されない。SUSv3が定義するCコンパイラはc99だけど、それが存在するかどうかは判らない(自由なUNIXに似たシステムはUNIXじゃないからね)。
目標は、畢竟、ぼくたちのC++のコードがリンクする全ての静的ライブラリをbitcodeで表現すること、最後の最後に最適化をかけることだ。実際問題、ユーザランドで動作する使い勝手の良いライブラリ、特に様々なメディアを扱うライブラリはLLVMの恩恵を受けやすい。C++のライブラリがヘッダー主体になって久しいが、それだって内部では昔ながらのCのライブラリを呼び出している。
makeと呪いを唱える。現実に即し、乱暴に述べるなら、ほとんどの場合、GNU Compiler Collectionが呼び出される。GNU Compiler Collectionは魔術的にリンカを呼び出す。
gcc -Wall -O2 -g -c foo.c gcc -Wall -O2 -g -c bar.c ar rc libfoobar.a foo.o bar.o ranlib libfoobar.a gcc -Wall -O2 -g baz.c -L. -lfoobar -lm -o baz
人工的だけど典型的で例だ(実際、bzip2のMakefileはこんな感じだ)。-vオプションを与えると、gccは内部で呼び出すコマンドを表示する。本当に呼び出しているコマンドを知るためにはdtrace(あるいは他のなにか)を使用する。Mac OS X 10.5では/usr/bin/gccは/usr/bin/gcc-4.0のシンボリックリンクだ。最後の一行を実行すると、コンパイルのためにcc1とasが、リンクのためにcollect2そしてldが呼び出される。
- /usr/bin/gcc-4.0
- /usr/bin/i686-apple-darwin9-gcc-4.0.1
- /usr/libexec/gcc/i686-apple-darwin9/4.0.1/cc1
- /usr/libexec/gcc/i686-apple-darwin9/4.0.1/as
- /usr/libexec/gcc/i686-apple-darwin9/4.0.1/collect2
- /usr/libexec/gcc/i686-apple-darwin9/4.0.1/ld
- /usr/bin/i686-apple-darwin9-gcc-4.0.1
LLVMが透過的だとしたら、接頭辞を加えてコマンドを実行すれば全てがうまくいくだろう(もちろん、そう、-emit-llvmを忘れなければ)。そしてbitcodeが生成されるだろう。
llvm-gcc -emit-llvm -Wall -O2 -g -c foo.c llvm-gcc -emit-llvm -Wall -O2 -g -c bar.c llvm-ar rc libfoobar.a foo.o bar.o llvm-ranlib libfoobar.a llvm-gcc -emit-llvm -Wall baz.c -L. -lfoobar -lm -o baz
はかない望みである。はかなさの理由は、コンパイルとリンクを合わせて行うことがllvmの流儀に反しているからだと説明できるかもしれない。llvm-gccとllvm-ld(またはllvm-link)を別々に実行すれば問題は解決する。bitcodeとそれを実行するためのシェルスクリプトが生成される。
llvm-gcc -Wall -emit-llvm -c baz.c llvm-ld baz.o -L. -lfoobar -lm -o baz
流儀云々は窓から投げ捨てよう。collect2は$PATH
からldを決定する(実際には、もっと面倒な決定方法を経る)。特に設定していなければシステムのldを見つける。システムのldが望みを叶えてくれるわけはない。
- $LLVM_GCC_PREFIX/bin/llvm-gcc
- $LLVM_GCC_PREFIX/libexec/gcc/i686-apple-darwin9/4.2.1/cc1
- $LLVM_GCC_PREFIX/libexec/gcc/i686-apple-darwin9/4.2.1/collect2
- /usr/bin/ld
ldをllvm-ldへのシンボリックリンクに設定すれば、llvm-ldが呼び出されるようになる。しかし、collect2がldに渡す引数のなかにはllvm-ldが解釈できないものがある。典型的には-emit-llvmを扱えないし、Mac OS Xの拡張オプションや癖のあるlibc周りはうまく扱えない(なんだか間尺に合わない話だ)。厳密さを追い求めなければ、対処は難しくない。扱えない引数を削除した後、llvm-ldを呼び出せばいい。
0 件のコメント:
コメントを投稿