bug-libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Concurrent extraction of convenience-library components on OS X


From: Ralf Wildenhues
Subject: Re: Concurrent extraction of convenience-library components on OS X
Date: Wed, 27 May 2009 21:51:24 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

Hi Peter,

* Peter O'Gorman wrote on Tue, May 19, 2009 at 02:26:04AM CEST:
> Ralf Wildenhues wrote:
> > * Akim Demaille wrote on Mon, May 18, 2009 at 02:22:56PM CEST:
> >> I have two dlopen-modules that use a common convenience library.  If I'm 
> >> unlucky, libtool will try to extract the objects from the convenience 
> >> library at the same moment, which ar does not seem to like.
> > 
> > Wow.  What in the world does Darwin's ar do to a library that it is
> > extracting from?
> 
> It flock()'s it.
> http://opensource.apple.com/source/cctools/cctools-698.1/ar/archive.c
> 
> Will file a bug later.

Thanks; has anything come from that yet?

Anyway; what about this patch?  Please note that the patch requires that
the second argument to func_extract_an_archive has an absolute path; not
sure whether that is universally true.

Thanks,
Ralf

    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.

diff --git a/NEWS b/NEWS
index ff6731c..b300757 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,9 @@ New in 2.2.8 2009-??-??: git version 2.2.7a, Libtool team:
   - Argument mangling of execute mode has been improved (i.e., lessened).
   - Fix 2.1b regression that caused nm to not be the default name lister.
     The regression affected mainly (arguably broken) cross compiles.
+  - 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:
 
diff --git a/doc/libtool.texi b/doc/libtool.texi
index 15e4827..176f797 100644
--- a/doc/libtool.texi
+++ b/doc/libtool.texi
@@ -5679,6 +5679,11 @@ these commands, libtool will proceed to link against 
@var{$objdir/$newlib}
 instead of @var{soname}.
 @end defvar
 
address@hidden 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.
address@hidden defvar
+
 @defvar build
 @defvarx build_alias
 @defvarx build_os
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 76a456f..ac59a27 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2225,7 +2225,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
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 5f323d3..c47a941 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -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
 
 
diff --git a/tests/darwin.at b/tests/darwin.at
index 6284116..e50a6a8 100644
--- a/tests/darwin.at
+++ b/tests/darwin.at
@@ -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,48 @@ 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 foo (void);
+int bar (void) { return foo (); }
+]])
+cp bar.c baz.c
+
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c foo.c],
+        [], [ignore], [ignore])
+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 foo.lo],
+        [], [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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]