The libgcj testsuite is failing substantially all tests that require linking libgcj.a on arm-elf because of missing symbols. This failure started to occur sometime between 2005/02/13 and 2005/02/16. There are about 5000 lines of error messages for each link command: the total testrun log is about 1.5GBytes in size! /work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(jni.o): In function `_Jv_JNI_GetAnyMethodID<0u>': /home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:730: undefined reference to `java::lang::StringBuffer::StringBuffer(java::lang::String*)' /home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:736: undefined reference to `java::lang::StringBuffer::class$' /work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(jni.o): In function `_Jv_JNI_GetAnyMethodID<1u>': /home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:730: undefined reference to `java::lang::StringBuffer::StringBuffer(java::lang::String*)' /home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:736: undefined reference to `java::lang::StringBuffer::class$' /work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o): In function `_Jv_Linker::find_field(java::lang::Class*, java::lang::Class*, _Jv_Utf8Const*, _Jv_Utf8Const*)': /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:178: undefined reference to `java::lang::StringBuffer::StringBuffer()' /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:202: undefined reference to `java::lang::StringBuffer::StringBuffer()' /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:197: undefined reference to `java::lang::StringBuffer::class$' /work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o): In function `_Jv_Linker::search_method_in_class(java::lang::Class*, java::lang::Class*, _Jv_Utf8Const*, _Jv_Utf8Const*)': /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:471: undefined reference to `java::lang::StringBuffer::StringBuffer()' /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:478: undefined reference to `java::lang::StringBuffer::class$' /work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o): In function `_Jv_GetMethodString(java::lang::Class*, _Jv_Method*, java::lang::Class*)': /home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:684: undefined reference to `java::lang::StringBuffer::StringBuffer(java::lang::String*)' etc.
Does backing out this patch help? http://gcc.gnu.org/ml/java-patches/2005-q1/msg00402.html (See also: PR 20155)
Yes, that's the patch that introduces the problem.
*** Bug 20190 has been marked as a duplicate of this bug. ***
Verified on i686-linux with --disable-shared.
Yet another libtool bug. It has clobbered ./java/lang/StringBuffer.o with ./gnu/gcj/runtime/StringBuffer.o when moving data from the convenience library to the main library. I fear we may be screwed, with no resolution that satisfies everyone. Alex? Is there any way out?
Technically, it's not a libtool bug. When you create an archive out of object files that have overlapping basenames, ar will generally only retain the last one. Dropping the dirname portion is mandated by POSIX. The right solution would be to avoid duplicate basenames entirely. This is probably tricky and painful to do in libjava. Libtool has some trickery to at least force object files with the same basename into an archive, passing special options to ar. I suppose the best course of action would be to rename the input files internally, transparently to the caller, such that, when they're extracted, you don't one to overwrite the other. Either way, this is probably not trivial to implement in libtool. Reverting to piecewise linking and modifying the grouping strategy might be easier. I'll think a bit about it.
A short-term, simpler solution that might be more suitable for the GCC 4 time-frame is to create one convenience archives per subdir, so as to make sure we don't have any overlapping basenames within a single archive.
Created attachment 8282 [details] Patch that may fix the problem, at the expense of even slower library creation This patch makes sure no duplicate object names are added to static archives created by libtool, thereby avoiding the problem if we have to extract the contents of the archive. Unfortunately, this will slow down even more the creation of archives :-( Richard (Earnshaw), would you please give it a try and let me know whether the patch indeed fixes the problem for you. Make sure you don't have any left-over convenience libraries from a previous build; they may already contain overlapping names.
The build fails: rm -fr .libs/libgcj.lax/libgcjgc_convenience.a mkdir .libs/libgcj.lax/libgcjgc_convenience.a (cd .libs/libgcj.lax/libgcjgc_convenience.a && /work/rearnsha/gnu/egcs/binutils/ar x /work/rearnsha/gnu/egcs/arm-elf/thumb/libjava/../boehm-gc/.libs/libgcjgc_convenience.a) copying selected object files to avoid basename conflicts... rm -fr .libs/libgcj.lax mkdir .libs/libgcj.lax cp org/ietf/jgss/MessagesBundle.properties.o .libs/libgcj.lax/lt1-MessagesBundle.properties.o cp .libs/libgcj.lax/libgcj0_convenience.a/EventListener.o .libs/libgcj.lax/lt2-EventListener.o cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/EventListener.o': No such file or directory cp .libs/libgcj.lax/libgcj0_convenience.a/ContentHandler.o .libs/libgcj.lax/lt3-ContentHandler.o cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/ContentHandler.o': No such file or directory cp .libs/libgcj.lax/libgcj0_convenience.a/Attributes.o .libs/libgcj.lax/lt4-Attributes.o cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/Attributes.o': No such file or directory etc. Incidentally, wouldn't it be more efficient to use links (either hard or soft) rather than doing a copy?
Hard-linking is an option, although we can't rely on hard-links being available. Soft-linking would require even more pathname tweaking, it's just not worth it. Anyhow, thanks for testing, I see what the problem is, and I'll have a new patch for you soon.
Created attachment 8284 [details] Don't wipe out the dir onto which we've extracted convenience archives This should fix the problem you ran into, avoid another potential (although very unlikely) error condition and try ln before cp to speed things up a tiny little bit. Please let me know how it goes.
That patch seems to work, thanks.
Subject: [PR libgcj/20160] rename archive members with duplicate basenames The archives created for libjava are broken, in that some of the object files that should go into it are missing. That's because AR is supposed to drop dirname components of pathnames in archive members. Libtool was already careful enough to ensure the all archive members made to the convenience library, by using ar cq if creating archives piecewise, but it isn't as careful when extracting the archive members to create other archives with them, so we end up dropping all but the last-added overlapping-basename object from the second-generation archive. This problem is already fixed in libtool mainline and 1.5 branches, using some clever tricks at extract time, that I'm not entirely comfortable with, and not quite willing to back-port. Until we actually upgrade to a newer libtool, I'd rather go with this change that is IMHO safer, but unfortunately introduces some additional overhead in archive creation time. Oh well... I'm checking this in mainline and 4.0 branch. Tested on arm-elf (thanks Richard!) and x86_64-linux-gnu. Index: ChangeLog from Alexandre Oliva <aoliva@redhat.com> PR libgcj/20160 * ltmain.sh: Avoid creating archives with components that have duplicate basenames. * libjava/configure: Rebuilt. Index: ltmain.sh =================================================================== RCS file: /cvs/gcc/gcc/ltmain.sh,v retrieving revision 1.24 diff -u -p -r1.24 ltmain.sh --- ltmain.sh 8 Sep 2004 15:43:46 -0000 1.24 +++ ltmain.sh 1 Mar 2005 22:16:48 -0000 @@ -4307,6 +4307,63 @@ fi\ # fi # done + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" if len=`expr "X$cmds" : ".*"` && @@ -4320,20 +4377,7 @@ fi\ objlist= concat_cmds= save_oldobjs=$oldobjs - # GNU ar 2.10+ was changed to match POSIX; thus no paths are - # encoded into archives. This makes 'ar r' malfunction in - # this piecewise linking case whenever conflicting object - # names appear in distinct ar calls; check, warn and compensate. - if (for obj in $save_oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 - $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 - AR_FLAGS=cq - fi + for obj in $save_oldobjs do oldobjs="$objlist $obj" -- Alexandre Oliva http://www.ic.unicamp.br/~oliva/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}
Subject: Bug 20160 CVSROOT: /cvs/gcc Module name: gcc Changes by: aoliva@gcc.gnu.org 2005-03-01 22:27:44 Modified files: . : ChangeLog ltmain.sh Log message: PR libgcj/20160 * ltmain.sh: Avoid creating archives with components that have duplicate basenames. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.1061&r2=1.1062 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ltmain.sh.diff?cvsroot=gcc&r1=1.24&r2=1.25
Subject: Bug 20160 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: aoliva@gcc.gnu.org 2005-03-01 22:29:34 Modified files: . : ChangeLog ltmain.sh Log message: PR libgcj/20160 * ltmain.sh: Avoid creating archives with components that have duplicate basenames. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1057&r2=1.1057.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ltmain.sh.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.24&r2=1.24.30.1
I am going to assume this is fixed so I am going to close as such.