Problem summary
ports/lang/gcc42 cannot build with following error messages.
/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/gcj -B/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava/ -B/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/ -ffloat-store -fomit-frame-pointer -g -O2 -o .libs/jv-convert --main=gnu.gcj.convert.Convert -shared-libgcc -pthread -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava/.libs ./.libs/libgcj.so -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libstdc++-v3/src -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libstdc++-v3/src/.libs -lz -L/home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc -lgcc_s -lgcc_s -Wl,--rpath -Wl,/usr/local/lib/gcc-4.2.0
/usr/bin/ld: .libs/jv-convert: hidden symbol `__eprintf' in /home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc/libgcc.a(_eprintf.o) is referenced by DSO
collect2: ld returned 1 exit status
gmake[3]: *** [jv-convert] 1
gmake[3]: `/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava'
gmake[2]: *** [all-recursive] 1
gmake[2]: `/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava'
gmake[1]: *** [all-target-libjava] 2
gmake[1]: `/home2/ports.work/usr/ports/lang/gcc42/work/build'
OS version
FreeBSD 5.5-STABLE.
Some FreeBSD 6.2-PRERELEASE could build ports/lang/gcc42 and others did not.
How to fix
# pkg_delete gcc-2.95.3_2
Problem details
unresolved __eprintf symbol was included in libgcj.a
# nm .libs/libgcj.a | grep eprintf
U __eprintf
U __eprintf
this came from ltdl.o and mprec.o
ltdl.o:
000000a3 r .LC9
U _CurrentRuneLocale
U _GLOBAL_OFFSET_TABLE_
U ___runetype
U __eprintf
mprec.o:
00000157 T _Jv_ulp
U __eprintf
# find . -name ltdl.o -print
./libltdl/.libs/ltdl.o
./libltdl/ltdl.o
libltdl/ltdl.o:
U _CurrentRuneLocale
U ___runetype
U __eprintf
U __isthreaded
U access
ltdl.o was build like this
# /bin/sh ./libtool --debug --tag=CC --mode=compile /home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc/xgcc -B/home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc/ -B/usr/local/i386-portbld-freebsd5.5/bin/ -B/usr/local/i386-portbld-freebsd5.5/lib/ -isystem /usr/local/i386-portbld-freebsd5.5/include -isystem /usr/local/i386-portbld-freebsd5.5/sys-include -DHAVE_CONFIG_H -I. -I../../.././..//gcc-4.2-20070102/libjava/libltdl -I. -O2 -O -pipe -march=pentiumpro -c -o ltdl.lo ../../.././..//gcc-4.2-20070102/libjava/libltdl/ltdl.c
Looking into /usr/local/i386-portbld-freebsd5.5/include, __eprintf symbol can be found.
# grep -R eprintf /usr/local/i386-portbld-freebsd5.5/include
/usr/local/i386-portbld-freebsd5.5/include/assert.h:extern void __eprintf (const char *, const char *, unsigned, const char *)
/usr/local/i386-portbld-freebsd5.5/include/assert.h:extern void __eprintf (const char *, const char *, unsigned, const char *)
/usr/local/i386-portbld-freebsd5.5/include/assert.h: (__eprintf ("%s:%u: failed assertion `%s'\n", \
/usr/local/i386-portbld-freebsd5.5/include/assert.h:extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
/usr/local/i386-portbld-freebsd5.5/include/assert.h: (__eprintf ("%s:%u: failed assertion `%s'\n", \
Hummmm...
# ls -l /usr/local/i386-portbld-freebsd5.5/include/assert.h
-rw-r--r-- 1 root wheel 1486 11 9 14:41 /usr/local/i386-portbld-freebsd5.5/include/assert.h
# pkg_which /usr/local/i386-portbld-freebsd5.5/include/assert.h
gcc-2.95.3_2
There is one more problem about ports/lang/gcc42
Problem summary
ports/lang/gcc42 cannot build binary package.
===> Building package for gcc-4.2.0_20070102
Creating package /usr/ports/packages-5-stable/All/gcc-4.2.0_20070102.tbz
Registering depends: mpfr-2.2.1 libiconv-1.9.2_2 libgmp-4.2.1_1.
Creating bzip'd tar ball in '/usr/ports/packages-5-stable/All/gcc-4.2.0_20070102.tbz'
tar: bin/jar42: Could not stat: No such file or directory
pkg_create: make_dist: tar command failed with code 256
*** Error code 1
Stop in /usr/ports/lang/gcc42.
How to fix
a very simple workaround is ...
# touch /usr/local/bin/jar42
# make package
===> Building package for gcc-4.2.0_20070102
Creating package /usr/ports/packages-5-stable/All/gcc-4.2.0_20070102.tbz
Registering depends: mpfr-2.2.1 libiconv-1.9.2_2 libgmp-4.2.1_1.
Creating bzip'd tar ball in '/usr/ports/packages-5-stable/All/gcc-4.2.0_20070102.tbz'
---------------------------------------------------
というわけで、FreeBSDのportsで、lang/gcc42をビルドしようとしたら(別にgcc-4.2が使いたいわけじゃなくて、portupgradeしたときに、依存関係によって、gcc42がビルドされただけなんですが)、エラーがでて失敗しました。
/usr/bin/ld: .libs/jv-convert: hidden symbol `__eprintf' で検索すると
http://lists.freebsd.org/pipermail/freebsd-questions/2007-January/138706.html
lang/gcc41 woes
というのが見つかりますが
hidden symbol `__eprintf' で検索すると、もっとたくさんでてくるようです。
で、いろいろ見てみましたが、解決方法は見つかりませんでした。
仕方ないので、自分で調べてみたよ、ってかんじ。
調べてみた結果、ports/lang/gcc295でインストールされるassert.hに含まれるシンボル__eprintfが悪さをしているのが原因でした。gcc42とgcc295がconflictしてる、っていってもいいかもしれませんが、gcc295のassert.hのインストール先がおかしいんじゃない?っていう気もします。
問題の解決方法をどうやって見つけたか?
かなり泥臭い方法ですが・・・
エラーを出したコマンドが
/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/gcj -B/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava/ -B/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/ -ffloat-store -fomit-frame-pointer -g -O2 -o .libs/jv-convert --main=gnu.gcj.convert.Convert -shared-libgcc -pthread -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libjava/.libs ./.libs/libgcj.so -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libstdc++-v3/src -L/home2/ports.work/usr/ports/lang/gcc42/work/build/i386-portbld-freebsd5.5/libstdc++-v3/src/.libs -lz -L/home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc -lgcc_s -lgcc_s -Wl,--rpath -Wl,/usr/local/lib/gcc-4.2.0
だったので、これの頭に、「ktrace」をつけて実行しました。ようするに、どのファイルを参照しているのか、を知りたかったのです。しかし、残念ながら、途中でexecしてしまうようで、ktraceで追いかけられません(私が子プロセスのトレース方法を知らないだけ?)。
ただ、何をexecしたかはktraceでわかるので、execしているプログラムを、ktraceで実行するようにwrapper scriptを作成します。さらにexecしてれば、同じことの繰り返し。
そうやってわかったのですが
/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/collect2 が呼ばれていて、
さらに
/home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/collect-ld
が呼ばれてました。で、collect-ldの中身はというと
# cat /home2/ports.work/usr/ports/lang/gcc42/work/build/gcc/collect-ld
#!/bin/sh
exec /usr/bin/ld "$@"
なんてものだったので、ここ「ld --verbose」と書き換えてしまいます。
exec /usr/bin/ld --verbose "$@"
さらにexecの行の前に、
echo /usr/bin/ld "$@"
とか付けたすのもいいかもしれません。
これで、実際にどのファイル(ライブラリ)をリンクするかが表示されるようになるので、あとは、アクセスしたファイルすべてについて、「grep __eprintf」をしまくります。
そうやってみつけたのが、libgcj.aでした。
ktraceしたのは、grepでの探索範囲を狭めるという目的があったからでして、grep -Rで手当たりしだいに探すのでも、いいかもしれません(時間がかかるかもしれませんが)。
libgcj.aに取り込まれたltdl.oに、__eprintfというunresolved symbolがあることが、nmコマンドですぐにわかりますから、あとは、ltdl.oがどうやってコンパイルされたかを、調べればいいってこと。コンパイル中のログをみてもいいし、ログを残していなければ、ファイルを削除してから、gmakeコマンドを実行しちゃえばいいです。
/home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc/xgcc -B/home2/ports.work/usr/ports/lang/gcc42/work/build/./gcc/ -B/usr/local/i386-portbld-freebsd5.5/bin/ -B/usr/local/i386-portbld-freebsd5.5/lib/ -isystem /usr/local/i386-portbld-freebsd5.5/include -isystem /usr/local/i386-portbld-freebsd5.5/sys-include -DHAVE_CONFIG_H -I. -I../../.././..//gcc-4.2-20070102/libjava/libltdl -I. -O2 -O -pipe -march=pentiumpro -c ../../.././..//gcc-4.2-20070102/libjava/libltdl/ltdl.c -o ltdl.o
というコマンドでコンパイルされているので、じゃあ、includeファイルのどこかに__eprintfがあるに違いない、となるので、include pathにあるディレクトリについて、grep -Rしまくったところ
% grep -R eprintf /usr/local/i386-portbld-freebsd5.5/include
/usr/local/i386-portbld-freebsd5.5/include/assert.h:extern void __eprintf (const char *, const char *, unsigned, const char *)
というかんじで見つかりました。
このヘッダファイルはどこからやってきたのか、どのパッケージでインストールされたのかは、pkg_whichでわかります。
# pkg_which /usr/local/i386-portbld-freebsd5.5/include/assert.h
gcc-2.95.3_2
なーんだ、じゃあ、gcc-2.95.3_2をpkg_deleteしちゃえばいいんじゃない?
というかんじです。
0 件のコメント:
コメントを投稿