夜行録 - 酔歩.net
LLVM + gcc frontend を x86_64 で野良 build する手順
拾いもののバイナリじゃ、なんでか他所で compile/link した LLVM バイナリが実行時にエラーとなったので、諦めて野良 build。
てゆーか、 OS 古いぞ。 gcc なんて 3.4.6 だし…。ということで、まずは GCC-4.2 の野良 build からorz
GCC-4.2 を $HOME/GCC 以下にインストールする。 enable-languages は c,c++,fortran (gfortran を使うこともいつかあるだろ)。以降、 $PATH と $LD_LIBRARY_PATH に $HOME/GCC/bin と $HOME/GCC/lib64 を追加。とくに後者は、 libstdc++ をリンクしようとして /lib/ を見に行ってコケるケースが頻出する。
LLVM の gcc frontend の build には LLVM の object ファイルが必要になるので、連続して作業する。
~/tmp/ あたりで作業するとして、 llvm-2.2, llvm-gcc4.2-2.2.source を展開する。 LLVM の流儀で(?)コンパイルはソースツリーとは別の場所で行うので、 llvmobj と llvmgccobj を作成。
cd llvmobj env LDFLAGS="-Wl,--rpath -Wl,$HOME/GCC/lib64" F77=gfortran ../llvm-2.2/configure --prefix=$HOME/LLVM --enable-optimized |& tee LOG1 make -j 3 make install cd ../llvmgccobj ../llvm-gcc4.2-2.2.source/configure --prefix=$HOME/LLVM/gcc --enable-llvm=`pwd`/../llvmobj --program-prefix=llvm- --disable-shared --disable-multilib --enable-languages=c,c++,fortran make -j 3 make install
make の並列度はプロセッサ数に合わせててきとーに指定。 LLVM の configure で F77 が指定されているのはシステムの古い g77 の方を見つけるから。キモは、 LDFLAGS を上のようにして有無を言わさず $HOME/GCC/lib64 の libstdc++ をリンクさせること。
gcc frontend の方では、 LLVM のオブジェクトコードの探索のために --enable-llvm が指定されているが、これが絶対パス指定という制約がある。 README にあるように、 --disable-shared --disable-multilib している。
--disable-multilib がない場合は
/home/yagi/tmp/llvmgccobj/./gcc/xgcc -B/home/yagi/tmp/llvmgccobj/./gcc/ -B/home/yagi/LLVM/gcc/x86_64-unknown-linux-gnu/bin/ -B/home/yagi/LLVM/gcc/x86_64-unknown-linux-gnu/lib/ -isystem /home/yagi/LLVM/gcc/x86_64-unknown-linux-gnu/include -isystem /home/yagi/LLVM/gcc/x86_64-unknown-linux-gnu/sys-include -O2 -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -I. -I32 -I../../llvm-gcc4.2-2.2.source/gcc -I../../llvm-gcc4.2-2.2.source/gcc/32 -I../../llvm-gcc4.2-2.2.source/gcc/../include -I../../llvm-gcc4.2-2.2.source/gcc/../libcpp/include -I../../llvm-gcc4.2-2.2.source/gcc/../libdecnumber -I../libdecnumber -I/home/yagi/tmp/llvm-2.2/include -I/home/yagi/tmp/llvmgccobj/../llvmobj/include -m32 -g0 -finhibit-size-directive -fno-inline-functions -fno-exceptions -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
-c ../../llvm-gcc4.2-2.2.source/gcc/crtstuff.c -DCRT_BEGIN \
-o 32/crtbegin.o
Warning: Generation of 64-bit code for a 32-bit processor requested.
Warning: 64-bit processors all have at least SSE2.
cc1: ../../llvm-gcc4.2-2.2.source/gcc/llvm-types.cpp:82: const llvm::Type* llvm_set_type(tree_node*, const llvm::Type*): Assertion `(!(__extension__ ({ const tree __t = (Tr); if (tree_code_type[(int) (((enum tree_code) (__t)->common.code))] != (tcc_type)) tree_class_check_failed (__t, (tcc_type), "../../llvm-gcc4.2-2.2.source/gcc/llvm-types.cpp", 82, __FUNCTION__); __t; })->type.size) || !Ty->isSized() || !isInt64((__extension__ ({ const tree __t = (Tr); if (tree_code_type[(int) (((enum tree_code) (__t)->common.code))] != (tcc_type)) tree_class_check_failed (__t, (tcc_type), "../../llvm-gcc4.2-2.2.source/gcc/llvm-types.cpp", 82, __FUNCTION__); __t; })->type.size), true) || getInt64((__extension__ ({ const tree __t = (Tr); if (tree_code_type[(int) (((enum tree_code) (__t)->common.code))] != (tcc_type)) tree_class_check_failed (__t, (tcc_type), "../../llvm-gcc4.2-2.2.source/gcc/llvm-types.cpp", 82, __FUNCTION__); __t; })->type.size), true) == getTargetData().getABITypeSizeInBits(Ty)) && "LLVM type size doesn't match GCC type size!"' failed.
../../llvm-gcc4.2-2.2.source/gcc/crtstuff.c:267: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See for instructions.
make[5]: *** [32/crtbegin.o] Error 1
と、よく判らないエラーになった。
--enable-bootstrap もやりたかったが、こちらも
/home/yagi/tmp/llvmgccobj/./prev-gcc/xgcc -B/home/yagi/tmp/llvmgccobj/./prev-gcc/ -B/home/yagi/LLVM/gcc/x86_64-unknown-linux-gnu/bin/ -g -O2 -o makedepend \
makedepend.o libcpp.a ../libiberty/libiberty.a \
libcpp.a(charset.o)(.text+0xf07): In function `init_iconv_desc':
: undefined reference to `alloca'
libcpp.a(charset.o)(.text+0x16fc): In function `_cpp_interpret_identifier':
: undefined reference to `alloca'
libcpp.a(directives.o)(.text+0x1158): In function `parse_assertion':
: undefined reference to `alloca'
libcpp.a(directives.o)(.text+0x271f): In function `destringize_and_run':
: undefined reference to `alloca'
libcpp.a(directives.o)(.text+0x2aca): In function `handle_assertion':
: undefined reference to `alloca'
libcpp.a(directives.o)(.text+0x2b81): more undefined references to `alloca' follow
collect2: ld returned 1 exit status
make[3]: *** [makedepend] Error 1
と、 libcpp の make で微妙なエラーで終了。 Getting Started with LLVM にも、 native コードの生成はできないとあったのであっさり諦めておく。
これでできた llvm-g++ で compile/link したバイナリは正常に動作した。
他所の LLVM で compile/link したバイトコードや、配布されているバイナリ版 gcc frontend だと、こんなエラーで止っていた……。
ERROR: Program used external function '__error' which could not be resolved! lli[0x8cbe7c] /lib64/tls/libc.so.6[0x31d662e2b0] /lib64/tls/libc.so.6(gsignal+0x3d)[0x31d662e21d] /lib64/tls/libc.so.6(abort+0xfe)[0x31d662fa1e] lli(llvm::JIT::getPointerToNamedFunction(std::basic_string<char, std::char_trait s<char>, std::allocator<char> > const&)+0xf1)[0x5dad21] lli(llvm::JIT::getPointerToFunction(llvm::Function*)+0xe1)[0x5dc021] lli[0x5dd540] lli[0x5dd7dc] lli[0x5de553] lli[0x4a6fe5] lli(llvm::MachineFunctionPass::runOnFunction(llvm::Function&)+0x2c)[0x5b2c4c] lli(llvm::FPPassManager::runOnFunction(llvm::Function&)+0x231)[0x879de1] lli(llvm::FunctionPassManagerImpl::run(llvm::Function&)+0xdc)[0x87a2dc] lli(llvm::FunctionPassManager::run(llvm::Function&)+0x30)[0x87a430] lli(llvm::JIT::runJITOnFunction(llvm::Function*)+0x38)[0x5dadd8] lli(llvm::JIT::getPointerToFunction(llvm::Function*)+0x12d)[0x5dc06d] lli(llvm::JIT::runFunction(llvm::Function*, std::vector<llvm::GenericValue, std: :allocator<llvm::GenericValue> > const&)+0x4c)[0x5db0bc] lli(llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::b asic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator <std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > cons t&, char const* const*)+0x382)[0x5d41b2] lli(main+0x233)[0x49c763] /lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x31d661c3fb] lli(fmod+0x82)[0x49bc3a]
なんぞね? Program used external function '__error' which could not be resolved! とは?!
追加:
compile したノード上にだけ libltdl.so があって、実行ノードにはなくって実行時エラーになる罠。…うんこ管理人メ、何か頼むと屁理屈こねて「動かなくなる可能性が0ではないのですよ」とかって意地でもなにもしないくせに、何もしてない状況で既に動かないじゃねーか…。
$HOME/NODE01LIB/とか怪しいディレクトリ作って .so をコピっとく。ジョブのスクリプトで、ここを LD_LIBRARY_PATH に追加すればよかべぇ。 $HOME は全ノードで共有されてるので…。
Karma points: 5. Do you like this article? [yes/no]
- Use this Trackback URL for ping (right mouse click and copy URL).
- You can [print] this article, DISALLOWED (MailToAFriend) it, or export a [PDF].