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}"
"[EMAIL PROTECTED]"); } 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 "[EMAIL PROTECTED]"
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