[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] [cygwin]: Add cross-compile support to cwrapper take 5
From: |
Charles Wilson |
Subject: |
[PATCH] [cygwin]: Add cross-compile support to cwrapper take 5 |
Date: |
Fri, 19 Jun 2009 13:53:22 -0400 |
* libltdl/config/general.m4sh: Update copyright year.
(func_tr_sh): New function.
* libltdl/config/ltmain.m4sh (func_generate_dlsyms) [cygwin|mingw]:
Obtain DLL name corresponding to import library by using value
stored in unique variable libfile_$(transliterated implib name).
If that fails, use $sharedlib_from_linklib_cmd to extract DLL
name from import library directly. Also, properly extract dlsyms
from the import library.
(func_mode_link) [cygwin|mingw]: Prefer to dlpreopen DLLs
over static libs when both are available. When dlpreopening
DLLs, use linklib (that is, import lib) as dlpreopen file,
rather than DLL. Store name of associated la file in
unique variable libfile_$(transliterated implib name)
for later use.
(func_win32_libid): Accomodate pei-i386 import libs
as well as pe-i386.
(func_cygming_dll_for_implib): New function.
(func_cygming_dll_for_implib_fallback): New function.
(func_cygming_dll_for_implib_fallback_core): New function.
(func_cygming_gnu_implib_p): New function.
(func_cygming_ms_implib_p): New function.
* libltdl/m4/libtool.m4 (_LT_CMD_GLOBAL_SYMBOLS): Adjust sed
expressions for lt_cv_sys_global_symbol_to_c_name_address and
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
as trailing space after module name is optional.
(_LT_LINKER_SHLIBS) [cygwin|mingw][C++]:
Set exclude_expsyms correctly for $host. Simplify regular
expression in export_symbols_cmds.
(_LT_LINKER_SHLIBS) [cygwin|mingw|pw32][C]: Set exclude_expsyms
correctly for $host. Enable export_symbols_cmds to identify
DATA exports by _nm_ prefix.
(_LT_CHECK_SHAREDLIB_FROM_LINKLIB): New macro sets
sharedlib_from_linklib_cmd variable.
(_LT_DECL_DLLTOOL): New macro ensures DLLTOOL is always set.
--
This is a repost of the "take 4" patch originally posted here:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00232.html
This patch has been in use in the cygwin distribution since 2009-02-20.
I've rewritten the original "patch notes" from -take1...-take4, so that
a more coherent story can be told, for folks just joining this thread or
who have forgotten all the surrounding context...
Another good summary (if I do say so myself) of the problem, and history,
that the attached patch addresses can be found here:
[CFT] libtool on nix->cygwin cross, with wine
http://www.cygwin.com/ml/cygwin/2009-02/msg00555.html
(Ignore the rest of the thread; there was not a single on-topic reply.)
Definition: "works", or "for the cwrapper to work properly" in this
context means that you can, from the $build environment, execute the
cwrapper program, and eventually the actual target executable will be
successfully launched. In all known cases involving the cwrapper (e.g
$host is win32-related -- except maybe cegcc but that's another issue),
*compiling* in a cross environment with those $hosts always works just
fine. It's launching the uninstalled target executables that is at issue
throughout this post.
Unix -> mingw cross builds need special support when creating the
cwrapper source code in order for the cwrapper to work properly
under the wine environment. This was originally described here:
http://lists.gnu.org/archive/html/libtool-patches/2008-04/msg00164.html
(that patch is already part of libtool, in a modified form).
However, the full explanation is:
1) On win32 $host we need an executable wrapper, rather than the normal
shell script wrapper, for dynamically linked executables. This is
because the automake rules' target is foo$(EXEEXT).
a) it is a bad idea to lie to win32 OS by naming a file that is NOT
a PE/COFF executable "foo.exe" so we can't just rename foo (the
shell script) as foo.exe. So, because we need to support native
builds on cygwin, mingw, and friends, we have to care about this
case, and not simply emit the shell wrapper as foo$(EXEEXT).
2) We have long had this cwrapper. It used to coexist in the same
directory with the shell script wrapper. The cwrapper would
exec the shell wrapper, which did all the work, and then launched
the actual target.
a) This doesn't work for cygwin-1.5 where CYGWIN variable contains
the flag "transparent_exe". Since "transparent_exe" is now the
default behavior for cygwin-1.7 (due to be released within 2 wks)
this foo + foo.exe in same directory will very shortly be broken.
b) So, a year or so ago, the cwrapper was modified to do all the
work itself (setting PATH/LD_LIBRARY_PATH, etc), and to directly
invoke the target. Similarly, libtool no longer creates the shell
wrapper with the target's name (there is still a shell wrapper on
these $hosts, but it goes in .libs/ and is named ltshwrapper_foo.
This was the original goal, anyway, because it's just kinda silly
to have two levels of wrappers to get to the target exe.
c) One wrinkle: the cwrapper is a $host executable, not a $build one.
So, for instance when $host=$mingw, the path-to-real-target must
be translated to C:/dos/path form, from libtool's normal unixish
version. libtool is a shell script, running under some sort of
unix emulation: a different $build like linux or cygwin, or the
bizarro-world of MSYS, where "$host" claims to be mingw, but where
very odd behind-the-scenes path translation logic makes things
really complicated.
d) So, the original patch
http://lists.gnu.org/archive/html/libtool-patches/2008-04/msg00164.html
included func_to_native_path() which did an evil dance of death
to ensure The Right Thing happened. This was eventually accepted
into libtool in modified form.
3) However, even that caused some problems, as it broke cross compile
behavior for unix->mingw, when previously a WINE installation on unix
allowed the target exes to be run in-place using the shell wrapper.
http://lists.gnu.org/archive/html/libtool-patches/2008-05/msg00034.html
So, after #2, libtool-master had a regression over libtool-1.5.x;
in the past, using a unix $build with WINE, one could use a mingw
cross toolchain to build win32 applications, AND run the uninstalled
executables including test suites. After #2, this was broken because
the exe wrapper (a $host, that is, win32 program) has the $build path,
"/z/my/src/dir/.libs/target.exe" hardcoded into it in unix format.
Obviously, unless you use certain tricks [*], the win32 _spawn() function
has no idea what that path means. Ditto the fact that the exe wrapper
has, hardcoded, certain $PATH settings;
/z/my/src/dir/dlls/.lib:${ORIGPATH}
Again, the path is wrong -- but also, the string uses ':' as a path
separator instead of ';'.
[*] require so-called "identity mounts" in your WINE setup, and
manually change the ':' to ';', etc.
Now, none of this was a problem when $build was mingw (e.g "MSYS")
because of the games played by the first patch in this series (up in
bullet point #2, above).
To fix this case, the patch here:
http://lists.gnu.org/archive/html/libtool-patches/2008-05/msg00044.html
added special cases for $host = mingw, $build = <not cygwin, not
msys/mingw>.
For our purposes here, this summary brings us to the present day. In the
past, libtool-1.5.x allowed cross builds (with $build = unix, $host = cygwin)
to work as long as WINE was installed -- but for reasons similar to those above,
they no longer do. Current status vis-a-vis using libtool to build applications
in a win32 cross environments:
$host $build
===================================
mingw mingw (MSYS) OK
mingw cygwin OK [**]
mingw unix OK [***]
cygwin cygwin OK
cygwin unix X [****]
(preliminary reports also indicate that $host=msvc, $build=msys/mingw works,
too,
assuming certain other patches to libtool are included).
[**] OK, we need more discussion of this point. In the olden days, the
following worked:
a) you lie to configure and tell it --host=mingw --build=mingw
even though $build is ACTUALLY cygwin
b) you have set up your cygwin mounts using an "identity" scheme
such that C:/usr == /usr
C:/opt == /opt
and you never use files from any drive other than C:. This is usually
called "identity mounts" and is often used in certain WINE setups on
linux,
and (as in this case) MinGW setups under cygwin and/or msys.
c) and/or you are very careful that only relative paths are ever used
anywhere in your build system and configuration
d) you use --disable-dependency-tracking (this is esoteric: without this
then (mingw)gcc puts win32 (C:/foo) paths into .deps/*.P, and
(cygwin)make
doesn't understand them.)
AND the compiler you are using was the "Native" MinGW-distributed gcc (e.g.
from www.mingw.org) NOT a cygwin-hosted cross compiler or cygwin's gcc with
the (soon to be phased-out) -mno-cygwin switch. While odd, these scenarios
are not uncommon -- and several prominent mingw developers use this setup
exclusively. IMNSHO, this always was EXTREMELY fragile, and those guys are
darned lucky that it has worked as well as it has, for as long as it has.
In the current libtool-master, the situation above no longer works, IN
GENERAL.
For the specific case of building binutils and gcc (which those "prominent
mingw developers" care about) it DOES still continue to work -- mainly
because
binutils and gcc do NOT use libtool to build their executables (including
tests).
So...no cwrapper to worry about. For other packages...there's still a
problem.
This is because we (collectively, on libtool and cygwin lists, if I judged
the
consensus correctly) decided that
--build=cygwin --host=mingw
really ought to mean the same thing that any other --build=A --host=B
configuration
does: a CROSS environment, where the $build tools (compiler, but ALSO OS
utilities
like ln, uname, expr, cat) are true entities in the $build environment.
For instance,
if --build=cygiwn, then cat "understands" cygwin (that is, unix) paths and
does not
grok win32 (C:/foo) paths. Ditto -- most especially ditto -- for gcc: it's
a program
running on $build that makes $host output, and therefore gcc expects
$build-style
input paths. This is NOT the case if the gcc you are using is actually
the MinGW-
supplied gcc.exe.
So, as a special workaround for those people who
a) insist on lying to configure and claim that --build=mingw when it is
actually
cygwin
b) are building/compiling a package that actually needs to use the
cwrappers
(that is, not binutils nor gcc)
then what they need to do is the following:
$ export lt_cv_to_host_path_cmd=func_cygwin_to_mingw_path_convert
$ configure --build=mingw32 --host=mingw32 [--target=mingw32 [*]]
[*] Note that only toolchain packages (like binutils or gcc) ever need to
be given
a --target specification. However, since as described above,
gcc/binutils
luckily don't need to worry about this cwrapper issue, in practice
you'd never
need to override lt_cv_to_host_path* AND invoke configure with all
three
--build/--host/--target. (It's actually not luck. This is a
consequence of
the gcc/binutils folks taking special care for the mingw compilers in
cross-
and canadian-cross- scenarios. They already had to ensure that
symlinks
were never used in the tree, because otherwise the just-built gcc
wouldn't be
able to build its runtime libraries. Other issues also dictate this
serendipitous
result).
For more discussion of this issue, see the following:
[Re: [PATCH] [cygwin]: Add cross-compile support to cwrapper]
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00233.html
&& subthread
[RFD: cygwin + *native* MinGW compiler]
http://cygwin.com/ml/cygwin/2009-01/msg00808.html && thread
[***] assuming you have WINE installed, and the winepath executable can
be found in the $PATH on $build, and the linux-only binfmt kernel
extension is enabled.
[****] This is a regression in libtool-master ToT. With libtool-1.5.x, this
used to
work under the same circumstances as [***], but with current
libtool-master
and all libtool-2.2.x, it does not.
So, just as unix -> mingw cross builds need special support when creating
the cwrapper source code in order for the cwrapper to work properly under the
wine environment, so too do unix -> cygwin cross builds. However, this led to
a lot of duplicated code, so I refactored a bit.
WITH this patch, all of the "OK" items above remain "OK" (I've tested
the native mingw->mingw and cygwin->cygwin, and long ago Roumen Petrov
tested the unix/WINE->mingw case with this patch; Peter Rosen tested
the MSYS/msvc->native case with his additional patchset)
unix -> cygwin *should* work, but I can't test it
I'm hoping that somebody, with a working cygwin-under-WINE installation
can please do so. I do know that the core logic works, because I've
been able to extract that into a separate script and test it.
HOWEVER: even supposing that the putative unix->cygwin support DOESN'T work (and
I strongly believe it DOES work) the attached patch is still a strict
improvement
over current libtool-master, 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.
NOTE: At present, to use the unix -> cygwin support, you *MUST* have the
LT_CYGPATH environment variable exported, containing the *unix* (that is,
$build) path to the cygpath.exe you want to use.
# 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.
Oh: one other thing. I know using 'win32' is frowned upon by the FSF/RMS.
But I somehow need to distinguish between "cygwin" paths, "msys" paths,
and actual win32 paths. I have several functions now named func_*_to_win32*().
"mingw" is actually ambiguous, as it could also refer to unix-style msys paths.
"mingw_native" might be okay, but it's rather wordy. So I went with _win32.
==
Chuck
Makefile.am | 3
libltdl/config/ltmain.m4sh | 687 ++++++++++++++++++++++++++++++++++++---------
libltdl/m4/libtool.m4 | 53 +++
tests/testsuite.at | 5
diff --git a/Makefile.am b/Makefile.am
index a18955e..5d86681 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -508,7 +508,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 6f44d35..221b540 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2544,166 +2544,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_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_wine_to_win32_path_tmp}"; then
+ func_to_host_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_msys_to_mingw_path_convert
+
+
+# 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.
+#
+# 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_to_host_path
+# end func_nix_to_cygwin_path_convert
+
-# func_to_host_pathlist arg
+#################################################
+# $build to $host PATHLIST CONVERSION FUNCTIONS #
+#################################################
+# invoked via `eval $to_host_pathlist_cmd ARG'
#
-# 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):
+# 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_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_to_host_pathlist
+# 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 5f24fab..4bdb751 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -166,6 +166,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_CMD_OLD_ARCHIVE])dnl
@@ -7337,3 +7338,55 @@ _LT_EOF
;;
esac
])
+
+# _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 e9226ee..0bcdb5e 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -38,7 +38,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"
@@ -46,6 +46,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
- [PATCH] [cygwin]: Add cross-compile support to cwrapper take 5,
Charles Wilson <=