libtool-patches
[Top][All Lists]
Advanced

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

Re: [PATCH] [mingw] Add cross-compile support to cwrapper


From: Charles Wilson
Subject: Re: [PATCH] [mingw] Add cross-compile support to cwrapper
Date: Tue, 20 May 2008 23:02:51 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.14) Gecko/20080421 Thunderbird/2.0.0.14 Mnenhy/0.7.5.666

Roumen Petrov wrote:
No answer from wine-developers ( http://www.winehq.org/pipermail/wine-devel/2008-May/065695.html )

As expected you patch pass my test :).

That's good to know. Except for one issue [1], I'm of the opinion that my current patch is pedantically "correct" -- but slow, while your proposed modifications are optimizations.

Lets go upstream.

By this do you mean 'push to the git repo'? I'd rather wait for Ralf to get back and comment; should be later this week I think.

Roumen Petrov wrote:
Charles Wilson wrote:
But I'm not sure that supporting "changing the mapping after building the wrapper" is something we should support (e.g. deliberately code the wrapper to allow it, and then have to answer questions about why it does or does not work in some user's wacky wine setup, down the road.) Is there a realistic use case where this facility is important, that couldn't be solved by "okay, then rm -f wrapper.exe, make wrapper"

Expanding on this point, right now we do not expect the wrapper *scripts* to work outside of their build directory:

#! /bin/sh
# mdemo_static - temporary wrapper script for .libs/mdemo_static
# Generated by ltmain.sh (GNU libtool 1.2980 2008-05-13) 2.2.5a
...
# This wrapper script should never be moved out of the build directory.
# If it is, it will not operate correctly.

And, if you change your fstab so that the effective path to the wrapper script changes -- even if you don't physcially
   mv from-here/wrapper to-there/wrapper
I would still expect the wrapper script to be broken.

That same limitations apply to the binary wrapper executables. Change the wine "fstab" after you build, and you'll probably break the wrappers.

So if the wine developers confirm that run-time translation in not
"side-effect" we may skip winepath and the problem will disappear
and will not depend of $WINEPREFIX/dosdevice links.
In well setup environment z in link to the root of the filesystems on
build. In my test-environment m: is an additional link (to
<MINGWCROSS>) and z: is removed intentionally before tests.

But, if I understand your text above correctly, even with no Z: mapping (as long as you have SOME suitable mapping to the build directly), my current proposed patch works.

The problem I have with "echo $val | sed -e 's|:|;|g'" is what if, somehow, a dos-style path is in $val?

C:\bob -> C;\bob

May we left "the build path cannot contain ':'" as limitation of libtool in case of cross-compilation environment ?

But that's a rather arbitrary restriction, simply to enable an optimization in the wrapper generation, isn't it?

May be if ltmain.m4sh, during creation of dllsearchpath and some other variables, separate items by host system dir-separator the problem will be solved.

Oh, boy. I *really* don't know about that: because then the changes we are talking about are no longer isolated to one little corner of libtool, but could propagate everywhere -- and affect other platforms. No, thanks -- in that case, the cure is worse than the disease.

P.S.:
Also winepath exit with zero(!?!?!?) even if path cannot be translated:
==============================
$ winepath -w `pwd`; echo $?
Warning: could not find DOS drive for current working directory '/...../lt-HEAD-mingw-mlib', starting in the Windows directory.

0

Well, that's just...evil. Is it possible that this is a bug in winepath that should be reported upstream? Surely exit-with-0-on-error is not the *design* behavior, is it?

I'm going to have to think hard about how to detect error status...there is a very ugly way to simultaneously redirect stdout to one var, and stderr to another, but that's just...wrong.

[1] This one ^^^. I've attached an example of the technique that can be used to simultaneously capture both stdout and stderr. If test and echo are builtins, it has only three forks (2 seds necessary on win32 $build where TARGET may emit CRLF line endings, and the target invocation itself).

You could then
   test -n $captured_stderr
to determine if there were an error -- and you have $captured_stdout which holds the converted path value (if no error).

But, the example script uses a number of non-portable bash-isms, and frankly I don't see how to implement it in the restricted portable subset of POSIX that we are required to use in libtool.

Of course, the alternative is to invoke winepath twice. (ugh)

captured_stderr=`winepath ... 2>&1 1>/dev/null`
if -z "$captured_stderr" ; then
  captured_stdout=`winepath ... 2>/dev/null`
fi

Which is a lot simpler, and actually has FEWER forks -- especially once all of the not-universally-portable ${var%%}, ${var##}, and ${var/pat/rep} substitutions are replaced by sed!

This alternative imposes a race condition, of course: the first `winepath ...` might succeed without error, but then for some reason the second one might fail. I don't think there's anything we can do to guard against that. It sure would be nice if winepath weren't insane, and returned a failure exit code...

To sum up, I'm leaning toward the following, for now:
  (1) the existing proposed patch, ugly IFS manipulation and all
(2) but modify slightly to call winepath twice, as shown above, since we can't rely on winepath exit status
  (3) but wait for Ralf to return and comment before pushing anything

Then, after that, we can look at any additional optimizations that may be possible. (And I can think about *nix->cygwin cross support).

--
Chuck

#!/bin/bash

# func_invoke_and_capture target ...
# invokes the command specified by TARGET with 
# any additional arguments. The stdout and stderr
# that result from executing TARGET will be captured
# in variables func_invoke_and_capture_stdout and
# func_invoke_and_capture_stderr, respectively.
#
# The exit status of this function will be the 
# exit status of TARGET.
#
# This is accomplished without the use of temporary
# files, but uses several non-portable bash-isms:
#   echo -e
#   $'\n' (especially within subst patterns)
#   ${var##pattern} substitution
#   ${var%%pattern} substitution
#   ${var/pat/repl} substitution
#   nested $() command substition
func_invoke_and_capture() {
    func_invcap_result=
    func_invcap_stdout=
    func_invcap_var_out=
    func_invcap_val_err=
    func_invcap_SEP="----- separator -----"
    func_invcap_target="$1"
    shift
    func_invoke_and_capture_stdout=""
    func_invoke_and_capture_stderr=""
    if test -f "${func_invcap_target}" ; then
      func_invcap_result=$( { func_invcap_stdout=$("${func_invcap_target}" 
"address@hidden"); } 2>&1; \
         echo -e "${func_invcap_SEP}\n$?\n${func_invcap_SEP}"; echo -e 
"${func_invcap_stdout}")
      func_invcap_var_out="${func_invcap_result##*${func_invcap_SEP}$'\n'}"
      func_invcap_var_err="${func_invcap_result%%$'\n'${func_invcap_SEP}*}"
      func_invcap_var_out="${func_invcap_var_out/*${func_invcap_SEP}/}"
      func_invcap_var_err="${func_invcap_var_err/${func_invcap_SEP}*/}"
      func_invcap_result="${func_invcap_result%$'\n'${func_invcap_SEP}*}"
      func_invcap_result="${func_invcap_result#*${func_invcap_SEP}$'\n'}"

      if test -n "${func_invcap_var_err}" ; then
        func_invoke_and_capture_stderr=`echo "${func_invcap_var_err}" | sed -e 
's|\r||g'`
      fi
      if test -n "${func_invcap_var_out}" ; then
        func_invoke_and_capture_stdout=`echo "${func_invcap_var_out}" | sed -e 
's|\r||g'`
      fi
    else
      func_invoke_and_capture_stderr="$func_invcap_target not found";
    fi
    return $func_invcap_result
}

do_func() {
   func_invoke_and_capture "address@hidden"
   status=$?
   echo "stdout is: '$func_invoke_and_capture_stdout'"
   echo "stderr is: '$func_invoke_and_capture_stderr'"
   echo "status is: $status"
}
# NOTE: test.sh is:
#  #!/bin/sh
#  echo "$1"
#  echo "$2" 1>&2
#  exit $3

do_func "./test.sh" "stdout" "stderr" 0

echo

t_stdout=$(echo -e "stdout on\nmultiple lines")
t_stderr=$(echo -e "stderr on\nmultiple lines")
do_func "./test.sh" "$t_stdout" "$t_stderr" 2


reply via email to

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