[Top][All Lists]
[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