Am Die, 2003-08-19 um 00.36 schrieb Dimitrie O. Paun:

> Try doing winegcc in standard sh, I doubt you'll get any shorter/cleaner
> code. Not to mention a bit slower :)

You challenged me :-) really, shell coding is one of my favorites.

Have a look at the attached code, if you like. Actually, I found it
easier to mimic winegcc than wineld. For C++ code, a link 
winec++ -> winecc needs to be created. 

I have added a few enhancements, such as dealing with non-standard Wine
installation directories, running from a Wine source tree, and more
sophisticated debug output. Therefore, the code indeed isn't shorter
than the C code. IMO it is more readable and to the point, though - but
that's of course a matter of taste.

I found that paths in the original winegcc/winewrap are broken for my
wine/linux installation, so the paths that I put in these scripts may be
broken for MingW. They can be easily customized with environment
variables, though; see bottom of winetools.sh.

All three files must be somewhere in the PATH.
Everyone is invited to try this stuff out. I ran it with bash, ash, zsh,
and pdksh here, so I guess it must be fairly portable.

Please send bug reports to my email address because I'am not reading
wine-devel on a daily basis.

Martin

-- 
Martin Wilck                Phone: +49 5251 8 15113
Fujitsu Siemens Computers   Fax:   +49 5251 8 20409
Heinz-Nixdorf-Ring 1        mailto:[EMAIL PROTECTED]
D-33106 Paderborn           http://www.fujitsu-siemens.com/primergy




#!/bin/sh

# winecc - winegcc clone in POSIX shell language.
# Copyright (C) 2003 Martin Wilck <[EMAIL PROTECTED]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

. winetools.sh || { echo "Cannot find winetools.sh; please adjust PATH">&2; exit 129; }

### Set script name (for error messages etc.)
if expr "$0" : '.*++[^/]*$' >/dev/null; then 
    myself=$WINE_CXX
    cpp_opt=-C
    compiler="$CXX"
else
    myself=$WINE_CC
    cpp_opt=
    compiler="$CC"
fi
__MY_VERSION__=0.1

usage="\
usage: $__ME__ [options] file...
Options: like $compiler options
   --keep          do not delete temporary files
   --wrap          generate wrapper code (e.g. for C++ code using static objects)
   -v|--verbose    increase verbosity level
   -q|--quiet      decrease verbosity level
"

win_gccopts="-fPIC -fshort-wchar"

win_defs="-DWIN32 -D_WIN32 -D__WIN32 -D__WIN32__ -D__WINNT -D__WINNT__ \
'-D__stdcall=__attribute__((__stdcall__))' \
'-D__cdecl=__attribute__((__cdecl__))' \
'-D__fastcall=__attribute__((__fastcall__))' \
'-D_stdcall=__attribute__((__stdcall__))' \
'-D_cdecl=__attribute__((__cdecl__))' \
'-D_fastcall=__attribute__((__fastcall__))' \
'-D__declspec(x)=__attribute__((x))'"

wine_defs="-DWINE_UNICODE_NATIVE \
-D__int8=char -D__int16=short -D__int32=int '-D__int64=long long'"

keep=
link=y
stdinc=y
stdlib=y
exe_mode=cui
msvcrt=
static=
output_name=

### scan_options
scan_options() {

    while [ "$#" -gt 0 ]; do
        case $1 in
        -\?|--help)
            quit "$usage";;
        -c|-S|-E|-M*) 
            link=;;
        --keep) keep=y;;
        -mno-cygwin)
            msvcrt=y;;
        -mwindows)
            exe_mode=gui;;
        -nostdinc)
            stdinc=;;
        -nodefaultlibs|-nostdlibs)
            stdlib=;;
        -static|--static) 
            static=y;;    
        -v|--verbose) 
            __VERBOSE__=$(($__VERBOSE__+1));;
        -q|--quiet)
            __VERBOSE__=$(($__VERBOSE__-1));;
        -V)
            quit "Version: $__MY_VERSION__";;
        -Wl)
            expr "$1" : '.*-static' && static=y
        esac
        shift
    done
}

get_obj() {
    
    case $1 in
    *.o|*.a|*.res)
        append link_cmd $1;;
    *)
        debug 1 "===> compiling $1"
        spawn "$myself -c -o $tmp_dir/${1%.*}.o $wineccargs $1"
        append link_cmd "$tmp_dir/${1%.*}.o";;
    esac
}
        

do_link() {

    link_cmd="$WINE_LD -m$exe_mode $cpp_opt"
    tmp_dir=`mktemp -d $TMPDIR/wineccXXXXXX` || \
        die "failed to create temporary directory"
    [ "x$keep" = xy ] || cleanup_add "rm -rf $tmp_dir"

    while [ "$#" -gt 0 ]; do
        
        case $1 in
        -L)
            shift; append link_cmd "-L $1";;
        -o)
            shift; output_name=$1;;
        -Wl) ;;
        -l*|L*|--wrap)
            append link_cmd $1;;
        -v|--verbose|--keep|-q|--quiet)
            append wineccargs $1
            append link_cmd $1;;
        -*) append wineccargs $1;;
        *)  
            get_obj $1;; # recursion!
        esac
        shift

    done

    [ -n "$output_name" ] || output_name="a.out"
    append link_cmd "-o $output_name"
    [ "x$msvcrt" = xy ] && append link_cmd "-lmsvcrt"
    [ "x$exe_mode" = "gui" ] && append link_cmd "-lcomdlg32"
    append link_cmd "-ladvapi32 -lshell32"

    spawn "$link_cmd"
}

do_compile() {
    cc_cmd="$compiler $win_gccopts $win_defs $wine_defs"
    [ x$stdinc = xy ] && {
        [ x$msvcrt = xy ] && \
            append cc_cmd "-I$WINE_INCLUDEDIR/msvcrt -D__MSVCRT__"
        append cc_cmd "-I$WINE_INCLUDEDIR"
    }

    [ $__VERBOSE__ -ge 3 ] && append cc_cmd "-v"

    while [ "$#" -gt 0 ]; do
    case $1 in
        -mno-cygwin|-mwindows|-mthreads|-Wl*|-s*|--keep|--wrap|-v|--verbose|-q|--quiet) 
            ;; # ignore
        *) append cc_cmd "$1";;
        esac
        shift
    done
    spawn "$cc_cmd"
}

scan_options "$@"

[ -n "$static" ] && die "static linking is not supported"

if [ -n "$link" ]; then
    do_link "$@"
else
    do_compile "$@" 
fi
#!/bin/sh

# wineld - winewrap clone in POSIX shell language.
# Copyright (C) 2003 Martin Wilck <[EMAIL PROTECTED]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

. winetools.sh

### Set script name (for error messages etc.)
__MY_VERSION__=0.1

usage="\
usage: $__ME__ [option]... [file]... -- [compiler option|file]...
Options:
--		separate $me options and compiler options
-?|--help	print this information
-k|--keep	keep temporary files
--output-name file
-o file		set output file name
-L path		add path to library search path
-l library	add library
-mgui		GUI mode
-C|--c++	use C++ compiler for linking
-v|--verbose    increase verbosity level
-q|--quiet      decrease verbosity level
-W|--wrap	generate wrapper code (e.g. for C++ code using static objects)"

###### spec files #######
### create_spec <filename> <gui|cui>
create_spec() {
    case $2 in
    gui) echo "1 stdcall WinMain(ptr long ptr long) WinMain" >$1;;
    cui) echo "1 stdcall main(long ptr ptr) main" >$1;;
    *)   die  "unknown exe mode $_mode";;
    esac
}

### create_app_loader <file> <program name>
create_app_loader() {
    cat >$1 <<END_OF_APP_LOADER
#!/bin/sh

: \${WINEDLLPATH:=$WINE_DLLPATH}
: \${LD_LIBRARY_PATH:=$LIB_PATH}
: \${WINELOADER:=$WINE_LOADER}
: \${WINESERVER:=$WINE_SERVER}
export WINEDLLPATH LD_LIBRARY_PATH WINELOADER WINESERVER

appname="$2"
# determine the application directory
appdir=''
case "\$0" in
  */*)
    # \$0 contains a path, use it
    appdir=\`dirname "\$0"\`
    ;;
  *)
    # no directory in \$0, search in PATH
    saved_ifs="\$IFS"
    IFS=:
    for d in \$PATH
    do
      IFS="\$saved_ifs"
      if [ -x "\$d/\$appname" ]; then appdir="\$d"; break; fi
    done
    ;;
esac

while true; do
  case "\$1" in
    --debugmsg)
      debugmsg="\$1 \$2"
      shift; shift;
      ;;
    --dll)
      dll="\$1 \$2"
      shift; shift;
      ;;
    *)
      break
      ;;
  esac
done

# figure out the full app path
if [ -n "\$appdir" ]; then
    apppath="\$appdir/\$appname.exe.so"
    WINEDLLPATH="\$appdir:\$WINEDLLPATH"
else
    apppath="\$appname.exe.so"
fi

# determine the WINELOADER
if [ ! -x "\$WINELOADER" ]; then WINELOADER="wine"; fi

# and try to start the app
exec "\$WINELOADER" \$debugmsg \$dll -- "\$apppath" "\$@"
END_OF_APP_LOADER
    chmod a+x $1 || die "cannot change permissions of $1"
}

### create_wrapper <file> <app name> <gui|cui>
create_wrapper() {

    case $3 in
    gui) set -- "$1" "$2" 1;;
    cui) set -- "$1" "$2" 0;;
    *)   die "unknown exe mode $3";;
    esac

    cat >$1 <<END_OF_WRAPPER_CODE
/*
 * Copyright 2000 Francois Gouget <[EMAIL PROTECTED]> for CodeWeavers
 * Copyright 2002 Dimitrie O. Paun <[EMAIL PROTECTED]>
 */

#include <dlfcn.h>
#include <windows.h>


/*
 * Describe the wrapped application
 */

/* The app name */
#define APPNAME "$2"
/**
 * This is either 0 for a console based application or
 * 1 for a regular windows application.
 */
#define GUIEXE $3

#if !GUIEXE
#  include <stdio.h>
#endif

/**
 * This is the name of the library containing the application,
 * e.g. 'hello-wrap.dll' if the application is called 'hello.exe'.
 */
static char* appName     = APPNAME "-wrap.dll";

/**
 # This is the name of the application's Windows module. If left NULL
 * then appName is used.
 */
static char* appModule   = NULL;

/**
 # This is the application's entry point. This is usually 'WinMain' for a
 * gui app and 'main' for a console application.
 */
#if GUIEXE
static char* appInit     = "WinMain";
#else
static char* appInit     = "main";
#endif

/**
 * This is either non-NULL for MFC-based applications and is the name of the
 # MFC's module. This is the module in which we will take the 'WinMain'
 * function.
 */
static char* mfcModule   = NULL;


void error(const char *format, ...)
{
    va_list ap;
    char msg[4096];

    va_start(ap, format);
    vsnprintf(msg, sizeof(msg), format, ap);
#if GUIEXE
    MessageBox(NULL, msg, "Error", MB_OK);
#else
    fprintf (stderr, "Error: %s\n", msg);
#endif
    va_end(ap);
    exit(1);
}


#if GUIEXE
typedef int WINAPI (*WinMainFunc)(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				  PSTR szCmdLine, int iCmdShow);
#else
typedef int WINAPI (*MainFunc)(int argc, char** argv, char** envp);
#endif

#if GUIEXE
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
#else
int WINAPI main(int argc, char** argv, char** envp)
#endif
{
    HINSTANCE hApp = 0, hMFC = 0, hMain = 0;
    void* appMain;
    int retcode;

    /* Then if this application is MFC based, load the MFC module */
    if (mfcModule) {
        hMFC = LoadLibrary(mfcModule);
        if (!hMFC) error("Could not load the MFC module %s (%d)", mfcModule, GetLastError());
        /* For MFC apps, WinMain is in the MFC library */
        hMain = hMFC;
    }

    /* # Load the application module */
    if (!appModule) appModule = appName;
    hApp = LoadLibrary(appModule);
    if (!hApp) error("Could not load the application module %s (%d)", appModule, GetLastError());
    if (!hMain) hMain = hApp;

    /* Get the address of the application entry point */
    appMain = GetProcAddress(hMain, appInit);
    if (!appMain) error("Could not get the address of %s (%d)", appInit, GetLastError());

    /* And finally invoke the application entry point */
#if GUIEXE
    retcode = (*((WinMainFunc)appMain))(hApp, hPrevInstance, szCmdLine, iCmdShow);
#else
    retcode = (*((MainFunc)appMain))(argc, argv, envp);
#endif

    /* Cleanup and done */
    FreeLibrary(hApp);
    FreeLibrary(hMFC);

    return retcode;
}
END_OF_WRAPPER_CODE
}

### scan_options
scan_options() {

    while [ "$#" -gt 0 ]; do
        case $1 in
        --) 
            shift; break;;
        -\?|--help)
            quit "$usage";;
        -k|--keep) 
            keep=y;;
        -o|--output-name) 
            shift; output_name=$1;;
        -o*)
            output_name="${1#-o}";;
        -L) 
            shift; add_lib_path $1;;
        -L*) 
            add_lib_path "${1#-L}";;
        -l) 
            shift; add_lib_file $1;;
        -l*)
            add_lib_file "${1#-l}";;
        -mgui|-mcui)
            [ x$exe_mode = x${exe_mode%SET} ] || die "only one of -mcui/-mgui options allowed"
            exe_mode="${1#-m}SET";;
        -v|--verbose)
            __VERBOSE__=$(($__VERBOSE__+1));;
        -q|--quiet)
            __VERBOSE__=$(($__VERBOSE__-1));;
        -V) 
            quit "Verson: $__MY_VERSION__";;
        -C|--c++)
            compiler=$CXX;;
        -W|--wrap)
            wrap=y;;
        -*)
            die "$usage";;
        *)
            append obj_files $1;;
        esac
        shift
    done

    exe_mode=${exe_mode%SET}
    __rest__="$@"
}

### find_in_path <file> <dir:dir:...> - try to find a file in a PATH-like list
find_in_path() {

    (
     IFS=:
     for _d in $2; do
         [ -d $_d ] || { warn "invalid directory $_d in search path"; continue; }
         [ -f $_d/$1 ] && { _r=$_d; break; }
     done
                
     if [ -n "$_r" ]; then
        debug 4 "$1 found in $_r"
        printf %s "$_r/$1"
     else
        debug 3 "$1 not found in $2" 
     fi
    )
}

### make_lib_path - set LIB_PATH to a reasonable guess
make_lib_path() {

    assert_local _saved_ifs
    _saved_ifs="$IFS"

    LIB_PATH=$LD_LIBRARY_PATH

    IFS=:
    set -- $WINE_LIBPATH
    while [ "$#" -gt 0 ]; do
        prepend_unique LIB_PATH $1 ":"
        shift
    done

    IFS="$_saved_ifs"
    unset _saved_ifs
}

### add_lib_path <directory>
add_lib_path() {
    [ -n "$1" ] || { err "empty dir in add_lib_path"; return; }
    [ -d "$1" ] || { warn "$1 is not a directory"; return; }
    if ls $1 | grep -q '\.def$'; then
        debug 4 "$1 contains .def files - using as dll dir"
        prepend WINE_DLLPATH $1 ':';
    else    
        prepend LIB_PATH $1 # FIXME: always?
    fi    
}

### add_lib_file <library>
add_lib_file() {
    case $1 in
    uuid)    set wine_uuid;;
    unicode) set wine_unicode;;
    esac

    if [ -n "`find_in_path lib$1.def $WINE_DLLPATH`" ] || \
       [ -n "`find_in_path lib$1.def .`" ]; then
        debug 4 "adding DLL $1"
        append dll_files "-l$1"
    elif [ -n "`find_in_path $1.a $LIB_PATH`" ]; then
        debug 4 "adding library $1.a"
        append arh_files $1
    else #??
        debug 1 "cannot find -l$1, trying anyway"
        append lib_files "-l$1"
    fi
}

# **************** main program ****************

### Options

exe_mode="cui"
compiler="$CC"

### Initialization
__VERBOSE__=0

### MAIN

make_lib_path

scan_options "$@"

[ -n "$WINE_ROOT" ] || \
    die "no wine directory found -- please set WINE_ROOT or use the -w option"
[ -n "$obj_files" ] || die "no input files
$usage"
[ -n "$output_name" ] || \
    die "no output file specified -- please use the -o option"
nextstage

[ "$exe_mode" = gui ] && add_lib_file "gdi32"
add_lib_file "user32"
add_lib_file "kernel32"

tmp_dir=`mktemp -d $TMPDIR/wineldXXXXXX` || \
    die "failed to create temporary directory"
[ "x$keep" = xy ] || cleanup_add "rm -rf $tmp_dir"
nextstage

base_file=${output_name%.exe}
base_name=`basename $base_file`
spec_name=$tmp_dir/$base_name.spec
wine_libs="-lwine -lm"
winebuild_flags=`map 'new=-L$old' "$WINE_DLLPATH" : " "`
LD_FLAGS="-shared -Wl,-Bsymbolic,-z,defs "`map 'new=-L$old' "$LIB_PATH" : " "`

if [ -z "$wrap" ]; then
    spec_exe_args="--exe $base_name.exe -m$exe_mode"
    link_output_args="-o $base_file.exe.so"
else
    spec_exe_args="-F $base_name-wrap.dll --spec $spec_name"
    link_output_args="-o $base_name-wrap.dll.so"
    wspec_name=$tmp_dir/wrapper.spec
    wrapper_name=$tmp_dir/wrapper

    debug 1 "===> compiling wrapper"
    create_wrapper $wrapper_name.c $base_name $exe_mode || \
        die "failed to create $wrapper_name"
    nextstage
    spawn "$CC -fPIC -I$WINE_INCLUDEDIR -o $wrapper_name.o -c $wrapper_name.c"
    spawn "$WINE_BUILD $winebuild_flags \
           -o $wspec_name.c --exe $base_name.exe -m$exe_mode $wrapper_name.o -luser32"
    spawn "$CC -fPIC -o $wspec_name.o -c $wspec_name.c"
    spawn "$compiler -$LD_FLAGS -o $base_file.exe.so \
        $wspec_name.o $wrapper_name.o -ldl $wine_libs"
fi

debug 1 "===> compiling spec file"
create_spec $spec_name $exe_mode || die "failed to create $spec_name"
nextstage

spawn "$WINE_BUILD $winebuild_flags \
       -o $spec_name.c $spec_exe_args $dll_files $arh_files $obj_files"
spawn "$CC -fPIC -o $spec_name.o -c $spec_name.c"

debug 1 "===> linking"
spawn "$compiler $LD_FLAGS $link_output_args $spec_name.o \
    $obj_files $arh_files $lib_files $wine_libs $__rest__"

create_app_loader $base_file $base_name || die "cannot create app loader"
#!/bin/sh

# winetools.sh - a small shell function library for wineld/winecc.
# Copyright (C) 2003 Martin Wilck <[EMAIL PROTECTED]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

### messages

### info <message>
info() {
    printf "%s\n" "$__ME__($$): $1" >&2
}

### debug <level> <message>
debug() {
    [ "${__VERBOSE__}" -ge "$1" ] && info "[$1]: $2"
}

### quit <message>
quit() {
    info "$1"
    exit 0
}

### warn <message>
warn() {
    debug -1 "$1"
}

err() {
    debug -2 "$1"
}

### strings

### substr <string> <offset> [<length>]
### substr 'john doe' 1 3
### --> 'ohn'
substr() {
    case "$#" in
    2) expr "$1" : ".\\{$2\\}\\(.*\\)";;
    3) expr "$1" : ".\\{$2\\}\\(.\\{0,$3\\}\\)";;
    *) die_n_args "substr"
    esac
}

### error code handling
### exit code will be __stage__ + 128

__err_base__=128
__stage__=1

nextstage() {
    debug 5 "stage $__stage__ successfully completed"
    __stage__=$(($__stage__+1))
}

die() {
    debug -3 "$1"
    exit $(($__stage__+$__err_base__))
}

die_n_args() {
    die "$1: wrong number of arguments"
}

### assert_local <var> <var> ... - ensure that given variables are unset
assert_local() {
    while [ "$#" -gt 0 ]; do
        eval "[ -n \"\$$1\" -o -z \"\${$1-X}\" ]" && die "BUG: local variable $1 is set"
        shift
    done
}

### list handling

### append <list_name> <element> <separator>
### people=; append people jack ,; append people george ,; echo $people
### --> jack,george
append() {
    case "$#" in
    2) set -- "$@" "`substr \"$IFS\" 0 1`";;
    3) ;;
    *) die_n_args "append";;
    esac

    eval "\
if [ -z \"\$$1\" ]; then
    $1=\"$2\"
else
    $1=\"\$$1$3$2\"
fi"
}

### prepend <list_name> <element> <separator>
### see append()
prepend() {
    case "$#" in
    2) set -- "$@" "`substr \"$IFS\" 0 1`";;
    3) ;;
    *) die_n_args "prepend";;
    esac

    eval "\
if [ -z \"\$$1\" ]; then
    $1=\"$2\";
else
    $1=\"$2$3\$$1\";
fi"
}

### is_member <list_name> <element> <separaror>
### people=jack,john; is_member people jack , && echo yes
### --> yes
is_member() {

    case "$#" in
    3) ;;
    2) set -- "$@" "$IFS";;
    *) die_n_args "is_member";;
    esac

    eval "(
        IFS=\"$3\"
        for _e in \$$1; do
            [ \$_e = \"$2\" ] && exit 0
        done
        exit 1
    )"
}

append_unique() {
    is_member "$1" "$2" "$3" || append "$1" "$2" "$3"
}

prepend_unique() {
    is_member "$1" "$2" "$3" || prepend "$1" "$2" "$3"
}

### map <transform> <list> [<separator> [<output separator>]]
### <transform> is a shell expression that takes $old and assigns to _new.
### <separator> is the field separator in the input list (default $IFS)
### <output separator> is the field separator in the output list (default 1st char of <separator>)

### map 'new=-L$old' "/lib:/usr/lib" : " "
### --> -L/lib -L/usr/lib
### map 'new=`echo $old | tr a-z A-Z`' "/lib /usr/lib"
### --> /LIB /USR/LIB
### map 'new=`echo $old | sed s,/,\\\\\\\\,g`' "/lib /usr/lib"
### --> \lib \usr\lib
map() {

    case "$#" in
    2) set -- "$@" "$IFS" "`substr \"$IFS\" 0 1`";;
    3) set -- "$@" "`substr \"$3\" 0 1`";;
    4) ;;
    *) die_n_args "map"
    esac

    debug 3 "applying transform '$1' to '$2'"

    eval "(
        _out=
        IFS=\"$3\"
        for old in \$2; do
            $1 || 2>/dev/null || {
                new='*ERROR*';
                warn \"map: error during transform: '$1' with old=\$old'\";
            }
            append _out \"\$new\" \"$4\"
        done
        printf %s \"\$_out\"
    )"
}

### cleanup at exit

__trap_cmd__=''

### cleanup_add <command> -- add <command> to cleanup at exit
cleanup_add() {
    case $1 in
    *\;*) die "Illegal cleanup command: \"$1\"";;
    esac
    prepend __trap_cmd__ "$1" ";"
}

### cleanup_del() -- remove last cleanup_add'ed command
cleanup_del() {
    __trap_cmd__=${__trap_cmd__#*;}
}

trap '[ "$_notrap" != yes -a -n "$__trap_cmd__" ] && {
    debug 1 "===> Cleanup"
    debug 2 "command: $__trap_cmd__"
    eval "$__trap_cmd__"
}' EXIT

### spawn <command>
spawn() {
    debug 2 "command: $1"
    if [ $__VERBOSE__ -ge -2 ]; then 
        eval "$1"
    else    
        eval "$1" >/dev/null 2>&1 
    fi || die "error running ${1%% *}"
    nextstage
}

check_progs() {
    set -- WINE_BUILD WINE_LD WINE_CC WINE_CXX WINE_SERVER WINE_LOADER
    while [ "$#" -gt 0 ]; do
        eval "[ -x \$$1 ] || die \"cannot execute \$$1 - please check $1 environment variable\""
        shift
    done
}

### WINE stuff

__ME__="${0##*/}"
__VERBOSE__=0

: ${TMPDIR:=/tmp}
: ${CC:=gcc}
: ${CXX:=g++}
: ${WINE_ROOT:=/usr/local}

if [ -f $WINE_ROOT/dlls/ntdll/nt.o ]; then # it's a source tree
    : ${WINE_BINDIR:=$WINE_ROOT}
    : ${WINE_TOOLDIR:=$WINE_ROOT/tools}
    : ${WINE_INCLUDEDIR:=$WINE_ROOT/include}
    : ${WINE_LIBPATH:=$WINE_ROOT/dlls:$WINE_ROOT/libs}
    : ${WINE_DLLPATH:=$WINE_ROOT/dlls:$WINE_ROOT/programs}
    : ${WINE_BUILD:=$WINE_TOOLDIR/winebuild/winebuild}
    : ${WINE_SERVER:=$WINE_ROOT/server/wineserver}
    : ${WINE_LOADER:=$WINE_ROOT/miscemu/wine}
else # try installation defaults
    : ${WINE_BINDIR:=$WINE_ROOT/bin}
    : ${WINE_TOOLDIR:=$WINE_BINDIR}
    : ${WINE_INCLUDEDIR:=$WINE_ROOT/include/wine}
    : ${WINE_LIBPATH:=$WINE_ROOT/lib}
    : ${WINE_DLLPATH:=$WINE_LIBPATH/wine}
    : ${WINE_BUILD:=$WINE_BINDIR/winebuild}
    : ${WINE_SERVER:=$WINE_BINDIR/wineserver}
    : ${WINE_LOADER:=$WINE_BINDIR/wine}
fi

: ${WINE_LD:=$WINE_TOOLDIR/wineld}    # name of the "ld" script
: ${WINE_CC:=$WINE_TOOLDIR/winecc}    # name of the "cc" script
: ${WINE_CXX:=$WINE_TOOLDIR/winec++}  # name of the "c++" script (link to $WINE_CC)

check_progs

Reply via email to