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