libtool-patches
[Top][All Lists]
Advanced

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

[Patch] cwrapper invokes target directly


From: Charles Wilson
Subject: [Patch] cwrapper invokes target directly
Date: Sat, 26 Apr 2008 16:22:39 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080213 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666

As mentioned here:
http://lists.gnu.org/archive/html/bug-libtool/2008-04/msg00159.html
this patch teaches the cwrapper to invoke the target executable directly, without using a shell wrapper. I left the --lt-dump-script option for now, but it's obsoleted by this patch.

I don't think that should impact the dump-script related changes here:
http://lists.gnu.org/archive/html/libtool-patches/2008-04/msg00161.html
because we should move cautiously in eliminating existing functionality. See FAIL: tests/demo-exec.test below, for why retaining this is valuable.


This patch also adds the following three command line options to the wrapper executable:

--lt-env-set     foo=bar
--lt-env-prepend foo=bar
--lt-env-append  foo=bar

The first sets the environment variable foo to bar. The second sets the environment variable foo to bar${foo}. The third sets the environment variable foo to ${foo}bar. In no case is substitution performed on bar, or the contents of foo. Also, arguments can be chained, and are processed in order:

--lt-env-prepend foo=bar \
--lt-env-append  foo=baz \
--lt-env-prepend foo=buzz

will set foo to buzzbar${foo}baz

foo= is okay, and will unset foo. foo=bar=baz will set foo to bar=baz. However, if the argument to any of these three options is missing or does not contain an '=' at all, then an error message is printed and the wrapper executable exits with non-zero status.


One of the difficulties is that the cwrapper -- because it is compiled for $host -- needs to know that native (that is $host) path to the target. So there are two new shell functions in ltmain.m4sh:

func_to_native_path
func_to_native_pathlist

(perhaps these should be renamed s/native/host/ ?)

Currently, if $host is /not/ mingw, they both return their argument unchanged ("return" defined as setting a specify *_result variable). However, if $host is mingw, then the behavior depends on $build:

(a) mingw (actually, msys): use the 'cmd //c echo $1' trick to force msys to convert $1 to win32 -- then canonicalize for inclusion in a C char*. This last bit is very naive.

(b) cygwin: use 'cygpath -w $1'; ditto C char*.

(c) other: in *this* patch, do nothing (that is, return argument unchanged). This means that cross-compiles with $mingw host still don't work. While that's a regression from 1.5, it is not a regressino from 2.2. But thie point here is to /fix/ that, so see below.

So: as follow-ons to this patch, I intend to

(1) $host=mingw, $build=!(mingw|cygwin), use winepath to convert $1, IF winepath is found. If not, issue an error/warning message but continue the build -- because you might not CARE if you can run the uninstalled executables.

(2) extend the above for $host=cygwin. This would require chaining winepath (if found) and invoking cygpath within the wine environment, unless the developer has deliberately set up identity mounts in her wine/cygwin configuration (e.g. since wine maps '/' to 'Z:', then cygwin-inside-wine could map the various Z:\* paths she cares about to '/*'. Obviously not including /bin, /lib, or /usr. But we can't depend on that). However, the developer may have multiple cygwin trees installed -- and starting with cygwin-1.7.0 each one can have its own mount 'table' in its own /etc/fstab, so there is no single registry location. Thus, it *matters* which cygpath.exe is invoked. So she'll have to specify the path to the specific cygpath she wants to use. Note that this is /not/ required in case (b) above.

I'm going to need help with #2.

So, attached are three files:
(A) the patch, implementing (a), (b), and (c) above.
(B) a test script that contains a copy of the two shell functions func_to_native_path() and func_to_native_pathlist(), with a quick-n-dirty command line wrapper, for testing (C) a different version of the test script that adds support for (1) above. The pathlist conversion is a bit ugly, because winepath doesn't do pathlists by itself.

I've tested (1) on cygwin (native) and mingw (native e.g. msys). On cygwin, all tests passed except new-testsuite #10, #23. and #70 (all pre-existing),

On mingw, I had only slightly worse results

FAIL: tests/mdemo-dryrun.test
   my fault, I had another terminal window open in the .libs
   directory...

FAIL: tests/demo-exec.test (from the demo-shared configuration)
not the wrapper's fault. hell.exe works, as does hell_static.exe. helldl.exe (the target) crashes after being successfully invoked by either the cwrapper or the old script wrapper as produced by the --lt-dump-script option of the cwrapper.

FAIL: tests/f77demo-static.test
FAIL: tests/f77demo-conf.test
FAIL: tests/f77demo-shared.test
   I don't know about this. It doesn't seem related to these changes:

configure:4209: /usr/local/src/libtool/libtool-2.2.3a/libltdl/config/compile gcc -o conftest.exe -g -O2 conftest.c -L/usr/lib -L/bin/../lib/gcc-lib/i686-pc-msys/2.95.3-1 -L/bin/../lib/gcc-lib -L/usr/lib/gcc-lib/i686-pc-msys/2.95.3-1 -L/bin/../lib/gcc-lib/i 686-pc-msys/2.95.3-1/../../../../i686-pc-msys/lib -L/usr/lib/gcc-lib/i686-pc-msys/2.95.3-1/../../../../i686-pc-msys/lib -lg2c -lms
ys-1.0 -luser32 -lkernel32 -ladvapi32 -lshell32 >&5
C:/msys/1.0/lib/libmsys-1.0.dll.a(ds00563.o):(.text+0x0): multiple definition of `atexit'
/mingw/lib/crt2.o:crt1.c:(.text+0x2c0): first defined here
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o:crtstuff.c:(.text+0x5): undefined reference to `__w32_sharedptr_initialize'
collect2: ld returned 1 exit status
configure:4215: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "f77demo"
| #define PACKAGE_TARNAME "f77demo"
| #define PACKAGE_VERSION "1.0"
| #define PACKAGE_STRING "f77demo 1.0"
| #define PACKAGE_BUGREPORT "address@hidden"
| #define PACKAGE "f77demo"
| #define VERSION "1.0"
| /* end confdefs.h.  */
| #define F77_DUMMY_MAIN _main
| #ifdef F77_DUMMY_MAIN
|
| #  ifdef __cplusplus
|      extern "C"
| #  endif
|    int F77_DUMMY_MAIN() { return 1; }
|
| #endif
| int
| main ()
| {
|
|   ;
|   return 0;
| }
configure:4242: result: unknown
configure:4262: error: linking to Fortran libraries from C fails

new:

#10, #23, #70 -- pre-existing failures

 56: compiling softlinked libltdl                    FAILED
 57: compiling copied libltdl                        FAILED
 58: installable libltdl                             FAILED

Something is going wrong with the 'Msys Supplementary Tools: Tech preview for msys 1.0.11' auto* wrapper system. aclocal is a gentoo-derived wrapper, that is trying to exec 'aclocal-1.10', but fails for some reason... C:\msys\1.0\local\bin\aclocal: line 156: exec: C:\msys\1.0\local\bin\aclocal-1.10: not found
autoreconf-2.61: aclocal failed with exit status: 127

Note that C:\msys\1.0\local\bin\aclocal-1.10 (aka /usr/local/aclocal-1.10) does exist, and if I replace the wrapper with a copy of aclocal-1.10, 56, 57, and 58 all pass.

Note that I do not expect the testsuite to be runnable on a linux->mingw cross, just yet.


2008-04-26  Charles Wilson  <...>

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

        * 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.

--
Chuck




diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index ac334dc..d145766 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2247,8 +2247,6 @@ func_extract_archives ()
     func_extract_archives_result="$my_oldobjs"
 }
 
-
-
 # func_emit_wrapper arg
 #
 # emit a libtool wrapper script on stdout
@@ -2474,6 +2472,106 @@ fi\
 }
 # end: func_emit_wrapper
 
+# func_to_native_path
+#
+# 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 ()
+{
+  func_to_native_path_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* ) # 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"`
+            ;;
+          *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"`
+            ;;
+        esac
+        if test -z "$func_to_native_path_result" ; then
+          func_error "Could not determine native path corresponding to"
+          func_error "  '$1'"
+          func_error "Perhaps it doesn't exist."
+          func_error "Continuing, but running uninstalled executables may not 
work."
+        fi
+        ;;
+    esac
+  fi
+}
+# end: func_to_native_path
+
+# func_to_native_pathlist
+#
+# 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 ()
+{
+  func_to_native_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|:*$||'`
+            ;;
+        esac
+        case $build in
+          *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" |\
+              $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"`
+            ;;
+          *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"`
+            ;;
+        esac
+        if test -z "$func_to_native_pathlist_result" ; then
+          func_error "Could not determine the native 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."
+        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" ;;
+            esac
+            case "$1" in
+              *: ) 
func_to_native_pathlist_result="$func_to_native_pathlist_result;" ;;
+            esac
+            ;;
+        esac
+        ;;
+    esac
+  fi
+}
+# end: func_to_native_pathlist
+
 # func_emit_cwrapperexe_src
 # emit the source code for a wrapper executable on stdout
 # Must ONLY be called from within func_mode_link because
@@ -2509,6 +2607,11 @@ EOF
 # include <stdint.h>
 # ifdef __CYGWIN__
 #  include <io.h>
+#  define HAVE_SETENV
+#  ifdef __STRICT_ANSI__
+int putenv (char *);
+int setenv (const char *, const char *, int);
+#  endif
 # endif
 #endif
 #include <malloc.h>
@@ -2615,6 +2718,14 @@ int make_executable (const char *path);
 int check_executable (const char *path);
 char *strendzap (char *str, const char *pat);
 void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
 
 static const char *script_text =
 EOF
@@ -2626,18 +2737,53 @@ EOF
 
            cat <<EOF
 const char * MAGIC_EXE = "$magic_exe";
+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"
+             cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_native_pathlist_result";
+EOF
+           else
+             cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+           fi
+
+           if test -n "$dllsearchpath"; then
+              func_to_native_pathlist "$dllsearchpath:"
+             cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_native_pathlist_result";
+EOF
+           else
+             cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+           fi
+
+           cat <<"EOF"
+
+static const char *dumpscript_opt  = "--lt-dump-script";
+static const char *env_set_opt     = "--lt-env-set";
+  /* argument is putenv-style "foo=bar", value of foo is set to bar */
+static const char *env_prepend_opt = "--lt-env-prepend";
+  /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+static const char *env_append_opt  = "--lt-env-append";
+  /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
 
 int
 main (int argc, char *argv[])
 {
   char **newargz;
+  int  newargc;
   char *tmp_pathspec;
   char *actual_cwrapper_path;
-  char *shwrapper_name;
+  char *target_name;
   intptr_t rval = 127;
-  FILE *shwrapper;
 
-  const char *dumpscript_opt = "--lt-dump-script";
   int i;
 
   program_name = (char *) xstrdup (base_name (argv[0]));
@@ -2657,38 +2803,13 @@ EOF
                ;;
              esac
 
-           cat <<EOF
+           cat <<"EOF"
          printf ("%s", script_text);
          return 0;
        }
     }
 
-  newargz = XMALLOC (char *, argc + 2);
-EOF
-
-           if test -n "$TARGETSHELL" ; then
-             # no path translation at all
-             lt_newargv0=$TARGETSHELL
-           else
-             case "$host" in
-               *mingw* )
-                 # awkward: cmd appends spaces to result
-                 lt_sed_strip_trailing_spaces="s/[ ]*\$//"
-                 lt_newargv0=`( cmd //c echo $SHELL | $SED -e 
"$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
-                 case $lt_newargv0 in
-                   *.exe | *.EXE) ;;
-                   *) lt_newargv0=$lt_newargv0.exe ;;
-                 esac
-                 ;;
-               * ) lt_newargv0=$SHELL ;;
-             esac
-           fi
-
-               cat <<EOF
-  newargz[0] = (char *) xstrdup ("$lt_newargv0");
-EOF
-
-           cat <<"EOF"
+  newargz = XMALLOC (char *, argc + 1);
   tmp_pathspec = find_executable (argv[0]);
   if (tmp_pathspec == NULL)
     lt_fatal ("Couldn't find %s", argv[0]);
@@ -2700,39 +2821,38 @@ EOF
                          actual_cwrapper_path));
   XFREE (tmp_pathspec);
 
-  shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
-  strendzap (actual_cwrapper_path, shwrapper_name);
-
-  /* shwrapper_name transforms */
-  strendzap (shwrapper_name, ".exe");
-  tmp_pathspec = XMALLOC (char, (strlen (shwrapper_name) +
-                                strlen ("_ltshwrapperTMP") + 1));
-  strcpy (tmp_pathspec, shwrapper_name);
-  strcat (tmp_pathspec, "_ltshwrapperTMP");
-  XFREE (shwrapper_name);
-  shwrapper_name = tmp_pathspec;
+  target_name = (char *) xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, target_name);
+
+  /* target_name transforms */
+  strendzap (target_name, ".exe");
+  tmp_pathspec = XMALLOC (char, (strlen (target_name) +
+                                strlen (".exe") + 1));
+  strcpy (tmp_pathspec, target_name);
+  strcat (tmp_pathspec, ".exe");
+  XFREE (target_name);
+  target_name = tmp_pathspec;
   tmp_pathspec = 0;
-  LTWRAPPER_DEBUGPRINTF (("(main) libtool shell wrapper name: %s\n",
-                         shwrapper_name));
+  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+                         target_name));
 EOF
 
            cat <<EOF
-  newargz[1] =
+  newargz[0] =
     XMALLOC (char, (strlen (actual_cwrapper_path) +
-                   strlen ("$objdir") + 1 + strlen (shwrapper_name) + 1));
-  strcpy (newargz[1], actual_cwrapper_path);
-  strcat (newargz[1], "$objdir");
-  strcat (newargz[1], "/");
-  strcat (newargz[1], shwrapper_name);
+                   strlen ("$objdir") + 1 + strlen (target_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+  strcat (newargz[0], target_name);
 EOF
 
-
            case $host_os in
              mingw*)
            cat <<"EOF"
   {
     char* p;
-    while ((p = strchr (newargz[1], '\\')) != NULL)
+    while ((p = strchr (newargz[0], '\\')) != NULL)
       {
        *p = '/';
       }
@@ -2742,39 +2862,77 @@ EOF
            esac
 
            cat <<"EOF"
-  XFREE (shwrapper_name);
+  XFREE (target_name);
   XFREE (actual_cwrapper_path);
 
-  /* always write in binary mode */
-  if ((shwrapper = fopen (newargz[1], FOPEN_WB)) == 0)
-    {
-      lt_fatal ("Could not open %s for writing", newargz[1]);
-    }
-  fprintf (shwrapper, "%s", script_text);
-  fclose (shwrapper);
-
-  make_executable (newargz[1]);
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
 
+  newargc=0;
   for (i = 1; i < argc; i++)
-    newargz[i + 1] = xstrdup (argv[i]);
-  newargz[argc + 1] = NULL;
+    {
+      if (strcmp (argv[i], env_set_opt) == 0)
+        {
+          if (i+1 < argc)
+            {
+              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 (i+1 < argc)
+            {
+              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 (i+1 < argc)
+            {
+              lt_opt_process_env_append (argv[i+1]);
+              i++; /* don't copy */
+            }
+          else
+            {
+              lt_fatal ("%s missing required argument", env_append_opt);
+            }
+          continue;
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
 
-  for (i = 0; i < argc + 1; i++)
+  for (i = 0; i < newargc; i++)
     {
-      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, newargz[i]));
+      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? 
newargz[i] : "<NULL>")));
     }
 
 EOF
 
            case $host_os in
              mingw*)
-               cat <<EOF
+               cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
-  rval = _spawnv (_P_WAIT, "$lt_newargv0", (const char * const *) newargz);
+  rval = _spawnv (_P_WAIT, newargz[0], (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
-      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target 
\"$lt_newargv0\": errno = %d\n", errno));
+      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = 
%d\n", newargz[0], errno));
       return 127;
     }
   return rval;
@@ -2782,8 +2940,8 @@ EOF
 EOF
                ;;
              *)
-               cat <<EOF
-  execv ("$lt_newargv0", newargz);
+               cat <<"EOF"
+  execv (newargz[0], newargz);
   return rval; /* =127, but avoids unused variable warning */
 }
 EOF
@@ -3064,6 +3222,176 @@ lt_fatal (const char *message, ...)
   lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
   va_end (ap);
 }
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+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);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcat (new_value, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcat (new_value, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+  const char *p;
+  int len;
+  if (!arg || !*arg)
+    return 1;
+
+  p = strchr (arg, (int)'=');
+
+  if (!p)
+    return 1;
+
+  *value = xstrdup (++p);
+
+  len = strlen (arg) - strlen (*value);
+  *name = XMALLOC (char, len);
+  strncpy (*name, arg, len-1);
+  (*name)[len-1] = '\0';
+
+  return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+    }
+
+  lt_setenv (name, value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 0);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 1);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending 
'%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR 
(new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending 
'%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+
 EOF
 }
 # end: func_emit_cwrapperexe_src
#!/bin/bash

func_error ()
{
  echo "Error: $1" 1>&2
}
func_warning ()
{
  echo "Warning: $1" 1>&2
}

if test -z "$1" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi
if test -z "$2" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi
if test -z "$3" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi

host="$1"
build="$2"
SED=sed

func_to_native_path ()
{
  func_to_native_path_result="$1"
  if test -n "$1" ; then
    case $host in
      *mingw* )
        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
        func_to_native_path_result=""
        case $build in
          *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"`
            ;;
          *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"`
            ;;
        esac
        if test -z "$func_to_native_path_result" ; then
          func_error "Could not determine native path corresponding to"
          func_error "  '$1'"
          func_error "Perhaps it doesn't exist."
          func_error "Continuing, but running uninstalled executables may not 
work."
        fi
        ;;
    esac
  fi
}

func_to_native_pathlist()
{
  func_to_native_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|:*$||'`
            ;;
        esac
        case $build in
          *mingw* ) # actually, msys

            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
            func_to_native_pathlist_tmp2=`( cmd //c echo 
"$func_to_native_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"`
            ;;
          *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"`
            ;;
        esac
        if test -z "$func_to_native_pathlist_result" ; then
          func_error "Could not determine the native 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."
        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" ;;
            esac
            case "$1" in
              *: ) 
func_to_native_pathlist_result="$func_to_native_pathlist_result;" ;;
            esac
            ;;
        esac
        ;;
    esac
  fi
}

func_to_native_pathlist "$3"
echo "'$func_to_native_pathlist_result'"

#!/bin/bash

func_error ()
{
  echo "Error: $1" 1>&2
}
func_warning ()
{
  echo "Warning: $1" 1>&2
}

if test -z "$1" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi
if test -z "$2" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi
if test -z "$3" ; then
  func_error "Usage: $0 host build pathlist"
  exit 1
fi

host="$1"
build="$2"
SED=sed

func_to_native_path ()
{
  func_to_native_path_result="$1"
  if test -n "$1" ; then
    case $host in
      *mingw* )
        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
        func_to_native_path_result=""
        case $build in
          *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"`
            ;;
          *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"`
            ;;
          * )
            if winepath -h >/dev/null 2>&1 ; then
              func_to_native_path_tmp1=`winepath -w "$1"`
              func_to_native_path_result=`echo "$func_to_native_path_tmp1" | 
$SED -e "$lt_sed_naive_backslashify"`
            fi
            ;;
        esac
        if test -z "$func_to_native_path_result" ; then
          func_error "Could not determine native path corresponding to"
          func_error "  '$1'"
          func_error "Perhaps it doesn't exist."
          func_error "Continuing, but running uninstalled executables may not 
work."
        fi
        ;;
    esac
  fi
}

func_to_native_pathlist()
{
  func_to_native_pathlist_result="$1"
  if test -n "$1" ; then
    case $host in
      *mingw* )
        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
        # remove leading and trailing ':' from $1.  msys behavior is
        # inconsistent here, cygpath turns them into into '.;' and ';.'
        # and winepath ignores them completely.
        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|:*$||'`
        case $build in
          *mingw* ) # actually, msys

            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
            func_to_native_pathlist_tmp2=`( cmd //c echo 
"$func_to_native_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"`
            ;;
          *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"`
            ;;
          * )
            # unfortunately, winepath doesn't convert pathlists
            func_to_native_pathlist_result=""
            func_to_native_pathlist_oldIFS=$IFS
            IFS=:
            for func_to_native_pathlist_f in $func_to_native_pathlist_tmp1 ; do
              IFS=$func_to_native_pathlist_oldIFS
              if test -n "$func_to_native_pathlist_f" ; then
                func_to_native_path "$func_to_native_pathlist_f"
                if test -n "$func_to_native_path_result" ; then
                  if test -z "$func_to_native_pathlist_result" ; then
                    func_to_native_pathlist_result="$func_to_native_path_result"
                  else
                    
func_to_native_pathlist_result="$func_to_native_pathlist_result;$func_to_native_path_result"
                  fi
                fi
              fi
              IFS=:
            done
            IFS=$func_to_native_pathlist_oldIFS
            ;;
        esac
        if test -z "$func_to_native_pathlist_result" ; then
          func_error "Could not determine the native 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."
        fi
        # Now, add the leading and trailing ':' back
        case "$1" in
          :* ) 
func_to_native_pathlist_result=";$func_to_native_pathlist_result" ;;
        esac
        case "$1" in
          *: ) 
func_to_native_pathlist_result="$func_to_native_pathlist_result;" ;;
        esac
        ;;
    esac
  fi
}

func_to_native_pathlist "$3"
echo "'$func_to_native_pathlist_result'"


reply via email to

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