Hello, A change dated 2004-12-10 broke handling of archives containing multiple members of the same name for GNU binutils. Unlike what the relevant ChangeLog entry suggests may be true for all ar implementations, GNU ar actually extracts all matching members. OTOH, it only deletes first matching ones. As a result, when renaming archive members, all the new files are really copies of the last member.
This has been observed with the current version of GNU binutils as available in their CVS tree. I'm not sure if this behaviour has always been such, but GNU ar only changed a little over the last few years and a "cvs diff" shows it has been such at least since 2.10 (sourceware.org's CVS history starts then). Additionally GNU ar has severe performance problems with deletion from huge archives (which may or may not be an ar bug, but libtool might consider avoiding it anyway). The problem might have been unnoticed, because the test case that is supposed to detect it is broken. Following is a fix to the test case and a change to ltmain.in I'm currently using (which is more or less a back-out of the problematic commit) to make member renaming work. Beside being correct this change shortens the time needed for a GCC 4.0 full bootstrap from about 6 hours to about 3 hours for me. But the ltmain.in change is not portable -- a configure-time test should be used instead, so I'm not proposing it to be used as is. The test case fix is correct, though, perhaps obviously even, so please apply. 2004-04-04 Maciej W. Rozycki <[EMAIL PROTECTED]> * tests/func_extract_archives.test: Fix expressions used. Maciej libtool-1.5.12-ar-extract-multi.patch diff -up --recursive --new-file libtool-1.5.12.macro/ltmain.in libtool-1.5.12/ltmain.in --- libtool-1.5.12.macro/ltmain.in 2005-02-05 14:04:29.000000000 +0000 +++ libtool-1.5.12/ltmain.in 2005-04-01 00:27:42.000000000 +0000 @@ -274,8 +274,8 @@ func_extract_an_archive () do name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` done - $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_lib '$name' && $mv '$name' '$name_to')" - $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_lib '$name' && $mv '$name' '$name_to' && $AR -d \$f_ex_an_ar_lib '$name')" || exit $? + $show "(cd $f_ex_an_ar_dir && $AR xN $i $f_ex_an_ar_lib '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$f_ex_an_ar_dir && $AR xN $i \$f_ex_an_ar_lib '$name' && $mv '$name' '$name_to')" || exit $? i=`expr $i + 1` done done diff -up --recursive --new-file libtool-1.5.12.macro/tests/func_extract_archives.test libtool-1.5.12/tests/func_extract_archives.test --- libtool-1.5.12.macro/tests/func_extract_archives.test 2005-02-05 13:59:49.000000000 +0000 +++ libtool-1.5.12/tests/func_extract_archives.test 2005-04-01 01:30:40.000000000 +0000 @@ -19,8 +19,8 @@ do done for anum in 1 2 3 4 5 6 7 8 9 10 11 12 do - echo "foo $anum" > foo.o - echo "bar $anum" > bar.o + echo "foo-$anum" > foo.o + echo "bar-$anum" > bar.o ar -q libfoo.a foo.o bar.o done test -d .libs || mkdir .libs @@ -39,7 +39,7 @@ func_extract_archives ".libs/libfoo" "li for anum in 1 2 3 4 5 6 7 8 9 10 11 12 do test -f ".libs/libfoo/libfoo.a/foo-$anum.o" || exit 1 - $EGREP -v "foo-$anum" ".libs/libfoo/libfoo.a/foo-$anum.o" || exit 1 + $EGREP -v "^foo-$anum\$" ".libs/libfoo/libfoo.a/foo-$anum.o" && exit 1 rm -f ".libs/libfoo/libfoo.a/foo-$anum.o" done rm -rf ".libs/libfoo" libfoo.a bar.o foo.o