]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Fix concurrent extraction of convenience libraries on Darwin.
authorRalf Wildenhues <Ralf.Wildenhues@gmx.de>
Wed, 10 Jun 2009 17:47:33 +0000 (19:47 +0200)
committerRalf Wildenhues <Ralf.Wildenhues@gmx.de>
Wed, 10 Jun 2009 17:47:33 +0000 (19:47 +0200)
* libltdl/m4/libtool.m4 (_LT_CMD_OLD_ARCHIVE): New libtool
variable `lock_old_archive_extraction', set to `yes' on darwin.
* doc/libtool.texi (libtool script contents): Document it.
* libltdl/config/ltmain.m4sh (func_extract_an_archive): Lock
`ar x' invocation if `lock_old_archive_extraction' is yes.
* tests/darwin.at (darwin concurrent library extraction): New
test.
* NEWS: Update.
Report by Akim Demaille.

Signed-off-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
ChangeLog
NEWS
doc/libtool.texi
libltdl/config/ltmain.m4sh
libltdl/m4/libtool.m4
tests/darwin.at

index 596abeac4bbce8e3c6008244e3d3b8ee6081ae9a..0eedffde51bebce73e1a4431df557ee38d1f1810 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-10  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
+
+       Fix concurrent extraction of convenience libraries on Darwin.
+       * libltdl/m4/libtool.m4 (_LT_CMD_OLD_ARCHIVE): New libtool
+       variable `lock_old_archive_extraction', set to `yes' on darwin.
+       * doc/libtool.texi (libtool script contents): Document it.
+       * libltdl/config/ltmain.m4sh (func_extract_an_archive): Lock
+       `ar x' invocation if `lock_old_archive_extraction' is yes.
+       * tests/darwin.at (darwin concurrent library extraction): New
+       test.
+       * NEWS: Update.
+       Report by Akim Demaille.
+
 2009-06-07  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        Fix testsuite failure of lt_dlopenadvise test on FreeMiNT.
diff --git a/NEWS b/NEWS
index 3656acdd7f0b04f6c9c352b1c9031017a1839389..5a57891863219801b9f818bd2b57739993d28de5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,9 @@ New in 2.2.8 2009-??-??: git version 2.2.7a, Libtool team:
     The regression affected mainly (arguably broken) cross compiles.
   - Fix long standing bug that caused compiler checks for Fortran and
     C++ compilers to run twice.
+  - Link mode works around a parallel build failure on Darwin 9.6.0 due
+    to the `ar' `flock'ing an archive upon extraction, by protecting the
+    extraction of convenience archives with a lock.
 
 * Miscellaneous changes:
 
index 5e25531568fe098128d537427058bd2a50e442cb..a7872c6660f8186c0c2691f5a8229ae8d57bb4ce 100644 (file)
@@ -5670,6 +5670,11 @@ these commands, libtool will proceed to link against @var{$objdir/$newlib}
 instead of @var{soname}.
 @end defvar
 
+@defvar lock_old_archive_extraction
+Set to @samp{yes} if the extraction of a static library requires locking
+the library file.  This is required on Darwin.
+@end defvar
+
 @defvar build
 @defvarx build_alias
 @defvarx build_os
index 72660a87e1144f30300c31ecf0f10276e37118b7..02f4d2159d9a143cbddf2bfe95443c74b260122c 100644 (file)
@@ -2222,7 +2222,18 @@ func_extract_an_archive ()
     $opt_debug
     f_ex_an_ar_dir="$1"; shift
     f_ex_an_ar_oldlib="$1"
-    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+       func_echo "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+                  'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
     if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
      :
     else
index 0670980a281e09c27d6c31c62c341bc9feec3529..5f24fab3d762aeda908c3298a5cb01ef8191f204 100644 (file)
@@ -1312,10 +1312,19 @@ if test -n "$RANLIB"; then
   esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
 fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
 _LT_DECL([], [old_postinstall_cmds], [2])
 _LT_DECL([], [old_postuninstall_cmds], [2])
 _LT_TAGDECL([], [old_archive_cmds], [2],
     [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
 ])# _LT_CMD_OLD_ARCHIVE
 
 
index 628411604325676eb9557b44e1ce700b931729d9..8884fd2e1ae28a5c3c447522784b5c9ece85e5fd 100644 (file)
@@ -1,6 +1,6 @@
 # darwin.at - tests specific to Mac OS X
 #
-#   Copyright (C) 2008 Free Software Foundation, Inc.
+#   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 #   Written by Peter O'Gorman, 2008
 #
 #   This file is part of GNU Libtool.
@@ -98,3 +98,53 @@ AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC  -o main$EXEEXT $CPPFLAGS $CFLAGS $L
 
 PATH=$save_PATH
 AT_CLEANUP
+
+
+AT_SETUP([darwin concurrent library extraction])
+
+AT_DATA([foo.c], [[
+int foo (void) { return 0; }
+]])
+
+AT_DATA([bar.c], [[
+extern int foo1 (void);
+int bar (void) { return foo1 (); }
+]])
+cp bar.c baz.c
+
+objects=
+for obj in 1 2 3 4 5 6 7 8; do
+  sed "s/foo/foo$obj/" < foo.c > foo$obj.c
+  AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c foo$obj.c],
+          [], [ignore], [ignore])
+  objects="$objects foo$obj.lo"
+done
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c bar.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c baz.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o libfoo.la $objects],
+        [], [ignore], [ignore])
+
+# Hypothesis: concurrent convenience archive extraction works.
+for i in 1 2 3 4 5; do
+  rm -f libbar.la libbaz.la
+  AT_CHECK([($LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS ]dnl
+          [  -o libbar.la bar.lo -rpath /foo libfoo.la) & ]dnl
+          [($LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS ]dnl
+          [  -o libbaz.la baz.lo -rpath /foo libfoo.la) & ]dnl
+          [wait; test -f libbar.la && test -f libbaz.la],
+          [], [ignore], [ignore])
+done
+
+# Hypothesis: the lock is not used in dry run mode.
+eval "`$LIBTOOL --config | $EGREP '^(objdir)='`"
+# Next line is internal detail.
+lockfile=$objdir/libfoo.a.lock
+echo stamp > $lockfile
+AT_CHECK([$LIBTOOL --dry-run --mode=link $CC $CFLAGS $LDFLAGS ]dnl
+        [ -o libbar.la bar.lo -rpath /foo libfoo.la],
+        [], [ignore], [ignore])
+AT_CHECK([grep stamp $lockfile], [], [ignore])
+
+AT_CLEANUP