It is just intricate. I'm don't mind a merge after 2.0, but if you deem it ok, I'd put it in CVS HEAD now.
Prologue -------- We assume that the user is not so stup^H^H^H^Hadventurous to do something along these lines: $LIBTOOL --mode=compile --tag=CC $CC -c baz.c -o foo.$OBJEXT $LIBTOOL --mode=compile --tag=F77 $F77 -c foo.f -o bar.$OBJEXT (i.e., one of the _desired_ object file names is the one that a(nother) possibly losing compiler would create by default)? Otherwise, we'd need to enable locking for _all_ compilers if at least one of them turns out to be broken. :-/ We document a similar example in the manual and state that it needs to be avoided anyway. Main part --------- If above may be ruled out, then the patch at the end of this post should fix this locking issue: http://lists.gnu.org/archive/html/libtool-patches/2005-03/msg00252.html Notes: - The creation of the .libs/LoCk_SrC file may cause spurious errors on w32 systems, thus the drop of stderr. - We cannot remove the .libs/LoCk_SrC file in compile mode: that could defeat another libtool process concurrently running. For the same reason, it does not make sense to put the object file name in its _name_. - Not creating the bugger in dry mode is necessary for mdemo-dryrun to succeed. - Testing for its existence in clean mode before removing is a hack, and won't save us in case the user is strange enough to do a parallel clean with `rm' as opposed to `rm -f'. The fact that it is removed on the command line of the first object may seem a bit strange, however I could not see a good reason to add more special code for this. - If the user actually passes a non-existing object file `foo.lo' as the first one for this directory, then the `LoCk_SrC' file will not be removed. - Surely it breaks for a 'libtool --mode=clean' concurrently with a 'libtool --mode=compile'. Some sanity has to be expected from the user. - If any program has name `LoCk_SrC' and needs to be relinked upon execution, things break horribly. Epilogue -------- Unfixed issue (which I don't intend to attack now): - need_locks is not tagged ATM. It should not be (compiler_c_o already is), but tests for later tags should not be able to set it to NO, if earlier ones set it to something else. - putting the object file name in the _contents_ of the lock file is wrong, too, but AFAICS harmless, so it will be fixed later. Cheers, Ralf * libltdl/config/ltmain.m4sh (func_mode_compile): When locking is necessary, hard-link against `.libs/lock_src' instead of `$progpath'. (func_mode_uninstall): In clean mode, remove `LoCk_SrC' if present, along with the first object we remove. Fixes potential hang reported by Marcin Siennicki and others. Index: libltdl/config/ltmain.m4sh =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v retrieving revision 1.35 diff -u -r1.35 ltmain.m4sh --- libltdl/config/ltmain.m4sh 5 Feb 2006 11:06:31 -0000 1.35 +++ libltdl/config/ltmain.m4sh 5 Feb 2006 20:11:07 -0000 @@ -1330,6 +1330,14 @@ # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[[^.]]*$%%'`.${objext} + lock_src="$xdir$objdir/LoCk_SrC" + $opt_dry_run || { + func_mkdir_p "$xdir$objdir" + test -f "$lock_src" || { + { touch "$lock_src" || echo dummy > "$lock_src"; } 2>/dev/null + test -f "$lock_src" || func_fatal_error "Cannot create $lock_src for locking." + } + } lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE" 1 2 15 @@ -1342,7 +1350,7 @@ # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + until $opt_dry_run || ln "$lock_src" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done @@ -6691,12 +6701,18 @@ func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" + rmfiles= # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; + *) + rmdirs="$rmdirs $objdir" + if test "$need_locks" = yes && test -f "$objdir/LoCk_SrC"; then + rmfiles="$rmfiles $objdir/LoCk_SrC" + fi + ;; esac fi @@ -6712,7 +6728,7 @@ continue fi - rmfiles="$file" + rmfiles="$rmfiles $file" case $name in *.la)
