libbfdのクロスコンパイル

oprofileのクロスコンパイルでlibbfdが必要って言われて、作ろうとしたらまたはまってしまったorz


libbfd自体はbinutilsの一部っぽいんだけど、クロスコンパイラ用のlibbfdはコンパイル環境用にコンパイルされていてターゲット用としては使えないっぽい。(リンクしようとしても「incompatible」とか言われちゃう)

なので、binutilsをクロスコンパイルするしかないんだけどmakeでエラーになっちゃう。

$> ./configure --prefix=/hoge/sysroot --build=i386-pc-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
$> make

Configuring in libiberty
configure: loading cache ./config.cache
configure: error: `CC' has changed since the previous run:
configure: former value: gcc
configure: current value: x86_64-unknown-linux-gnu-gcc
configure: error: `CFLAGS' has changed since the previous run:
configure: former value: -g -O2
configure: current value: -g -O2
configure: error: `build_alias' has changed since the previous run:
configure: former value: x86_64-unknown-linux-gnu
configure: current value: i386-pc-linux-gnu
configure: error: changes in the environment can compromise the build
configure: error: run `make distclean' and/or `rm ./config.cache' and start over
make: *** [configure-libiberty] エラー 1

手強い…


いろいろやってみたけど、よくわからないのでとりあえずlibbfdのみをクロスコンパイルしてみたらコンパイルできた。

binutils-2.16.1 $> cd bfd
bfd $> ./configure --prefix=/hoge/sysroot --build=i386-pc-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
bfd $> make

ただ、これで終わりじゃなかった。
どうやらlibbfdはlibibertyに依存してるらしくて「-lbfd」だけだと大量のリンクエラーがはき出される。んで、調べてみたらlibibertyもbinutilsに含まれている。てか、クロスコンパイル環境にも入ってるので「-lbfd -liberty」とすると「unlink_if_ordinary」ってのでなぜかリンクエラー。

nm -sとかで調べてみると「/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/lib64/libiberty.a」に入っているlibibertyにはなぜか「unlink_if_ordinary」が含まれていないっぽい。仕方がないのでやっぱりlibibertyもクロスコンパイルしなおすことに。

binutils-2.16.1 $> cd libiberty
libiberty $> ./configure --prefix=/hoge/sysroot --build=i386-pc-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
libiberty $> make

やれやれ。これで終わりかと思ったらまだあった。とりあえずlibiberty.aを「/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/lib64」に上書きせずに「/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sys-root/lib64」においたらコンパイラのリンク検索順的にsys-rootじゃなくてlib64が上だったらしくて症状が変わらずに無駄に時間を浪費してしまった…orz
gccに-vをつけてコンパイルしたログから今使ってるコンパイラの検索順を調べたら

lib/gcc/x86_64-unknown-linux-gnu/4.0.2
x86_64-unknown-linux-gnu/lib64
x86_64-unknown-linux-gnu/lib
x86_64-unknown-linux-gnu/sys-root/lib64
x86_64-unknown-linux-gnu/sys-root/lib
x86_64-unknown-linux-gnu/sys-root/usr/lib64
x86_64-unknown-linux-gnu/sys-root/usr/lib

こんな感じになってた。sys-root最後ですか(´・ω・`)




[2010/01/30 11:25追記]
と思ったらまだあったー!!!
普通のコンパイルは通るんだけど、.soに今回作ったlibbfd.aとlibiberty.aを含めようとするとエラーになっちゃう!

x86_64-unknown-linux-gnu-gcc -shared .libs/libopagent_la-opagent.o -lbfd -liberty -ldl -Wl,--version-script=../libopagent/opagent_symbols.ver -Wl,-soname -Wl,libopagent.so.1 -o .libs/libopagent.so.1.0.0
/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/lib/gcc/x86_64-unknown-linux-gnu/4.0.2/../../../../x86_64-unknown-linux-gnu/bin/ld: /opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sys-root/lib/../lib64/libbfd.a(archures.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sys-root/lib/../lib64/libbfd.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

x86_64-unknown-linux-gnu-gcc -shared .libs/libopagent_la-opagent.o -lbfd -liberty -ldl -Wl,--version-script=../libopagent/opagent_symbols.ver -Wl,-soname -Wl,libopagent.so.1 -o .libs/libopagent.so.1.0.0
/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/lib/gcc/x86_64-unknown-linux-gnu/4.0.2/../../../../x86_64-unknown-linux-gnu/bin/ld: /opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sys-root/lib/../lib64/libiberty.a(xmalloc.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sys-root/lib/../lib64/libiberty.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

ちょwwww -fPICついてないですと!?
ということで、-fPIC付きでコンパイルし直し。
configureには無理矢理オプションを付与。

bfd $> ./configure --prefix=/hoge/sysroot --build=i386-pc-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu CFLAGS=-fPIC
libiberty $> ./configure --prefix=/hoge/sysroot --build=i386-pc-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu CFLAGS=-fPIC