libtool-patches
[Top][All Lists]
Advanced

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

[PATCH] [cygwin|mingw]: Add cross-compile support to cwrapper (take 6)


From: Charles Wilson
Subject: [PATCH] [cygwin|mingw]: Add cross-compile support to cwrapper (take 6)
Date: Tue, 24 Aug 2010 20:24:48 -0000

* libltdl/m4/libtool.m4 (_LT_PATH_CONVERSION_FUNCTIONS): New
function sets libtool variable $to_host_path_cmd, and employs
cache. AC_SUBSTs $to_host_path_cmd, as well.
(_LT_SETUP): Require it.
* tests/testsuite.at: Ensure to_host_path_cmd is passed as a
variable setting on the configure line for (new testsuite) tests.
* Makefile.am: Ensure to_host_path_cmd is included in
TEST_ENVIRONMENT so that it is passed to (old testsuite) tests.
* libltdl/config/ltmain.m4sh (func_cygpath): New function.
(func_init_to_host_pathlist_cmd): New function.
(func_to_host_path): Refactored to... (now uses eval
$to_host_path_cmd).
(func_wine_to_win32_path): Here. New function.
(func_msys_to_win32): Here. New function.
(func_path_convert_check): Here. New function.
(func_noop_path_convert): Here. New function.
(func_msys_to_mingw_path_convert): Here. New function.
(func_cygwin_to_mingw_path_convert): Here. New function.
(func_nix_to_mingw_path_convert): Here. New function.
(func_msys_to_cygwin_path_convert): New function.
(func_nix_to_cygwin_path_convert): New function.
(func_to_host_pathlist): Refactored to... (now uses eval
$to_host_pathlist_cmd and func_init_to_host_pathlist_cmd).
(func_pathlist_convert_check): Here. New function.
(func_pathlist_front_back_pathsep): Here. New function.
(func_wine_to_win32_pathlist): Here. New function.
(func_noop_pathlist_convert): Here. New function.
(func_msys_to_mingw_pathlist_convert): Here. New function.
(func_cygwin_to_mingw_pathlist_convert): Here. New function.
(func_nix_to_mingw_pathlist_convert): Here. New function.
(func_msys_to_cygwin_pathlist_convert): New function.
(func_nix_to_cygwin_pathlist_convert): New function.
---
Originally posted here:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00006.html
but much changed since then. This version actually resembles closely
version 5, below -- and the link there includes a good summary
discussion particularly intended for those who had forgotten all the
context and previous discussion concerning this patch, over the
intervening 6 months. Since it's now been 14 months later...it's still
a good review. So go read it.

See also http://www.cygwin.com/ml/cygwin/2009-02/msg00555.html
but ignore the rest of the thread; there was not a single on-topic
reply and nobody responded to my call for test. :-(


version 2:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00163.html

version 3:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00233.html

version 3a (an overlay on version 3)
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00238.html

More disucssion here:
http://lists.gnu.org/archive/html/libtool-patches/2009-02/msg00010.html

version 4 (squashed 3 and 3a):
http://lists.gnu.org/archive/html/libtool-patches/2009-02/msg00012.html

version 5 (ignore the bogus changelog and the first URL in this message):
http://lists.gnu.org/archive/html/libtool-patches/2009-06/msg00030.html
but the other two URLs in that message are relevant and accurate).

Interesting background discussion here:
http://cygwin.com/ml/cygwin/2009-01/msg00808.html


The original motivation was to enable correct cwrapper *execution*
when cross-compiling to a cygwin target (from linux, primarily) --
where the $build machine was (a) x86 (b) and had wine (c) and had
a cygwin "installation" that could be executed under wine.

However, the framework is, I think, useful for other situations --
and it is a strict improvement for unix->mingw and cygwin->mingw
cross compilation, IMO, because it (a) cleans up and refactors
the existing hodgepodge of case statements for path translation, by
(b) moving a lot of that over to libtool.m4, and (c) uses cacheable --
and thus overridable -- indirection vars to invoke the correct
refactored path translation function (this override capability is
needed for the "lie to me" use case; see cygwin->mingw (lie) below).

That's good, because in the interim between Jan 2009 and now, things
outside of libtool's control have changed: Running cygwin under wine
has always been...complicated, but at least in the relatively recent
past simple .exe's and especially cygpath.exe could be executed without
issue.

As of cygwin-1.7, that no longer appears to be true; I can only
occassionally get any cygwin application to execute under wine without
coredumping -- including cygpath. This might be PIBKAC, since I have
updated/reinstalled my linux OS two or three times since then; OTOH
others have reported difficulties with cygwin-1.7 on wine, too.

Fortunately, the default behavior implemented by this patch (for
*nix->cygwin cross) relies on the value of the user-set variable
LT_CYGPATH (whose value is, obviously, by default empty).  In that
case, the path-conversion logic for unix->cygwin halts after the
interim unix->"dos" conversion, complains about the empty LT_CYGPATH
value, and continues without error.  The result of this is simply
the status quo: the wrapper exe won't work correctly, and you won't
be able to launch the $host exe on the $build platform.

But, since the wrapper exe in this situation would be a cygwin app,
and current cygwin apps all seem to coredump under wine, that's really
not a concern of ours!

Even if the user DOES set LT_CYGPATH to something non-empty (for example,
$sysroot/$prefix/bin/cygpath.exe) and, when libtool tries to execute it
and it coredumps (as it does for me) -- again, we simply have the status
quo: libtool complains, but continues with the "old" unconverted value
of the path, and the cwrapper will have the "wrong" path settings.

As it does today.

Obviously, in a follow-on documentation patch this misfeature -- which
in the words of Rex from Toy Story is "not our fault" -- must be
explained.

However, with this framework, once wine is able to deal with cygwin-1.7,
then libtool will be ready for it, and the wrappers will be runnable
under wine.

In the meantime, this refactoring also improves cross behavior for other
common use cases, expecially cygwin->mingw and "native" mingw (e.g.
msys->mingw), has the other benefits described above, and will enable
some of Peter's blocked MSVC changes.

As obvious from the table below, I still need to do some more testing
to (a) verify that the errors reported below are not regressions, and
(b) investigate some of the anomalous behaviors.  However, that should
not impact an on-going review of the code IN the patch.


Test results

cygwin-native
=============
cygwin-native (old tests): 122 PASS, 2 SKIP
cygwin-native (new tests): 111 as expected, 6 skip

mingw-native (e.g. msys->mingw)
============
mingw-native (old tests): 2 FAIL, 120 PASS, 2 SKIP
  mdemo-exec.test (after mdemo-conf)
  mdemo2-exec.text
  I don't believe these are related to this patch, because they
  have been around a long time. I do NOT see these failures in the
  cygwin->mingw configuration (where the -exec test is, correctly,
  skipped), nor in the linux->mingw cross configurations (where these
  two -exec tests are NOT skipped (!!) but do pass [I have binfmt
  enabled]).
mingw-native (new tests): 1 unexpected failure, 8 skip
  - known issue: "Run tests with low max_cmd_len"
    ar with long command line fails, because
    it should convert paths (using this framework)
    but doesn't. This should be deferred as a
    separate patch, once this patch is merged.

linux-native
============
linux-native (old tests): All 106 tests passed
linux-native (new tests): 102 as expected, 15 skip
I don't have java installed...


cygwin->mingw cross (a true cross compiler)
===================
cygwin->mingw (old tests): All 107 tests passed
cygwin->mingw (new tests): 99 as expected, 18 skip
   Spot check verifies that the cwrapper source code has
   the correct path(s).

cygwin->mingw cross (faked)
===================
This is where you do:
   $ export PATH="/c/MinGW/bin:${PATH}"
   $ configure --build=i686-pc-cygwin --host=mingw32 \
        NM=/c/MinGW/bin/nm.exe
That is, you use cygwin as $build, but use the native MinGW
compiler (instead of a cygwin-hosted cross compiler).

I haven't tested this yet (I forgot about it) but I really should.
It is a common use case.

cygwin->mingw cross (lie)
===================
This is where you do
   $ configure --build=i686-pc-mingw32 --host=i686-pc-mingw32 \
        --target=i686-pc-mingw32
even though you are actually running under *cygwin* and not
mingw (e.g. msys in it's normal "pretend I'm mingw" personality).
See:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00193.html

To make this work, with this patch and when you lie to your build
system this way, you'll have to do the following:

cygwin$ export lt_cv_to_host_path_cmd=func_cygwin_to_mingw_path_convert
cygwin$ path/to/configure \
      --build=i686-pc-mingw32 \
      --host=i686-pc-mingw32 \
      --target=i686-pc-mingw32 \
      --disable-dependency-tracking

because if you don't, libtool will (mistakenly) use the
func_msys_to_mingw_path_convert function, since you did tell it that
$build was mingw (e.g. msys in it's pretend I'm mingw" personality).
disable-dependency-tracking is necessary because otherwise MinGW gcc
will put pure win32 (C:/foo) paths into the .deps/*.P files, and
cygwin make will be quite confused.

I haven't tested this recently, but I need to. I just forgot.

linux->mingw cross
==================
linux->mingw (old tests): 2 of 100 FAIL, 6 SKIP
  FAIL: tests/demo-hardcode.test
  FAIL: tests/depdemo-relink.test
  Don't know if these are regressions or not; will recheck without
  this patch.
linux->mingw (new tests): 89 as expected, 28 skip
   Spot check verifies that the cwrapper source code has
   the correct path(s).

linux->cygwin cross (LT_CYGPATH not set)
===================
linux->cygwin (old tests): 1 of 114 FAIL, 10 SKIP
  FAIL: tests/demo-hardcode.test
  Ditto: don't know if this is a regression or not; will recheck
  without this patch.
linux->cygwin (new tests): AWFUL.
                           23 unexpected failures
                           32 skip
I don't expect any difference WITH LT_CYGPATH set, because
cygpath-1.7 (and, indeed, all cygwin-1.7 programs) seems to crash under
wine anyway. I need to investigate this and re-run in this configuration
without this patch, to verify that these failures are not regressions.
I don't *think* the changes in this patch could have caused them...

msys native
===========
msys-native (old tests): 8 of 109 FAIL, 15 SKIP
msys-native (new tests): 11 unexected failures, 18 skip
  This appears to be a "regression" from the libtool currently
  distributed by msys -- but THAT version ALSO includes this patch
  (against an earlier snapshot of libtool: 2.2.7a).  So, these
  regressions are probably caused by some OTHER change in libtool,
  and not this patch. Besides, msys is not an officially supported
  platform anyway (it can't be; config.status doesn't support it, and
  by request of the MinGW/MSYS people it WILL not); I'm just doing
  this one for my benefit. Something for me to investigate later,
  but shouldn't impact evaluation of this patch: I verified that

checking how to convert i686-pc-msys paths to i686-pc-msys 
format...func_noop_path_convert

  which is correct for msys-native; it basically means that all this
  machinery is a no-op -- as it should be. So whatever is failing on
  msys, it is unlikely to be related to this patch.

Congratulations, you have reached the end of this message, and can
now review the 750 line patch!
--
Chuck

 
 Makefile.am                |    3 +-
 libltdl/config/ltmain.m4sh |  687 +++++++++++++++++++++++++++++++++++---------
 libltdl/m4/libtool.m4      |   53 ++++
 tests/testsuite.at         |    5 +-
 4 files changed, 617 insertions(+), 131 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 2c4a3db..251dc19 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -528,7 +528,8 @@ TESTS_ENVIRONMENT = MAKE="$(MAKE)" CC="$(CC)" 
CFLAGS="$(CFLAGS)" \
        CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" CXXCPP="$(CXXCPP)" \
        F77="$(F77)" FFLAGS="$(FFLAGS)" \
        FC="$(FC)" FCFLAGS="$(FCFLAGS)" \
-       GCJ="$(GCJ)" GCJFLAGS="$(GCJFLAGS)"
+       GCJ="$(GCJ)" GCJFLAGS="$(GCJFLAGS)" \
+       lt_cv_to_host_path_cmd="$(to_host_path_cmd)"
 
 BUILDCHECK_ENVIRONMENT = _lt_pkgdatadir="$(abs_top_srcdir)" \
        LIBTOOLIZE="$(abs_top_builddir)/libtoolize" \
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index c6671a0..72927ba 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2775,166 +2775,595 @@ fi\
 "
 }
 
+####################################
+# PATH CONVERSION HELPER FUNCTIONS #
+####################################
+
+# func_wine_to_win32_path ARG
+# Helper function used by path conversion functions
+# when $build is *nix, and $host is mingw, cygwin,
+# or some other win32 environment. Relies on a
+# correctly configured wine environment available,
+# with the winepath program in $build's $PATH.
+#
+# ARG is the $build path to be converted to win32 format.
+# result is available in $func_wine_to_win32_path_result
+# result is empty on error (or when arg is empty)
+func_wine_to_win32_path ()
+{
+  $opt_debug
+  lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+  func_wine_to_win32_path_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero
+    # error code, so we are forced to check the contents of
+    # stdout. On the other hand, if the command is not
+    # found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both
+    # error code of zero AND non-empty stdout, which explains
+    # the odd construction:
+    func_wine_to_win32_path_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_wine_to_win32_path_tmp}"; then
+      func_wine_to_win32_path_result=`$ECHO "$func_wine_to_win32_path_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_wine_to_win32_path_result=
+    fi
+  fi
+}
+# end: func_wine_to_win32_path
+
+
+# func_wine_to_win32_pathlist ARG
+# Helper function used by path conversion functions
+# when $build is *nix, and $host is mingw, cygwin,
+# or some other win32 environment. Relies on a
+# correctly configured wine environment available,
+# with the winepath program in $build's $PATH.
+# Assumes ARG has no leading or trailing path separator
+# characters.
+#
+# ARG is pathlist to be converted from $build format to win32.
+# Result is available in $func_wine_to_win32_pathlist_result
+# Unconvertible paths in pathlist are skipped; if no paths
+# are convertible, result may be empty.
+func_wine_to_win32_pathlist ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert pathlists
+  func_wine_to_win32_pathlist_result=""
+  if test -n "$1"; then
+    func_wine_to_win32_pathlist_oldIFS=$IFS
+    IFS=:
+    for func_wine_to_win32_pathlist_f in $1; do
+      IFS=$func_wine_to_win32_pathlist_oldIFS
+      if test -n "$func_wine_to_win32_pathlist_f" ; then
+        func_wine_to_win32_path "$func_wine_to_win32_pathlist_f"
+        if test -n "$func_wine_to_win32_path_result" ; then
+          if test -z "$func_wine_to_win32_pathlist_result"; then
+            
func_wine_to_win32_pathlist_result="$func_wine_to_win32_path_result"
+          else
+            func_append func_wine_to_win32_pathlist_result 
";$func_wine_to_win32_path_result"
+          fi
+        fi
+      fi
+    done
+    IFS=$func_wine_to_win32_pathlist_oldIFS
+  fi
+}
+# end: func_wine_to_win32_pathlist
+
+
+# func_cygpath ARGS...
+# a wrapper around calling the cygpath program via
+# LT_CYGPATH, when $host is *nix and cygwin is
+# hosted via a wine environment (or, rarely, when
+# host is mingw -- that is, msys).
+#
+# Result is available in func_cygpath_result, which
+# may be empty on error. Can accomodate both paths
+# and pathlists (with appropriate options).
+#
+# ARGS are the typical arguments and options for
+# the cygpath program. Usually, the last argument
+# is the path or pathlist to be converted.
+#
+# The full *nix (or msys) path to the cygpath program must be
+# specified in the LT_CYGPATH environment variable. This
+# is because (a) the cygpath program shouldn't be in $PATH,
+# because it usually lives in cygwin's bin/ directory --
+# along with *cygwin* versions of sed, id, cp. If the *nix (or
+# msys) host environment had those programs in its $PATH, many
+# bad things could happen. (b) especially in cygwin-1.7, multiple
+# installations (with separate "mount tables" in
+# <CYGROOT-N>/etc/fstab) can coexist on the same Win32
+# instance. The cygpath.exe for cygwin installation #N in
+# <CYGROOT-N>/bin automatically deduces the appropriate
+# ../etc/fstab file. Therefore, it matters which cygpath.exe
+# is used. LT_CYGPATH may be replaced or supplemented by an
+# LT_INIT-activated configure option in the future.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existant file: 
\`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_msys_to_win32 ARG
+# Converts ARG from msys (unix-ish) format to
+# win32 format. Can accomodate both paths and pathlists.
+# Result is available in func_msys_to_win32_result.
+func_msys_to_win32 ()
+{
+  $opt_debug
+  lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+  # awkward: cmd appends spaces to result
+  func_msys_to_win32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_msys_to_win32
+
+
+# func_path_convert_check ARG1 ARG2
+# Verify that ARG1 (a path in $build format) was
+# converted to $host format in ARG2. Otherwise, emit
+# an error message, but continue (resetting
+# func_to_host_path_result to ARG1).
+func_path_convert_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host path corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_path_result="$1"
+  fi
+}
+# end func_path_convert_check
+
+
+# func_pathlist_convert_check FROM_PATHSEP TO_PATHSEP FROM_PATHLIST TO_PATHLIST
+# Verify that FROM_PATHLIST (a path in $build format) was converted
+# $host format in TO_PATHLIST. Otherwise, emit an error message, but
+# continue, resetting func_to_host_path_result to a simplistic
+# fallback value (see below).
+func_pathlist_convert_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path(s) corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback. If even this fallback fails, the fix is not to
+    # complicate the expression below, but for the user to provide,
+    # in that situation, whatever elements are missing from the
+    # environment so that the actual pathlist conversion functions
+    # work properly (for instance, a working wine installation
+    # with winepath so that path translation in the cross-to-mingw
+    # case works).
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_pathlist_result=`echo "$3" |\
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_pathlist_result="$3"
+    fi
+  fi
+}
+# end func_pathlist_convert_check
+
+
+# func_pathlist_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_pathlist_result by prepending REPL
+# if ORIG matches FRONTPAT and appending REPL if ORIG matches
+# BACKPAT.
+func_pathlist_front_back_pathsep ()
+{
+  $opt_debug
+  case "$4" in
+  $1 ) func_to_host_pathlist_result="$3$func_to_host_pathlist_result"
+    ;;
+  esac
+  case "$4" in
+  $2 ) func_append func_to_host_pathlist_result "$3"
+    ;;
+  esac
+}
+# end func_pathlist_front_back_pathsep
 
-# func_to_host_path arg
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `eval $to_host_path_cmd ARG'
 #
-# Convert paths to host format when used with build tools.
-# Intended for use with "native" mingw (where libtool itself
-# is running under the msys shell), or in the following cross-
-# build environments:
+# At present, the following path conversions are supported:
 #    $build          $host
 #    mingw (msys)    mingw  [e.g. native]
 #    cygwin          mingw
 #    *nix + wine     mingw
+#    mingw (msys)    cygwin [*] [**]
+#    *nix + wine     cygwin [**]
 # where wine is equipped with the `winepath' executable.
-# In the native mingw case, the (msys) shell automatically
-# converts paths for any non-msys applications it launches,
-# but that facility isn't available from inside the cwrapper.
-# Similar accommodations are necessary for $host mingw and
-# $build cygwin.  Calling this function does no harm for other
-# $host/$build combinations not listed above.
-#
-# 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.
+# [*] available, but not officially supported. See comments with
+#     func_msys_to_cygwin_path_convert.
+# [**] requires environment variable $LT_CYGPATH. See comments
+#      with func_cygpath.
+# In each case, ARG is the path to be converted from $build
+# to $host format. the result will be available in
+# $func_to_host_path_result.
+
+
+# func_to_host_path ARG
+# converts the path ARG from $build format to $host
+# format.
 func_to_host_path ()
 {
+  $opt_debug
+  eval '$to_host_path_cmd "$1"'
+}
+# end func_to_host_path
+
+
+# func_noop_path_convert ARG
+# A no-op path conversion function for use when $build == $host.
+# or when there is no required (or known) conversion function
+# between $build and $host.
+func_noop_path_convert ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+}
+# end func_noop_path_convert
+
+
+# func_msys_to_mingw_path_convert ARG
+# A path conversion function for use with "native" mingw
+# builds -- that is, when $host is *mingw*, and $build
+# is *mingw* (which is to say, msys).  In this case, the
+# msys shell automatically converts paths for any non-msys
+# applications it launches, but that facility isn't available
+# from inside the cwrapper.
+#
+# ARG is the path to be converted; the result is available
+# in func_to_host_path_result.
+func_msys_to_mingw_path_convert ()
+{
+  $opt_debug
   func_to_host_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
-            func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null |
-              $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
-            ;;
-          *cygwin* )
-            func_to_host_path_result=`cygpath -w "$1" |
-             $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          * )
-            # Unfortunately, winepath does not exit with a non-zero
-            # error code, so we are forced to check the contents of
-            # stdout. On the other hand, if the command is not
-            # found, the shell will set an exit code of 127 and print
-            # *an error message* to stdout. So we must check for both
-            # error code of zero AND non-empty stdout, which explains
-            # the odd construction:
-            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
-            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
-              func_to_host_path_result=`$ECHO "$func_to_host_path_tmp1" |
-                $SED -e "$lt_sed_naive_backslashify"`
-            else
-              # Allow warning below.
-              func_to_host_path_result=
-            fi
-            ;;
-        esac
-        if test -z "$func_to_host_path_result" ; then
-          func_error "Could not determine host path corresponding to"
-          func_error "  \`$1'"
-          func_error "Continuing, but uninstalled executables may not work."
-          # Fallback:
-          func_to_host_path_result="$1"
-        fi
-        ;;
-    esac
+    func_msys_to_win32 "$1"
+    func_to_host_path_result="$func_msys_to_win32_result"
   fi
+  func_path_convert_check "$1" "$func_to_host_path_result"
 }
-# end: func_to_host_path
+# end func_msys_to_mingw_path_convert
 
-# func_to_host_pathlist arg
+
+# func_cygwin_to_mingw_path_convert ARG
+# A path conversion function for use when $host is *mingw*
+# but $build is *cygwin*. In this case, the cygpath program
+# provided by the $build environment is sufficient for all
+# conversions.
 #
-# Convert pathlists to host format when used with build tools.
-# See func_to_host_path(), above. This function supports the
-# following $build/$host combinations (but does no harm for
-# combinations not listed here):
+# ARG is the path to be converted; the result is available
+# in func_to_host_path_result.
+func_cygwin_to_mingw_path_convert ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath
+    # in $PATH; no need to use LT_CYGPATH in this case.
+    func_to_host_path_result=`cygpath -m "$1"`
+  fi
+  func_path_convert_check "$1" "$func_to_host_path_result"
+}
+# end func_cygwin_to_mingw_path_convert
+
+
+# func_nix_to_mingw_path_convert ARG
+# A path conversion function for use when $host is *mingw*
+# but $build is some *nix variant. In this case, we assume
+# that a wine environment with a working winepath executable
+# is available in $build's $PATH.
+#
+# ARG is the path to be converted; the result is available
+# in func_to_host_path_result.
+func_nix_to_mingw_path_convert ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    func_wine_to_win32_path "$1"
+    func_to_host_path_result="$func_wine_to_win32_path_result"
+  fi
+  func_path_convert_check "$1" "$func_to_host_path_result"
+}
+# end func_nix_to_mingw_path_convert
+
+
+# func_msys_to_cygwin_path_convert ARG
+# A path conversion function for use when $host is *cygwin*
+# but $build is *mingw* (that is, msys). This implies running
+# a cross build from msys to cygwin -- but msys has notorious
+# problems executing cygwin apps, because of conflicts between
+# cygwin1.dll and msys-1.0.dll. However, we'll try it. First,
+# convert from msys to win32, then use func_cygpath to convert
+# from win32 to cygwin. Requires LT_CYGPATH.
+#
+# ARG is the path to be converted; the result is available
+# in func_to_host_path_result.
+func_msys_to_cygwin_path_convert ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    func_msys_to_win32 "$1"
+    func_cygpath -u "$func_msys_to_win32_result"
+    func_to_host_path_result="$func_cygpath_result"
+  fi
+  func_path_convert_check "$1" "$func_to_host_path_result"
+}
+# end func_msys_to_cygwin_path_convert
+
+# func_nix_to_cygwin_path_convert ARG
+# A path conversion function for use when $host is *cygwin*
+# but $build is some *nix variant. In this case, we assume
+# that a wine environment with a working winepath executable
+# is available in $build's $PATH, and that cygwin is installed
+# within that wine environment. Requires LT_CYGPATH (see
+# func_cygpath).
+#
+# ARG is the path to be converted; the result is available
+# in func_to_host_path_result.
+func_nix_to_cygwin_path_convert ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to win32, then use cygpath to
+    # convert from win32 to cygwin.
+    func_wine_to_win32_path "$1"
+    func_cygpath -u "$func_wine_to_win32_path_result"
+    func_to_host_path_result="$func_cygpath_result"
+  fi
+  func_path_convert_check "$1" "$func_to_host_path_result"
+}
+# end func_nix_to_cygwin_path_convert
+
+
+#################################################
+# $build to $host PATHLIST CONVERSION FUNCTIONS #
+#################################################
+# invoked via `eval $to_host_pathlist_cmd ARG'
+#
+# At present, the following pathlist conversions are supported:
 #    $build          $host
 #    mingw (msys)    mingw  [e.g. native]
 #    cygwin          mingw
 #    *nix + wine     mingw
+#    mingw (msys)    cygwin [*] [**]
+#    *nix + wine     cygwin [**]
+# where wine is equipped with the `winepath' executable.
+# [*] available, but not officially supported. See comments with
+#     func_msys_to_cygwin_pathlist_convert.
+# [**] requires environment variable $LT_CYGPATH. See comments
+#      with func_cygpath.
+# In each case, ARG is the pathlist to be converted from
+# $build to $host format. the result will be available in
+# $func_to_host_pathlist_result.
 #
 # Path separators are also converted from $build format to
 # $host format. If ARG begins or ends with a path separator
 # character, it is preserved (but converted to $host format)
 # on output.
+
+
+# func_init_to_host_pathlist_cmd
+# Ensures that function "pointer" variable
+# $to_host_pathlist_cmd is set to the appropriate
+# value, based on the value of $to_host_path_cmd.
 #
-# 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.
+# ASSUMPTIONS: all such conversion functions are
+# named using the following convention:
+#   path conversion function    : xxxxxx_path_convert ()
+#   pathlist conversion function: xxxxxx_pathlist_convert ()
+# where, for any given $build/$host combination the 'xxxxxx'
+# value is the same.
+to_host_pathlist_cmd=
+func_init_to_host_pathlist_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_pathlist_cmd"; then
+    func_stripname '' '_path_convert' "$to_host_path_cmd"
+    to_host_pathlist_cmd="${func_stripname_result}_pathlist_convert"
+  fi
+}
+
+
+# func_to_host_pathlist ARG
+# converts the pathlist ARG from $build format to $host
+# format.
 func_to_host_pathlist ()
 {
+  $opt_debug
+  func_init_to_host_pathlist_cmd
+  eval '$to_host_pathlist_cmd "$1"'
+}
+# end func_to_host_pathlist
+
+
+# func_noop_pathlist_convert ARG
+# A no-op pathlist conversion function for use when $build == $host,
+# or when there is no required (or known) conversion function
+# between $build and $host.
+func_noop_pathlist_convert ()
+{
+  $opt_debug
+  func_to_host_pathlist_result="$1"
+}
+# end func_noop_pathlist_convert
+
+
+# func_msys_to_mingw_pathlist_convert ARG
+# A pathlist conversion function for use with "native" mingw
+# builds -- that is, when $host is *mingw*, and $build
+# is *mingw* (which is to say, msys).  In this case, the
+# msys shell automatically converts pathlists for any non-msys
+# applications it launches, but that facility isn't available
+# from inside the cwrapper.
+#
+# ARG is the pathlist to be converted; the result is available
+# in func_to_host_pathlist_result.
+func_msys_to_mingw_pathlist_convert ()
+{
+  $opt_debug
   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'
-        # Remove leading and trailing path separator characters from
-        # ARG. msys behavior is inconsistent here, cygpath turns them
-        # into '.;' and ';.', and winepath ignores them completely.
-       func_stripname : : "$1"
-        func_to_host_pathlist_tmp1=$func_stripname_result
-        case $build in
-          *mingw* ) # Actually, msys.
-            # Awkward: cmd appends spaces to result.
-            func_to_host_pathlist_result=`
-             ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null |
-             $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
-            ;;
-          *cygwin* )
-            func_to_host_pathlist_result=`cygpath -w -p 
"$func_to_host_pathlist_tmp1" |
-              $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          * )
-            # unfortunately, winepath doesn't convert pathlists
-            func_to_host_pathlist_result=""
-            func_to_host_pathlist_oldIFS=$IFS
-            IFS=:
-            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
-              IFS=$func_to_host_pathlist_oldIFS
-              if test -n "$func_to_host_pathlist_f" ; then
-                func_to_host_path "$func_to_host_pathlist_f"
-                if test -n "$func_to_host_path_result" ; then
-                  if test -z "$func_to_host_pathlist_result" ; then
-                    func_to_host_pathlist_result="$func_to_host_path_result"
-                  else
-                    func_append func_to_host_pathlist_result 
";$func_to_host_path_result"
-                  fi
-                fi
-              fi
-            done
-            IFS=$func_to_host_pathlist_oldIFS
-            ;;
-        esac
-        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 "Continuing, but uninstalled executables may not work."
-          # Fallback. This may break if $1 contains DOS-style drive
-          # specifications. The fix is not to complicate the expression
-          # below, but for the user to provide a working wine installation
-          # with winepath so that path translation in the cross-to-mingw
-          # case works properly.
-          lt_replace_pathsep_nix_to_dos="s|:|;|g"
-          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
-            $SED -e "$lt_replace_pathsep_nix_to_dos"`
-        fi
-        # Now, add the leading and trailing path separators back
-        case "$1" in
-          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
-            ;;
-        esac
-        case "$1" in
-          *: ) func_append func_to_host_pathlist_result ";"
-            ;;
-        esac
-        ;;
-    esac
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_pathlist_tmp1=$func_stripname_result
+    func_msys_to_win32 "$func_to_host_pathlist_tmp1"
+    func_to_host_pathlist_result="$func_msys_to_win32_result"
+    func_pathlist_convert_check ":" ";" \
+      "$func_to_host_pathlist_tmp1" "$func_to_host_pathlist_result"
+    func_pathlist_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_msys_to_mingw_pathlist_convert
+
+
+# func_cygwin_to_mingw_pathlist_convert ARG
+# A pathlist conversion function for use when $host is *mingw*
+# but $build is *cygwin*. In this case, the cygpath program
+# provided by the $build environment is sufficient for all
+# conversions.
+#
+# ARG is the pathlist to be converted; the result is available
+# in func_to_host_pathlist_result.
+func_cygwin_to_mingw_pathlist_convert ()
+{
+  $opt_debug
+  func_to_host_pathlist_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_pathlist_tmp1=$func_stripname_result
+    func_to_host_pathlist_result=`cygpath -m -p "$func_to_host_pathlist_tmp1"`
+    func_pathlist_convert_check ":" ";" \
+      "$func_to_host_pathlist_tmp1" "$func_to_host_pathlist_result"
+    func_pathlist_front_back_pathsep ":*" "*:" ";" "$1"
   fi
 }
-# end: func_to_host_pathlist
+# end func_cygwin_to_mingw_pathlist_convert
+
+
+# func_nix_to_mingw_pathlist_convert ARG
+# A pathlist conversion function for use when $host is *mingw*
+# but $build is some *nix variant. In this case, we assume
+# that a wine environment with a working winepath executable
+# is available in $build's $PATH.
+#
+# ARG is the pathlist to be converted; the result is available
+# in func_to_host_pathlist_result.
+func_nix_to_mingw_pathlist_convert ()
+{
+  $opt_debug
+  func_to_host_pathlist_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_pathlist_tmp1=$func_stripname_result
+    func_wine_to_win32_pathlist "$func_to_host_pathlist_tmp1"
+    func_to_host_pathlist_result="$func_wine_to_win32_pathlist_result"
+    func_pathlist_convert_check ":" ";" \
+      "$func_to_host_pathlist_tmp1" "$func_to_host_pathlist_result"
+    func_pathlist_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_nix_to_mingw_pathlist_convert
+
+
+# func_msys_to_cygwin_pathlist_convert ARG
+# A pathlist conversion function for use when $host is *cygwin*
+# but $build is *mingw* (that is, msys). This implies running
+# a cross build from msys to cygwin -- but msys has notorious
+# problems executing cygwin apps, because of conflicts between
+# cygwin1.dll and msys-1.0.dll. However, we'll try it. First,
+# convert from msys to win32, then use func_cygpath to convert
+# from win32 to cygwin. Requires LT_CYGPATH.
+#
+# ARG is the pathlist to be converted; the result is available
+# in func_to_host_pathlist_result.
+func_msys_to_cygwin_pathlist_convert ()
+{
+  $opt_debug
+  func_to_host_pathlist_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_pathlist_tmp1=$func_stripname_result
+    func_msys_to_win32 "$func_to_host_pathlist_tmp1"
+    func_cygpath -u -p "$func_msys_to_win32_result"
+    func_to_host_pathlist_result="$func_cygpath_result"
+    func_pathlist_convert_check ":" ":" \
+      "$func_to_host_pathlist_tmp1" "$func_to_host_pathlist_result"
+    func_pathlist_front_back_pathsep ":*" "*:" ":" "$1"
+  fi
+}
+# end func_msys_to_cygwin_pathlist_convert
+
+
+# func_nix_to_cygwin_pathlist_convert ARG
+# A pathlist conversion function for use when $host is *cygwin*
+# but $build is some *nix variant. In this case, we assume
+# that a wine environment with a working winepath executable
+# is available in $build's $PATH, and that cygwin is installed
+# within that wine environment. Requires LT_CYGPATH (see
+# func_cygpath).
+#
+# ARG is the pathlist to be converted; the result is available
+# in func_to_host_pathlist_result.
+func_nix_to_cygwin_pathlist_convert ()
+{
+  $opt_debug
+  func_to_host_pathlist_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_pathlist_tmp1=$func_stripname_result
+    func_wine_to_win32_pathlist "$func_to_host_pathlist_tmp1"
+    func_cygpath -u -p "$func_wine_to_win32_pathlist_result"
+    func_to_host_pathlist_result="$func_cygpath_result"
+    func_pathlist_convert_check ":" ":" \
+      "$func_to_host_pathlist_tmp1" "$func_to_host_pathlist_result"
+    func_pathlist_front_back_pathsep ":*" "*:" ":" "$1"
+  fi
+}
+# end func_nix_to_cygwin_pathlist_convert
+
 
 # func_emit_cwrapperexe_src
 # emit the source code for a wrapper executable on stdout
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 891a9f8..d7bd57d 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -168,6 +168,7 @@ _LT_DECL([], [exeext], [0], [Executable file suffix 
(normally "")])dnl
 dnl
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
 m4_require([_LT_CMD_RELOAD])dnl
 m4_require([_LT_CHECK_MAGIC_METHOD])dnl
 m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
@@ -7576,3 +7577,55 @@ if test x"$_lt_function_replace_fail" = x":"; then
   AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
 fi
 ])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which path conversion functions should be
+# used by func_to_host_path (and, implicitly, by
+# func_to_host_pathlist).  These are needed for certain
+# cross-compile configurations and "native" mingw (which
+# is actually an msys->mingw cross).
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build paths to $host format])
+AC_CACHE_VAL(lt_cv_to_host_path_cmd,
+[case $host in
+  *mingw* )
+    case $build in
+      *mingw* ) # actually msys
+        lt_cv_to_host_path_cmd=func_msys_to_mingw_path_convert
+        ;;
+      *cygwin* )
+        lt_cv_to_host_path_cmd=func_cygwin_to_mingw_path_convert
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_path_cmd=func_nix_to_mingw_path_convert
+        ;;
+    esac
+    ;;
+  *cygwin* )
+    case $build in
+      *mingw* ) # actually msys
+        lt_cv_to_host_path_cmd=func_msys_to_cygwin_path_convert
+        ;;
+      *cygwin* )
+        lt_cv_to_host_path_cmd=func_noop_path_convert
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_path_cmd=func_nix_to_cygwin_path_convert
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_path_cmd=func_noop_path_convert
+    ;;
+esac
+])
+to_host_path_cmd=$lt_cv_to_host_path_cmd
+AC_MSG_RESULT([$lt_cv_to_host_path_cmd])
+_LT_DECL([to_host_path_cmd], [lt_cv_to_host_path_cmd],
+         [0], [convert $build paths to $host format])dnl
+AC_SUBST([to_host_path_cmd])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
+
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 35b920b..3475fa1 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -37,7 +37,7 @@ for tool in ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE AUTORECONF; 
do
 done
 export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE AUTORECONF
 eval `$LIBTOOL --config | grep '^EGREP='`
-eval `$LIBTOOL --config | $EGREP 
'^(host|host_os|host_alias|build|build_alias)='`
+eval `$LIBTOOL --config | $EGREP 
'^(host|host_os|host_alias|build|build_alias|to_host_path_cmd)='`
 configure_options=--prefix=/nonexistent
 if test -n "$host_alias"; then
   configure_options="$configure_options --host $host_alias"
@@ -45,6 +45,9 @@ fi
 if test -n "$build_alias"; then
   configure_options="$configure_options --build $build_alias"
 fi
+if test -n "$to_host_path_cmd"; then
+  configure_options="$configure_options 
lt_cv_to_host_path_cmd=$to_host_path_cmd"
+fi
 if (FOO=bar; unset FOO) >/dev/null 2>&1; then
   unset=unset
 else
-- 
1.7.1




reply via email to

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