]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
My most recent `2004-09-02 Gary V. Vaughan' patch for mkdir_p
authorGary V. Vaughan <gary@gnu.org>
Thu, 16 Sep 2004 14:57:02 +0000 (14:57 +0000)
committerGary V. Vaughan <gary@gnu.org>
Thu, 16 Sep 2004 14:57:02 +0000 (14:57 +0000)
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.

ChangeLog
Makefile.am
NEWS
config/ltmain.in
configure.ac
libtoolize.in
tests/defs

index 0aa371cb18ce4a7c9119cee5912f3d0d6f7e3579..784099f38b182c81870621352995f54044adc1fa 100644 (file)
--- 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
index b911b2bcd3ad683dad0e5c79a47a9ab88b4c78c6..37f6e8f4397b9fd439c63938b7e05ac1f31c817b 100644 (file)
@@ -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 5c6dac18b5322c8f69c247e4fce637c5e430389d..b1118c391d30fdaa652e76882e1be068da268bbd 100644 (file)
--- 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'.
index 08fac5ea3c23bd11361504683e32570870301bf5..135710d5a776eadcf985e794c8a1c0b302a0e403 100644 (file)
@@ -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'"
 }
 
 
index a52de30cee235af4e8f553e5a10dc43d7d57e1cd..0e13cd996b9c5d2f6ed2106a90e4b4a49f361734 100644 (file)
@@ -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'])
index 0c1cdef8cc3d99bc48844ce66397b5d5b8e7c030..9087bd3b6dc8e9e22c2f05672f91ce4ce07fa8c7 100644 (file)
@@ -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]
index fd9b3db591327b0c0a4b9b41cd3df7b77f68d0eb..d219480f242d13429a720105c9babcc608ef8bdb 100644 (file)
@@ -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