Charles Wilson wrote:
Roumen Petrov wrote:
Charles Wilson wrote:
[mingw] Add cross-compile support to cwrapper
May be the patch can be more simple. In a previous post I confirm that
for the wine emulator is enough items in path list, where every item
is absolute path from build system, to be separated by DOS
path-separator only.
Right, and thank you for that. What wasn't clear, however, was whether
this automatic path translation was a peculiarity of your wine setup
(e.g. "identity mounts" or something) or is a documented feature of wine.
Automatic path translation work for me. I may ask wine-developers to
confirm.
This is enough and at run-time wine(wineloader?) will translate
internally from "build system absolute path" to the "path from
emulated environment".
So it only works for absolute paths, but is applied to all environment
variables (like PATH)?
winepath will convert relative paths, AFAICT, although it converts them
to absolute first, and canonicalizes if you have permissions to chdir to
the target:
No it work for relative paths too, but with limitation:
path can be relative to the executable location and current work
directory is equal to executable path it works.
I attach my test case (bootstrap.sh) executabel + two dependent shared
libraries from different directories.
The wine is setup with $WINEPREFIX/dosdevices/m: linked <MINGWCROSS>>
Note that <MINGWCROSS> is absolute path in build system.
Lets see output from the script:
========================================
<autotool build>
=== ./foo-t1.exe ===
in main()
in foo1(11)
in foo2(22)
in foo1(22)
(main) argv[0] : ./foo-t1.exe
(main) program_name : foo-t1.exe
(find_executable) : ./foo-t1.exe
(check_executable) : M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t1.exe
(main) found exe (before symlink chase) at :
M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t1.exe
(main) found exe (after symlink chase) at :
M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t1.exe
(main) libtool target name: foo.exe
(lt_setenv) setting 'BIN_SH' to 'xpg4'
(lt_setenv) setting 'DUALCASE' to '1'
(lt_update_lib_path) modifying 'PATH' by prepending
'<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib1/.libs;'
(lt_setenv) setting 'PATH' to
'<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib1/.libs;c:\windows\system32;c:\windows;z:\opt\mingw\bin;z:\opt\mingw\gtk2\bin'
(lt_update_exe_path) modifying 'PATH' by prepending
';<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib1/.libs;/tmp/test/pkg/lt-HEAD-mingw-mlib/lib;/tmp/test/pkg/lt-HEAD-mingw-mlib/bin;'
(lt_setenv) setting 'PATH' to
';<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib1/.libs;/tmp/test/pkg/lt-HEAD-mingw-mlib/lib;/tmp/test/pkg/lt-HEAD-mingw-mlib/bin;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib1/.libs;c:\windows\system32;c:\windows;z:\opt\mingw\bin;z:\opt\mingw\gtk2\bin'
(main) lt_argv_zero : M:/1/lt-HEAD-mingw-mlib-autotools/appl/./.libs/foo.exe
(main) newargz[0] :
M:/1/lt-HEAD-mingw-mlib-autotools/appl/./.libs/foo-t1.exe
DONE[t1]=126
=== ./foo-t2.exe ===
in main()
in foo1(11)
in foo2(22)
in foo1(22)
(main) argv[0] : ./foo-t2.exe
(main) program_name : foo-t2.exe
(find_executable) : ./foo-t2.exe
(check_executable) : M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t2.exe
(main) found exe (before symlink chase) at :
M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t2.exe
(main) found exe (after symlink chase) at :
M:\1\lt-HEAD-mingw-mlib-autotools\appl/./foo-t2.exe
(main) libtool target name: foo.exe
(lt_setenv) setting 'BIN_SH' to 'xpg4'
(lt_setenv) setting 'DUALCASE' to '1'
(lt_update_lib_path) modifying 'PATH' by prepending
'<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;../lib1/.libs;'
(lt_setenv) setting 'PATH' to
'<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;../lib1/.libs;c:\windows\system32;c:\windows;z:\opt\mingw\bin;z:\opt\mingw\gtk2\bin'
(lt_update_exe_path) modifying 'PATH' by prepending
';<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;../lib1/.libs;/tmp/test/pkg/lt-HEAD-mingw-mlib/lib;/tmp/test/pkg/lt-HEAD-mingw-mlib/bin;'
(lt_setenv) setting 'PATH' to
';<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;../lib1/.libs;/tmp/test/pkg/lt-HEAD-mingw-mlib/lib;/tmp/test/pkg/lt-HEAD-mingw-mlib/bin;<MINGWCROSS>/1/lt-HEAD-mingw-mlib-autotools/lib2/.libs;../lib1/.libs;c:\windows\system32;c:\windows;z:\opt\mingw\bin;z:\opt\mingw\gtk2\bin'
(main) lt_argv_zero : M:/1/lt-HEAD-mingw-mlib-autotools/appl/./.libs/foo.exe
(main) newargz[0] :
M:/1/lt-HEAD-mingw-mlib-autotools/appl/./.libs/foo-t2.exe
DONE[t2]=126
========================================
The libtool create C-wrapper with absolute paths.
- foo-t1.exe, where ':' is replaced with ';' : can be run from any location.
- foo-t1.exe, where path to one of libraries is relative. : work only if
is run for executable directory.
~ $ winepath -w ../<anonther user>
Z:\home\<my_user>\..\<another user>
~ $ winepath -w ../../mnt
Z:\mnt
The same is in run time.
Also the mapping can be changed after build of package (creation of
cwrapper). So that translated paths (in cwrapper) may point to non
existing more locations in emulated environment.
Well, this is also true of winepath:
$ winepath -w /tmp/nonexistent
Z:\tmp\nonexistent
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"
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.
Also, it's a bit odd to convert the $target_exe path (the argument of
_spawnv) to $host format, but set PATH using $build format path
components. Or does wine's emulation of _spawnv ALSO do automatic path
translation, and we could -- if we choose -- leave ALL paths in $build
format with the exception of s|/|\\|g and s|:|;|g?
I still think we don't want to do /that/ -- see caveats, below.
>
Please, let me know if you need more info (strace output, dos device
mapping, etc). The test case that I use was posted to the list. In brief:
- library foo1 in ./lib1
- library libfoo2 in ./lib2
- executable foo.exe in ./appl that call functions from foo1 and foo2
libraries.
Well, you didn't actually say whether the existing patch works or not --
just that you think it could be simplified. <g>
Does the current patch work?
Not yet tested, but looks good.
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 ?
(I mean, really: s|:|;|g is bit naive. I was kinda hoping somebody would
give me a better sed expression than the one I'm using in
lt_sed_naive_backslashify...)
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.
Anyway, to avoid C;\bob, I'd need a lot of special casing: if $val
starts with a letter, followed by a ':', followed by an optional '/',
then don't replace the ':', otherwise do. Also, if you see a rooted
relative path (C:bar) which means 'get the drive-specific CWD for drive
C:, and append \bar', then you should flag an error (because you don't
know what the per-drive CWD is within the wine environment)? Or you
should treat as if it is really 'C:\bar' instead, and insert the
"missing" '\' (this is what cygpath does, BTW)?
libtool shouldn't need to worry about these details of one particular
emulation environment. They (the wine people) gave us a path translator
program, we should use it -- and let IT worry about those issues.
Sure, the existing code is a bit ugly, because of winepath's deficiency
(it doesn't atomically convert pathLISTs), but I hope that eventually
winepath WILL support that, and then our ugliness goes away...
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.
--
Chuck
Roumen
#! /bin/sh
#set -e
ARCH=i386
PKG=lt-HEAD-mingw-mlib
libtoolPREFIX=/usr/local/libtool/HEAD
automakePREFIX=/usr/local/automake/1.10.1
autoconfPREFIX=/usr/local/autoconf/2.61
aclocalVERSION=1.10
#===
PATH="$libtoolPREFIX/bin:$PATH"
PATH="$automakePREFIX/bin:$PATH"
PATH="$autoconfPREFIX/bin:$PATH"
. ../../mingw-env
export PATH
aclocal() {
"$automakePREFIX"/bin/aclocal \
-I "$libtoolPREFIX"/share/aclocal \
-I "$automakePREFIX"/share/aclocal-${aclocalVERSION} \
-I "$mingwPREFIX"/share/aclocal \
-I /usr/share/aclocal \
${1+"$@"}
}
#===
do_lib1() {
test -d lib1 || mkdir lib1
cat > lib1/foo.c <<EOF
#include <stdio.h>
extern void foo1(long n) {
fprintf(stderr, "in foo1(%ld)\n", n);
}
EOF
cat > lib1/Makefile.am <<EOF
lib_LTLIBRARIES = libfoo1.la
libfoo1_la_SOURCES = foo.c
EOF
}
do_lib2() {
test -d lib2 || mkdir lib2
cat > lib2/foo.c <<EOF
#include <stdio.h>
extern void foo1(long n);
extern void foo2(long n) {
fprintf(stderr, "in foo2(%ld)\n", n);
foo1(n);
}
EOF
cat > lib2/Makefile.am <<EOF
lib_LTLIBRARIES = libfoo2.la
libfoo2_la_SOURCES = foo.c
libfoo2_la_LIBADD = ../lib1/libfoo1.la
EOF
}
do_appl() {
test -d appl || mkdir appl
cat > appl/foo.c <<EOF
#include <stdio.h>
extern void foo1(long n);
extern void foo2(long n);
int main() {
fprintf(stderr, "in main()\n");
foo1(11);
foo2(22);
return(126); /*to check exit code*/
}
EOF
cat > appl/Makefile.am <<EOF
bin_PROGRAMS = foo
foo_SOURCES = foo.c
foo_LDADD = ../lib2/libfoo2.la
EOF
}
do_top() {
test -d build-aux || mkdir build-aux
cat > configure.ac <<EOF
AC_INIT([test], [0.0])
AC_PREREQ(2.60)
AC_CONFIG_AUX_DIR(build-aux)
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE
AC_PROG_CC
LT_INIT([shared win32-dll])
AC_OUTPUT([
lib1/Makefile
lib2/Makefile
appl/Makefile
Makefile
])
EOF
cat > Makefile.am <<EOF
SUBDIRS = lib1 lib2 appl
EOF
}
do_bootstrap() {
do_lib1
do_lib2
do_appl
do_top
libtoolize --force --copy --automake
aclocal
automake --foreign --add-missing --copy
autoconf
}
#===
do_bootstrap
./configure --prefix=/tmp/test/pkg/$PKG --build=${ARCH}-gnu-linux
--host=${ARCH}-mingw32msvc
make LDFLAGS='-no-undefined -avoid-version'
(
cd appl
DEBUGWRAPPER="-DDEBUGWRAPPER"
CC=${ARCH}-mingw32msvc-gcc
awk '{ \
if ( $0 ~ /PATH_VALUE.*=/ ) \
gsub(":", ";"); \
print $0; \
}' < .libs/lt-foo.c > .libs/lt-foo-t1.c
LIB1PWD=`cd ../lib1; pwd`
awk '{ \
if ( $0 ~ /PATH_VALUE.*=/ ) \
gsub("'$LIB1PWD'", "../lib1"); \
print $0; \
}' < .libs/lt-foo-t1.c > .libs/lt-foo-t2.c
echo "=== ./foo-t1.exe ==="
$CC -g -O2 $DEBUGWRAPPER -o foo-t1.exe .libs/lt-foo-t1.c
wine ./foo-t1.exe
echo DONE[t1]=$?
echo "=== ./foo-t2.exe ==="
$CC -g -O2 $DEBUGWRAPPER -o foo-t2.exe .libs/lt-foo-t2.c
wine ./foo-t2.exe
echo DONE[t2]=$?
)