summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary V. Vaughan <gary@gnu.org>2004-09-16 14:57:02 +0000
committerGary V. Vaughan <gary@gnu.org>2004-09-16 14:57:02 +0000
commit0e0104aa456bd86f59f15afbeff12699a35d8110 (patch)
treec2d23a3d55659caa40d61531bf3f3629b9c1a0fb
parent7955f590bb4ad0f8990cf33e6ad08baca1c66e88 (diff)
downloadlibtool-0e0104aa456bd86f59f15afbeff12699a35d8110.tar.gz
My most recent `2004-09-02 Gary V. Vaughan' patch for mkdir_p
below is horrendously broken since it makes the installed libtool try to run the mkinstalldirs or install-sh helper scripts. This patch fixes the `make -j' mkdir race condition internally: * libtoolize.in (func_mkdir_p): New slice and dice algorithm to build the directory tree one dir at a time, ignoring errors until the end incase they are transient due to a concurrent identical mkdir. * tests/defs (func_mkdir_p): Ditto. * config/ltmain.in (func_mkdir_p): Ditto, except that ltmain.in uses $echo rather than $ECHO, and uses $show and $run to interact correctly with the command line. * configure.ac (AM_INIT_AUTOMAKE): 1.8 is sufficient again. * Makefile.am (edit): Don't substitute automake's $(mkdir_p). * NEWS: Updated.
-rw-r--r--ChangeLog19
-rw-r--r--Makefile.am1
-rw-r--r--NEWS5
-rw-r--r--config/ltmain.in58
-rw-r--r--configure.ac2
-rw-r--r--libtoolize.in91
-rw-r--r--tests/defs51
7 files changed, 158 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index 0aa371cb..784099f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2004-09-16 Gary V. Vaughan <gary@gnu.org>
+
+ My most recent `2004-09-02 Gary V. Vaughan' patch for mkdir_p
+ below is horrendously broken since it makes the installed libtool
+ try to run the mkinstalldirs or install-sh helper scripts. This
+ patch fixes the `make -j' mkdir race condition internally:
+
+ * libtoolize.in (func_mkdir_p): New slice and dice algorithm
+ to build the directory tree one dir at a time, ignoring errors
+ until the end incase they are transient due to a concurrent
+ identical mkdir.
+ * tests/defs (func_mkdir_p): Ditto.
+ * config/ltmain.in (func_mkdir_p): Ditto, except that ltmain.in
+ uses $echo rather than $ECHO, and uses $show and $run to interact
+ correctly with the command line.
+ * configure.ac (AM_INIT_AUTOMAKE): 1.8 is sufficient again.
+ * Makefile.am (edit): Don't substitute automake's $(mkdir_p).
+ * NEWS: Updated.
+
2004-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
* libltdl/loaders/loadlibrary.c: Compilation fixes (originally
diff --git a/Makefile.am b/Makefile.am
index b911b2bc..37f6e8f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,7 +30,6 @@ edit = sed \
-e 's,@pkgdatadir\@,$(pkgdatadir),g' \
-e 's,@aclocaldir\@,$(aclocaldir),g' \
-e 's,@host_triplet\@,$(host_triplet),g' \
- -e 's,@mkdir_p\@,$(mkdir_p),g' \
-e "s,@configure_input\@,Generated from $$input; do not edit by hand,g"
timestamp = set -- `$(MKSTAMP) < $(top_srcdir)/ChangeLog`; \
diff --git a/NEWS b/NEWS
index 5c6dac18..b1118c39 100644
--- a/NEWS
+++ b/NEWS
@@ -6,9 +6,8 @@ New in 1.9d: 2004-??-??; CVS version 1.9c, Libtool team:
back to pic objects.
* When compiling C glue code with $LTCC, libtool now saves the setting of
$compiler_flags from the C tag, and passes those flags to $LTCC.
-* libtool uses automake's $(mkdir_p), and can support `make -j' on
- multi-processor hosts if automake discovered a multithreadable mkdir. If
- it still doesn't work for you, install GNU mkdir (in GNU coreutils).
+* libtool no longer dies when concurrently creating directories with
+ `make -j' on multi-processor hosts.
* Return type, and name parameter of lt_dlloader_remove are no longer
`const'.
* Name parameter of lt_dlloader_find is no longer 'const'.
diff --git a/config/ltmain.in b/config/ltmain.in
index 08fac5ea..135710d5 100644
--- a/config/ltmain.in
+++ b/config/ltmain.in
@@ -86,7 +86,7 @@ DUALCASE=1; export DUALCASE # for MKS sh
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-: ${MKDIR_P="@mkdir_p@"}
+: ${MKDIR="mkdir"}
: ${RM="rm -f"}
: ${MV="mv -f"}
@@ -157,7 +157,7 @@ magic="%%%MAGIC variable%%%"
Xsed="${SED}"' -e 1s/^X//'
sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
# test EBCDIC or ASCII
-case `echo A|tr A '\301'` in
+case `$echo A|tr A '\301'` in
A) # EBCDIC based system
SP2NL="tr '\100' '\n'"
NL2SP="tr '\r\n' '\100\100'"
@@ -715,27 +715,47 @@ Otherwise, only FILE itself is deleted using RM."
# func_mkdir_p directory-path
-# Use automake's best guess at a multithreadable mkdir command to create
-# DIRECTORY-PATH in a way that shouldn't interfere with `make -j'.
-func_mkdir_p () {
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
my_directory_path="$1"
- my_status=
+ my_dir_list=
- test -f "$my_directory_path" && {
- $show "${RM}r $my_directory_path"
- $run ${RM}r "$my_directory_path"
- }
+ if test -n "$my_directory_path"; then
- $show "$MKDIR_P $my_directory_path"
- test -n "$my_directory_path" && {
- $run $MKDIR_P "$my_directory_path"
- my_status=$?
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
- # Bail out if $MKDIR_P failed to create a directory.
- test "$my_status" -ne $EXIT_SUCCESS && \
- test ! -d "$my_directory_path" && \
- exit $my_status
- }
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$echo "$my_directory_path" | $SED "$dirname"`
+ done
+ my_dir_list=`$echo $my_dir_list | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+ fi
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
}
diff --git a/configure.ac b/configure.ac
index a52de30c..0e13cd99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,7 +112,7 @@ AC_SUBST([package_revision])
dnl These are bootstrap requirements, once built, libtool may work with
dnl much older releases of autoconf and automake. See release notes.
-AM_INIT_AUTOMAKE([1.9 gnits dist-bzip2]) ## We use parallel $(mkdir_p)
+AM_INIT_AUTOMAKE([1.8 gnits dist-bzip2]) ## We use auto-m4_including
dnl Make sure config.status is regenerated when the version timestamp changes
AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ['$(top_builddir)/stamp-vcl'])
diff --git a/libtoolize.in b/libtoolize.in
index 0c1cdef8..9087bd3b 100644
--- a/libtoolize.in
+++ b/libtoolize.in
@@ -75,8 +75,9 @@ DUALCASE=1; export DUALCASE # for MKS sh
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
: ${CP="cp -f"}
+: ${ECHO="echo"}
: ${LN_S="@LN_S@"}
-: ${MKDIR_P="@mkdir_p@"}
+: ${MKDIR="mkdir"}
: ${RM="rm -f"}
: ${SED="@SED@"}
@@ -91,13 +92,13 @@ basename="s,^.*/,,g"
progpath="$0"
# The name of this program:
-progname=`echo "$progpath" | $SED "$basename"`
+progname=`$ECHO "$progpath" | $SED "$basename"`
PROGRAM=libtoolize
# Make sure we have an absolute path for reexecution:
case $progpath in
[\\/]*|[A-Za-z]:\\*) ;;
- *) progdir=`echo "$progpath" | $SED "$dirname"`
+ *) progdir=`$ECHO "$progpath" | $SED "$dirname"`
progdir=`cd "$progdir" && pwd`
progpath="$progdir/$progname"
;;
@@ -137,7 +138,7 @@ configure_ac=configure.in
# Echo program name prefixed message.
func_echo ()
{
- echo $progname: ${1+"$@"}
+ $ECHO $progname: ${1+"$@"}
}
# func_verbose arg...
@@ -151,7 +152,7 @@ func_verbose ()
# Echo program name prefixed message to standard error.
func_error ()
{
- echo $progname: ${1+"$@"} 1>&2
+ $ECHO $progname: ${1+"$@"} 1>&2
}
# func_fatal_error arg...
@@ -189,8 +190,8 @@ func_usage ()
s/\$progname/'$progname'/;
p;
}; d' < "$progpath"
- echo
- echo "run \`$progname --help | more' for full usage"
+ $ECHO
+ $ECHO "run \`$progname --help | more' for full usage"
exit $EXIT_SUCCESS
}
@@ -248,10 +249,10 @@ func_version ()
--dry-run|-n) if $opt_dry_run; then :; else
opt_dry_run=:
- RM="echo $RM"
- test -n "$LN_S" && LN_S="echo $LN_S"
- CP="echo $CP"
- MKDIR_P="echo $MKDIR_P"
+ RM="$ECHO $RM"
+ test -n "$LN_S" && LN_S="$ECHO $LN_S"
+ CP="$ECHO $CP"
+ MKDIR="$ECHO $MKDIR"
fi
libtoolize_flags="${libtoolize_flags} --dry-run"
;;
@@ -284,15 +285,15 @@ func_version ()
# Separate optargs to long options:
--ltdl=*)
- arg=`echo "$opt" | $SED "$my_sed_long_arg"`
- opt=`echo "$opt" | $SED "$my_sed_long_opt"`
+ arg=`$ECHO "$opt" | $SED "$my_sed_long_arg"`
+ opt=`$ECHO "$opt" | $SED "$my_sed_long_opt"`
set -- "$opt" "$arg" ${1+"$@"}
;;
# Separate non-argument short options:
-c*|-i*|-f*|-n*|-q*|-v*)
- rest=`echo "$opt" |$SED "$my_sed_single_rest"`
- opt=`echo "$opt" |$SED "$my_sed_single_opt"`
+ rest=`$ECHO "$opt" |$SED "$my_sed_single_rest"`
+ opt=`$ECHO "$opt" |$SED "$my_sed_single_opt"`
set -- "$opt" "-$rest" ${1+"$@"}
;;
@@ -308,25 +309,47 @@ func_version ()
# func_mkdir_p directory-path
-# Use automake's best guess at a multithreadable mkdir command to create
-# DIRECTORY-PATH in a way that shouldn't interfere with `make -j'.
-func_mkdir_p () {
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
my_directory_path="$1"
- my_status=
+ my_dir_list=
if test -n "$my_directory_path"; then
- test -f "$my_directory_path" && {
- ${RM}r "$my_directory_path"
- }
- $MKDIR_P "$my_directory_path"
- my_status=$?
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
- # Bail out if $MKDIR_P failed to create a directory.
- test "$my_status" -ne $EXIT_SUCCESS && \
- test ! -d "$my_directory_path" && \
- exit $my_status
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED "$dirname"`
+ done
+ my_dir_list=`$ECHO $my_dir_list | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
fi
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
}
@@ -339,7 +362,7 @@ func_copy ()
my_destfile="$2"
my_return_status=1
- func_mkdir_p `echo "$my_destfile" | $SED "$dirname"`
+ func_mkdir_p `$ECHO "$my_destfile" | $SED "$dirname"`
$RM "$my_destfile"
if $opt_link && $LN_S "$my_srcfile" "$my_destfile"; then
@@ -385,8 +408,8 @@ func_copy_all_files ()
while test -n "$my_srcdirs"; do
IFS="$my_save_IFS"
- my_srcdir=`echo "$my_srcdirs" | sed 's,:.*,,g'`
- my_srcdirs=`echo "$my_srcdirs" | sed 's,:*[^:][^:]*:*,,'`
+ my_srcdir=`$ECHO "$my_srcdirs" | sed 's,:.*,,g'`
+ my_srcdirs=`$ECHO "$my_srcdirs" | sed 's,:*[^:][^:]*:*,,'`
for my_filename in `cd "$my_srcdir" && ls`; do
@@ -397,7 +420,7 @@ func_copy_all_files ()
# Add to the appropriate list
if test -f "$my_srcdir/$my_filename"; then
- my_srcfile=`echo "$my_srcdir/$my_filename" |sed "s,^$my_basedir/*,,"`
+ my_srcfile=`$ECHO "$my_srcdir/$my_filename" |sed "s,^$my_basedir/*,,"`
my_srcfiles="$my_srcfiles${my_srcfiles:+:}$my_srcfile"
elif $my_opt_recurse && test -d "$my_srcdir/$my_filename"; then
my_srcdirs="$my_srcdirs${my_srcdirs:+:}$my_srcdir/$my_filename"
@@ -571,7 +594,7 @@ func_included_files ()
/^m4_include(\[.*\])$/ { s,^m4_include(\[\(.*\)\])$,\1,; p; };
d'
- test -f "$my_searchfile" && echo "$my_searchfile"
+ test -f "$my_searchfile" && $ECHO "$my_searchfile"
# Only recurse when we don't care if all the variables we use get
# trashed, since they are in global scope.
@@ -606,7 +629,7 @@ func_serial ()
# If the file has no serial number, we assume it's ancient.
test -n "$my_serial" || my_serial=0
- echo $my_serial
+ $ECHO $my_serial
}
# func_serial_update srcfile destfile [macro_regex] [old_macro_regex]
diff --git a/tests/defs b/tests/defs
index fd9b3db5..d219480f 100644
--- a/tests/defs
+++ b/tests/defs
@@ -45,7 +45,7 @@ DUALCASE=1; export DUALCASE # for MKS sh
: ${GREP="grep"}
: ${LIBTOOL="../libtool"}
: ${MAKE="make"}
-: ${MKDIR="mkdir"} # FIXME: Use @mkdir_p@ substitution for make -j
+: ${MKDIR="mkdir"}
: ${SED="sed"}
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
@@ -184,19 +184,48 @@ func_grep ()
$GREP "$1" "$2" >/dev/null 2>&1
}
-# func_mkdir_p dir
-# Make sure the entire path to DIR is available.
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
func_mkdir_p ()
{
- my_dir=$1
- my_dirs=
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED "$dirname"`
+ done
+ my_dir_list=`$ECHO $my_dir_list | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+ fi
- while test ! -d "$my_dir"; do
- my_dirs="$my_dir $my_dirs"
- case $my_dir in */*) ;; *) break ;; esac
- my_dir=`$ECHO "$my_dir" | $SED "$dirname"`
- done
- test ! -n "$my_dirs" || $MKDIR $my_dirs
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
}
# func_mkprefixdir