libtool-patches
[Top][All Lists]
Advanced

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

Re: [PATCH] [mingw|cygwin] Modify cwrapper to invoke target directly.


From: Charles Wilson
Subject: Re: [PATCH] [mingw|cygwin] Modify cwrapper to invoke target directly.
Date: Fri, 09 May 2008 09:25:31 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.14) Gecko/20080421 Thunderbird/2.0.0.14 Mnenhy/0.7.5.666

Charles Wilson wrote:
2008-05-05  Charles Wilson  <...>

        * libltdl/config/ltmain.m4sh (func_to_native_path):
        new function. If $host is mingw, and $build is mingw
        or cygwin, convert path to mingw native format.
        (func_to_native_pathlist): new function. Ditto, for
        :-separated pathlists.
        (func_emit_cwrapperexe_src) [__CYGWIN__ && __STRICT_ANSI__]:
        ensure putenv and setenv are declared. Define HAVE_SETENV.
        (func_emit_cwrapperexe_src) [main]: add new constants to
        hold desired PATH settings; initialize and convert to native
        mingw format using functions above. Add new command-line
        options --lt-env-set, --lt-env-prepend, and --lt-env-append.
        No longer emit wrapper script as integral part of launching
        child. Remove support for (now) unnecessary $TARGETSHELL.
        Exec actual target executable directly.
        (func_emit_cwrapperexe_src) [lt_setenv]: new function.
        (func_emit_cwrapperexe_src) [lt_extend_str]: new function.
        (func_emit_cwrapperexe_src) [lt_split_name_value]: new function.
        (func_emit_cwrapperexe_src) [lt_opt_process_env_set]: new function.
        (func_emit_cwrapperexe_src) [lt_opt_process_env_prepend]: new function.
        (func_emit_cwrapperexe_src) [lt_opt_process_env_append]: new function.
        (func_emit_cwrapperexe_src) [lt_update_exe_path]: new function.
        (func_emit_cwrapperexe_src) [lt_update_lib_path]: new function.


The attached patch (to be applied over the previous one) addresses the comments received so far. I can post the merged patch if desired -- and of course, I'll squash into a single patch before I push.

Cygwin: passes 115 (9 skip) on old test suite
only two "unexpected" failures on new test suite -- but 25 and 72 are actually expected on cygwin.

Mingw (msys): no regressions over previous results:
old test suite: fails demo-exec after demo-shared (helldl)
fails the fortran tests, but that's a peculiarity of my system

new test suite: fails 25 and 72 (expected), and 58-60 (a problem with the autotool wrappers on my system)

OK for push?

--
Chuck
 libltdl/config/ltmain.m4sh |  267 +++++++++++++++++++++++++++++---------------
 1 files changed, 177 insertions(+), 90 deletions(-)

diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 82f920e..6469beb 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2472,19 +2472,23 @@ fi\
 }
 # end: func_emit_wrapper
 
-# func_to_native_path
+# func_to_host_path ARG
 #
-# intended for use on "native" mingw (where libtool itself
-# is running under the msys shell).  Paths need to be converted
-# to native format when used with native tools. Ordinarily, the
-# (msys) shell automatically converts such things for non-msys
-# applications it launches, but that isn't available from inside
-# the cwrapper. Similar accommodations are necessary for $host
-# mingw and $build cygwin.  Calling this function does no harm
-# on other $build or for other $host.
-func_to_native_path ()
+# Convert paths to build format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell). Ordinarily, the (msys) shell
+# automatically converts such things for non-msys applications
+# it launches, but that isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and $build
+# cygwin.  Calling this function does no harm on other $build or
+# for other $host.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
 {
-  func_to_native_path_result="$1"
+  func_to_host_path_result="$1"
   if test -n "$1" ; then
     case $host in
       *mingw* )
@@ -2493,76 +2497,88 @@ func_to_native_path ()
           *mingw* ) # actually, msys
             # awkward: cmd appends spaces to result
             lt_sed_strip_trailing_spaces="s/[ ]*\$//"
-            func_to_native_path_tmp1=`( cmd //c echo "$1" | $SED -e 
"$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
-            func_to_native_path_result=`echo "$func_to_native_path_tmp1" | 
$SED -e "$lt_sed_naive_backslashify"`
+            func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
             ;;
           *cygwin* )
-            func_to_native_path_tmp1=`cygpath -w "$1"`
-            func_to_native_path_result=`echo "$func_to_native_path_tmp1" | 
$SED -e "$lt_sed_naive_backslashify"`
+            func_to_host_path_tmp1=`cygpath -w "$1"`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
             ;;
         esac
-        if test -z "$func_to_native_path_result" ; then
-          func_error "Could not determine native path corresponding to"
+        if test -z "$func_to_host_path_result" ; then
+          func_error "Could not determine host path corresponding to"
           func_error "  '$1'"
-          func_error "Perhaps it doesn't exist."
-          func_error "Continuing, but running uninstalled executables may not 
work."
+          func_error "Continuing, but uninstalled executables may not work."
         fi
         ;;
     esac
   fi
 }
-# end: func_to_native_path
+# end: func_to_host_path
 
-# func_to_native_pathlist
+# func_to_host_pathlist ARG
+#
+# Convert pathlists to build format when used with build tools.
+# See func_to_host_path(), above.
 #
-# see func_to_native_path, above
-# path separators are also converted from ':' to ';'
-# and if $1 begins or ends with a ':' it is preserved (as ';')
-# on output. This description applies only when $build is
-# mingw (msys) or cygwin, and $host is mingw.
-func_to_native_pathlist ()
+# Path separators are also converted from ':' to ';', and if
+# $1 begins or ends with a ':' it is preserved (as ';') on
+# output. This description applies only when $build is mingw
+# (msys) or cygwin, and $host is mingw.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
 {
-  func_to_native_pathlist_result="$1"
+  func_to_host_pathlist_result="$1"
   if test -n "$1" ; then
     case $host in
       *mingw* )
         lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
         case $build in
           *mingw* | *cygwin* )
-            # remove leading and trailing ':' from $1.  msys behavior is
-            # inconsistent here, and cygpath turns them into into '.;' and ';.'
-            func_to_native_pathlist_tmp1="$1"
-            func_to_native_pathlist_tmp2=`echo "$func_to_native_pathlist_tmp1" 
| $SED -e 's|^:*||'`
-            func_to_native_pathlist_tmp1=`echo "$func_to_native_pathlist_tmp2" 
| $SED -e 's|:*$||'`
+            # Remove leading and trailing ':' from $1. The behavior of
+            # msys is inconsistent here, and cygpath turns them into
+            # into '.;' and ';.'
+            func_to_host_pathlist_tmp2="$1"
+            func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e 's|^:*||' -e 's|:*$||'`
             ;;
         esac
         case $build in
-          *mingw* ) # actually, msys
-            # awkward: cmd appends spaces to result
+          *mingw* ) # Actually, msys.
+            # Awkward: cmd appends spaces to result.
             lt_sed_strip_trailing_spaces="s/[ ]*\$//"
-            func_to_native_pathlist_tmp2=`( cmd //c echo 
"$func_to_native_pathlist_tmp1" |\
+            func_to_host_pathlist_tmp2=`( cmd //c echo 
"$func_to_host_pathlist_tmp1" |\
               $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
-            func_to_native_pathlist_result=`echo 
"$func_to_native_pathlist_tmp2" | $SED -e "$lt_sed_naive_backslashify"`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
             ;;
           *cygwin* )
-            func_to_native_pathlist_tmp2=`cygpath -w -p 
"$func_to_native_pathlist_tmp1"`
-            func_to_native_pathlist_result=`echo 
"$func_to_native_pathlist_tmp2" | $SED -e "$lt_sed_naive_backslashify"`
+            func_to_host_pathlist_tmp2=`cygpath -w -p 
"$func_to_host_pathlist_tmp1"`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
             ;;
         esac
-        if test -z "$func_to_native_pathlist_result" ; then
-          func_error "Could not determine the native path(s) corresponding to"
+        if test -z "$func_to_host_pathlist_result" ; then
+          func_error "Could not determine the host path(s) corresponding to"
           func_error "  '$1'"
-          func_error "perhaps one or more of the paths do not exit."
-          func_error "Continuing, but running uninstalled executables may not 
work."
+          func_error "Continuing, but uninstalled executables may not work."
         fi
         case $build in
           *mingw* | *cygwin* )
             # Now, add the leading and trailing ':' back
             case "$1" in
-              :* ) 
func_to_native_pathlist_result=";$func_to_native_pathlist_result" ;;
+              :* ) 
func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+                ;;
             esac
             case "$1" in
-              *: ) 
func_to_native_pathlist_result="$func_to_native_pathlist_result;" ;;
+              *: ) 
func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+                ;;
             esac
             ;;
         esac
@@ -2570,7 +2586,7 @@ func_to_native_pathlist ()
     esac
   fi
 }
-# end: func_to_native_pathlist
+# end: func_to_host_pathlist
 
 # func_emit_cwrapperexe_src
 # emit the source code for a wrapper executable on stdout
@@ -2741,9 +2757,9 @@ const char * LIB_PATH_VARNAME = "$shlibpath_var";
 EOF
 
            if test "$shlibpath_overrides_runpath" = yes && test -n 
"$shlibpath_var" && test -n "$temp_rpath"; then
-              func_to_native_pathlist "$temp_rpath"
+              func_to_host_pathlist "$temp_rpath"
              cat <<EOF
-const char * LIB_PATH_VALUE   = "$func_to_native_pathlist_result";
+const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
 EOF
            else
              cat <<"EOF"
@@ -2752,10 +2768,10 @@ EOF
            fi
 
            if test -n "$dllsearchpath"; then
-              func_to_native_pathlist "$dllsearchpath:"
+              func_to_host_pathlist "$dllsearchpath:"
              cat <<EOF
 const char * EXE_PATH_VARNAME = "PATH";
-const char * EXE_PATH_VALUE   = "$func_to_native_pathlist_result";
+const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
 EOF
            else
              cat <<"EOF"
@@ -2764,13 +2780,30 @@ const char * EXE_PATH_VALUE   = "";
 EOF
            fi
 
+           if test "$fast_install" = yes; then
+             cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+           else
+             cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+           fi
+
+
            cat <<"EOF"
 
 static const char *dumpscript_opt  = "--lt-dump-script";
+
+static const size_t env_set_opt_len = 12;
 static const char *env_set_opt     = "--lt-env-set";
   /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = 16;
 static const char *env_prepend_opt = "--lt-env-prepend";
   /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len = 15;
 static const char *env_append_opt  = "--lt-env-append";
   /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
 
@@ -2781,7 +2814,9 @@ main (int argc, char *argv[])
   int  newargc;
   char *tmp_pathspec;
   char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
   char *target_name;
+  char *lt_argv_zero;
   intptr_t rval = 127;
 
   int i;
@@ -2821,18 +2856,24 @@ EOF
                          actual_cwrapper_path));
   XFREE (tmp_pathspec);
 
-  target_name = (char *) xstrdup (base_name (actual_cwrapper_path));
-  strendzap (actual_cwrapper_path, target_name);
+  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
 
-  /* target_name transforms */
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- 
prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
   strendzap (target_name, ".exe");
-  tmp_pathspec = XMALLOC (char, (strlen (target_name) +
-                                strlen (".exe") + 1));
-  strcpy (tmp_pathspec, target_name);
-  strcat (tmp_pathspec, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
   XFREE (target_name);
   target_name = tmp_pathspec;
   tmp_pathspec = 0;
+
   LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
                          target_name));
 EOF
@@ -2840,11 +2881,23 @@ EOF
            cat <<EOF
   newargz[0] =
     XMALLOC (char, (strlen (actual_cwrapper_path) +
-                   strlen ("$objdir") + 1 + strlen (target_name) + 1));
+                   strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 
1));
   strcpy (newargz[0], actual_cwrapper_path);
   strcat (newargz[0], "$objdir");
   strcat (newargz[0], "/");
-  strcat (newargz[0], target_name);
+EOF
+
+           cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = 0;
 EOF
 
            case $host_os in
@@ -2856,6 +2909,10 @@ EOF
       {
        *p = '/';
       }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+       *p = '/';
+      }
   }
 EOF
            ;;
@@ -2864,6 +2921,7 @@ EOF
            cat <<"EOF"
   XFREE (target_name);
   XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
 
   lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
   lt_setenv ("DUALCASE", "1");  /* for MSK sh */
@@ -2873,43 +2931,71 @@ EOF
   newargc=0;
   for (i = 1; i < argc; i++)
     {
-      if (strcmp (argv[i], env_set_opt) == 0)
+      size_t arglen = strlen (argv[i]);
+      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
         {
-          if (i+1 < argc)
+          if ((arglen > env_set_opt_len) && (argv[i][env_set_opt_len] == '='))
             {
-              lt_opt_process_env_set (argv[i+1]);
-              i++; /* don't copy */
+              const char *p = argv[i] + env_set_opt_len + 1;
+              lt_opt_process_env_set (p);
             }
-          else
+          else if ((arglen == env_set_opt_len) &&
+                   (i + 1 < argc) &&
+                   (strcmp (argv[i + 1], "--") != 0))
             {
-              lt_fatal ("%s missing required argument", env_set_opt);
+              lt_opt_process_env_set (argv[i + 1]);
+              i++; /* don't copy */
             }
+          else
+            lt_fatal ("%s missing required argument", env_set_opt);
           continue;
         }
-      if (strcmp (argv[i], env_prepend_opt) == 0)
+      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
         {
-          if (i+1 < argc)
+          if ((arglen > env_prepend_opt_len) &&
+              (argv[i][env_prepend_opt_len] == '='))
             {
-              lt_opt_process_env_prepend (argv[i+1]);
-              i++; /* don't copy */
+              const char *p = argv[i] + env_prepend_opt_len + 1;
+              lt_opt_process_env_prepend (p);
             }
-          else
+          else if ((arglen == env_prepend_opt_len) &&
+                   (i + 1 < argc) &&
+                   (strcmp (argv[i + 1], "--") != 0))
             {
-              lt_fatal ("%s missing required argument", env_prepend_opt);
+              lt_opt_process_env_prepend (argv[i + 1]);
+              i++; /* don't copy */
             }
+          else
+            lt_fatal ("%s missing required argument", env_prepend_opt);
           continue;
         }
-      if (strcmp (argv[i], env_append_opt) == 0)
+      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
         {
-          if (i+1 < argc)
+          if ((arglen > env_append_opt_len) &&
+              (argv[i][env_append_opt_len] == '='))
             {
-              lt_opt_process_env_append (argv[i+1]);
-              i++; /* don't copy */
+              const char *p = argv[i] + env_append_opt_len + 1;
+              lt_opt_process_env_append (p);
             }
-          else
+          else if ((arglen == env_append_opt_len) &&
+                   (i + 1 < argc) &&
+                   (strcmp (argv[i + 1], "--") != 0))
             {
-              lt_fatal ("%s missing required argument", env_append_opt);
+              lt_opt_process_env_append (argv[i + 1]);
+              i++; /* don't copy */
             }
+          else
+            lt_fatal ("%s missing required argument", env_append_opt);
+          continue;
+        }
+      if (strcmp (argv[i], "--") == 0)
+        {
+          /* immediately copy all the rest of the arguments */
+          ++i;
+          for (; i < argc; i++)
+            newargz[++newargc] = xstrdup (argv[i]);
+
+          /* same as break, because i = argc */
           continue;
         }
       /* otherwise ... */
@@ -2917,6 +3003,7 @@ EOF
     }
   newargz[++newargc] = NULL;
 
+  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? 
lt_argv_zero : "<NULL>")));
   for (i = 0; i < newargc; i++)
     {
       LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? 
newargz[i] : "<NULL>")));
@@ -2928,11 +3015,11 @@ EOF
              mingw*)
                cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
-  rval = _spawnv (_P_WAIT, newargz[0], (const char * const *) newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
-      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = 
%d\n", newargz[0], errno));
+      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = 
%d\n", lt_argv_zero, errno));
       return 127;
     }
   return rval;
@@ -2941,7 +3028,7 @@ EOF
                ;;
              *)
                cat <<"EOF"
-  execv (newargz[0], newargz);
+  execv (lt_argv_zero, newargz);
   return rval; /* =127, but avoids unused variable warning */
 }
 EOF
@@ -3252,17 +3339,18 @@ lt_extend_str (const char *orig_value, const char *add, 
int to_end)
   char *new_value;
   if (orig_value && *orig_value)
     {
-      int len = strlen (add) + strlen (orig_value) + 1;
-      new_value = XMALLOC (char, len);
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
       if (to_end)
         {
           strcpy (new_value, orig_value);
-          strcat (new_value, add);
+          strcpy (new_value + orig_value_len, add);
         }
       else
         {
           strcpy (new_value, add);
-          strcat (new_value, orig_value);
+          strcpy (new_value + add_len, orig_value);
         }
     }
   else
@@ -3290,7 +3378,7 @@ lt_split_name_value (const char *arg, char** name, char** 
value)
   len = strlen (arg) - strlen (*value);
   *name = XMALLOC (char, len);
   strncpy (*name, arg, len-1);
-  (*name)[len-1] = '\0';
+  (*name)[len - 1] = '\0';
 
   return 0;
 }
@@ -7188,11 +7276,10 @@ EOF
 
            func_emit_cwrapperexe_src > $cwrappersource
 
-           # we should really use a build-platform specific compiler
-           # here, but OTOH, the wrappers (shell script and this C one)
-           # are only useful if you want to execute the "real" binary.
-           # Since the "real" binary is built for $host, then this
-           # wrapper might as well be built for $host, too.
+           # The wrapper executable is built using the $host compiler,
+           # because it contains $host paths and files. If cross-
+           # compiling, it, like the target executable, must be
+           # executed on the $host or under an emulation environment.
            $opt_dry_run || {
              $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
              $STRIP $cwrapper
-- 
1.5.5.1


reply via email to

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