/*
 * MinGW wrapper: makes gcc behave like MinGW.
 *
 * Copyright 2000 Manuel Novoa III
 * Copyright 2000 Francois Gouget
 * Copyright 2002 Dimitrie O. Paun
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * DESCRIPTION
 *
 * all options for gcc start with '-' and are for the most part
 * single options (no parameters as separate argument). 
 * There are of course exceptions to this rule, so here is an 
 * exhaustive list of options that do take parameters (potentially)
 * as a separate argument:
 *
 * Compiler:
 * -x language
 * -o filename
 * -aux-info filename
 *
 * Preprocessor:
 * -D name 
 * -U name
 * -I dir
 * -MF file
 * -MT target
 * -MQ target
 * (all -i.* arg)
 * -include file 
 * -imacros file
 * -idirafter dir
 * -iwithprefix dir
 * -iwithprefixbefore dir
 * -isystem dir
 * -A predicate=answer
 *
 * Linking:
 * -l library
 * -Xlinker option
 * -u symbol
 *
 * Misc:
 * -b machine
 * -V version
 * -G num  (see NOTES below)
 *
 * NOTES
 * There is -G option for compatibility with System V that
 * takes no parameters. This makes "-G num" parsing ambiguous.
 * This option is synonymous to -shared, and as such we will
 * not support it for now.
 *
 * Special interest options 
 *
 *      Assembler Option
 *          -Wa,option
 *
 *      Linker Options
 *          object-file-name  -llibrary -nostartfiles  -nodefaultlibs
 *          -nostdlib -s  -static  -static-libgcc  -shared  -shared-libgcc
 *          -symbolic -Wl,option  -Xlinker option -u symbol --image-base
 *
 *      Directory Options
 *          -Bprefix  -Idir  -I-  -Ldir  -specs=file
 *
 *      Target Options
 *          -b machine  -V version
 *
 * Please note that the Target Options are relevant to everything:
 *   compiler, linker, assembler, preprocessor.
 * 
 */ 

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>

#include "utils.h"

static const char* app_loader_template =
    "#!/bin/sh\n"
    "\n"
    "appname=\"%s\"\n"
    "# determine the application directory\n"
    "appdir=''\n"
    "case \"$0\" in\n"
    "  */*)\n"
    "    # $0 contains a path, use it\n"
    "    appdir=`dirname \"$0\"`\n"
    "    ;;\n"
    "  *)\n"
    "    # no directory in $0, search in PATH\n"
    "    saved_ifs=$IFS\n"
    "    IFS=:\n"
    "    for d in $PATH\n"
    "    do\n"
    "      IFS=$saved_ifs\n"
    "      if [ -x \"$d/$appname\" ]; then appdir=\"$d\"; break; fi\n"
    "    done\n"
    "    ;;\n"
    "esac\n"
    "\n"
    "# figure out the full app path\n"
    "if [ -n \"$appdir\" ]; then\n"
    "    apppath=\"$appdir/$appname\"\n"
    "    WINEDLLPATH=\"$appdir:$WINEDLLPATH\"\n"
    "    export WINEDLLPATH\n"
    "else\n"
    "    apppath=\"$appname\"\n"
    "fi\n"
    "\n"
    "# determine the WINELOADER\n"
    "if [ ! -x \"$WINELOADER\" ]; then WINELOADER=\"wine\"; fi\n"
    "\n"
    "# and try to start the app\n"
    "exec \"$WINELOADER\" \"$apppath\" \"$@\"\n"
;

static int keep_generated = 0;
static strarray* tmp_files;
#ifdef HAVE_SIGSET_T
static sigset_t signal_mask;
#endif

enum processor { proc_cc, proc_cxx, proc_cpp, proc_as };

static const struct
{
    const char *name;
    enum target_cpu cpu;
} cpu_names[] =
{
    { "i386",    CPU_x86 },
    { "i486",    CPU_x86 },
    { "i586",    CPU_x86 },
    { "i686",    CPU_x86 },
    { "i786",    CPU_x86 },
    { "amd64",   CPU_x86_64 },
    { "x86_64",  CPU_x86_64 },
    { "powerpc", CPU_POWERPC },
    { "arm",     CPU_ARM },
    { "aarch64", CPU_ARM64 }
};

static const struct
{
    const char *name;
    enum target_platform platform;
} platform_names[] =
{
    { "macos",   PLATFORM_APPLE },
    { "darwin",  PLATFORM_APPLE },
    { "android", PLATFORM_ANDROID },
    { "solaris", PLATFORM_SOLARIS },
    { "cygwin",  PLATFORM_CYGWIN },
    { "mingw32", PLATFORM_WINDOWS },
    { "windows", PLATFORM_WINDOWS },
    { "winnt",   PLATFORM_WINDOWS }
};

struct options
{
    enum processor processor;
    enum target_cpu target_cpu;
    enum target_platform target_platform;
    const char *target;
    const char *version;
    int shared;
    int use_msvcrt;
    int nostdinc;
    int nostdlib;
    int nostartfiles;
    int nodefaultlibs;
    int noshortwchar;
    int gui_app;
    int unicode_app;
    int win16_app;
    int compile_only;
    int force_pointer_size;
    int large_address_aware;
    int unwind_tables;
    int strip;
    const char* wine_objdir;
    const char* output_name;
    const char* image_base;
    const char* section_align;
    const char* lib_suffix;
    strarray* prefix;
    strarray* lib_dirs;
    strarray* linker_args;
    strarray* compiler_args;
    strarray* winebuild_args;
    strarray* files;
};

#ifdef __i386__
static const enum target_cpu build_cpu = CPU_x86;
#elif defined(__x86_64__)
static const enum target_cpu build_cpu = CPU_x86_64;
#elif defined(__powerpc__)
static const enum target_cpu build_cpu = CPU_POWERPC;
#elif defined(__arm__)
static const enum target_cpu build_cpu = CPU_ARM;
#elif defined(__aarch64__)
static const enum target_cpu build_cpu = CPU_ARM64;
#else
#error Unsupported CPU
#endif

#ifdef __APPLE__
static enum target_platform build_platform = PLATFORM_APPLE;
#elif defined(__ANDROID__)
static enum target_platform build_platform = PLATFORM_ANDROID;
#elif defined(__sun)
static enum target_platform build_platform = PLATFORM_SOLARIS;
#elif defined(__CYGWIN__)
static enum target_platform build_platform = PLATFORM_CYGWIN;
#elif defined(_WIN32)
static enum target_platform build_platform = PLATFORM_WINDOWS;
#else
static enum target_platform build_platform = PLATFORM_UNSPECIFIED;
#endif

static void clean_temp_files(void)
{
    unsigned int i;

    if (keep_generated) return;

    for (i = 0; i < tmp_files->size; i++)
	unlink(tmp_files->base[i]);
}

/* clean things up when aborting on a signal */
static void exit_on_signal( int sig )
{
    exit(1);  /* this will call the atexit functions */
}

static char* get_temp_file(const char* prefix, const char* suffix)
{
    int fd;
    char* tmp = strmake("%s-XXXXXX%s", prefix, suffix);

#ifdef HAVE_SIGPROCMASK
    sigset_t old_set;
    /* block signals while manipulating the temp files list */
    sigprocmask( SIG_BLOCK, &signal_mask, &old_set );
#endif
    fd = mkstemps( tmp, strlen(suffix) );
    if (fd == -1)
    {
        /* could not create it in current directory, try in TMPDIR */
        const char* tmpdir;

        free(tmp);
        if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
        tmp = strmake("%s/%s-XXXXXX%s", tmpdir, prefix, suffix);
        fd = mkstemps( tmp, strlen(suffix) );
        if (fd == -1) error( "could not create temp file\n" );
    }
    close( fd );
    strarray_add(tmp_files, tmp);
#ifdef HAVE_SIGPROCMASK
    sigprocmask( SIG_SETMASK, &old_set, NULL );
#endif
    return tmp;
}

static char* build_tool_name(struct options *opts, const char* base, const char* deflt)
{
    char* str;

    if (opts->target && opts->version)
    {
        str = strmake("%s-%s-%s", opts->target, base, opts->version);
    }
    else if (opts->target)
    {
        str = strmake("%s-%s", opts->target, base);
    }
    else if (opts->version)
    {
        str = strmake("%s-%s", base, opts->version);
    }
    else
        str = xstrdup(deflt);
    return str;
}

static const strarray* get_translator(struct options *opts)
{
    char *str = NULL;
    strarray *ret;

    switch(opts->processor)
    {
    case proc_cpp:
        str = build_tool_name(opts, "cpp", CPP);
        break;
    case proc_cc:
    case proc_as:
        str = build_tool_name(opts, "gcc", CC);
        break;
    case proc_cxx:
        str = build_tool_name(opts, "g++", CXX);
        break;
    default:
        assert(0);
    }
    ret = strarray_fromstring( str, " " );
    free(str);
    if (opts->force_pointer_size)
        strarray_add( ret, strmake("-m%u", 8 * opts->force_pointer_size ));
    return ret;
}

static int try_link( const strarray *prefix, const strarray *link_tool, const char *cflags )
{
    const char *in = get_temp_file( "try_link", ".c" );
    const char *out = get_temp_file( "try_link", ".out" );
    const char *err = get_temp_file( "try_link", ".err" );
    strarray *link = strarray_dup( link_tool );
    int sout = -1, serr = -1;
    int ret;

    create_file( in, 0644, "int main(void){return 1;}\n" );

    strarray_add( link, "-o" );
    strarray_add( link, out );
    strarray_addall( link, strarray_fromstring( cflags, " " ) );
    strarray_add( link, in );

    sout = dup( fileno(stdout) );
    freopen( err, "w", stdout );
    serr = dup( fileno(stderr) );
    freopen( err, "w", stderr );
    ret = spawn( prefix, link, 1 );
    if (sout >= 0)
    {
        dup2( sout, fileno(stdout) );
        close( sout );
    }
    if (serr >= 0)
    {
        dup2( serr, fileno(stderr) );
        close( serr );
    }
    strarray_free( link );
    return ret;
}

static const strarray* get_lddllflags( const struct options *opts, const strarray *link_tool )
{
    strarray *flags = strarray_alloc();
    switch (opts->target_platform)
    {
    case PLATFORM_APPLE:
        strarray_add( flags, "-bundle" );
        strarray_add( flags, "-multiply_defined" );
        strarray_add( flags, "suppress" );
        if (opts->target_cpu == CPU_POWERPC)
        {
            strarray_add( flags, "-read_only_relocs" );
            strarray_add( flags, "warning" );
        }
        break;

    case PLATFORM_ANDROID:
    case PLATFORM_SOLARIS:
    case PLATFORM_UNSPECIFIED:
        strarray_add( flags, "-shared" );
        strarray_add( flags, "-Wl,-Bsymbolic" );

        /* Try all options first - this is likely to succeed on modern compilers */
        if (!try_link( opts->prefix, link_tool, "-fPIC -shared -Wl,-Bsymbolic "
                       "-Wl,-z,defs -Wl,-init,__wine_spec_init,-fini,_wine_spec_fini" ))
        {
            strarray_add( flags, "-Wl,-z,defs" );
            strarray_add( flags, "-Wl,-init,__wine_spec_init,-fini,__wine_spec_fini" );
        }
        else /* otherwise figure out which ones are allowed */
        {
            if (!try_link( opts->prefix, link_tool, "-fPIC -shared -Wl,-Bsymbolic -Wl,-z,defs" ))
                strarray_add( flags, "-Wl,-z,defs" );
            if (!try_link( opts->prefix, link_tool, "-fPIC -shared -Wl,-Bsymbolic "
                           "-Wl,-init,__wine_spec_init,-fini,_wine_spec_fini" ))
                strarray_add( flags, "-Wl,-init,__wine_spec_init,-fini,__wine_spec_fini" );
        }
        break;

    default:
        assert(0);
    }
    return flags;
}

/* check that file is a library for the correct platform */
static int check_platform( struct options *opts, const char *file )
{
    int ret = 0, fd = open( file, O_RDONLY );
    if (fd != -1)
    {
        unsigned char header[16];
        if (read( fd, header, sizeof(header) ) == sizeof(header))
        {
            /* FIXME: only ELF is supported, platform is not checked beyond 32/64 */
            if (!memcmp( header, "\177ELF", 4 ))
            {
                if (header[4] == 2)  /* 64-bit */
                    ret = (opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64);
                else
                    ret = (opts->target_cpu != CPU_x86_64 && opts->target_cpu != CPU_ARM64);
            }
        }
        close( fd );
    }
    return ret;
}

static char *get_lib_dir( struct options *opts )
{
    static const char *stdlibpath[] = { LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
    static const char libwine[] = "/libwine.so";
    unsigned int i;

    for (i = 0; i < sizeof(stdlibpath)/sizeof(stdlibpath[0]); i++)
    {
        char *p, *buffer = xmalloc( strlen(stdlibpath[i]) + strlen("/arm-linux-gnueabi") + strlen(libwine) + 1 );
        strcpy( buffer, stdlibpath[i] );
        p = buffer + strlen(buffer);
        while (p > buffer && p[-1] == '/') p--;
        strcpy( p, libwine );
        if (check_platform( opts, buffer )) goto found;
        if (p > buffer + 2 && (!memcmp( p - 2, "32", 2 ) || !memcmp( p - 2, "64", 2 ))) p -= 2;
        if (opts->target_cpu != CPU_x86_64 && opts->target_cpu != CPU_ARM64)
        {
            strcpy( p, "32" );
            strcat( p, libwine );
            if (check_platform( opts, buffer )) goto found;
        }
        if (opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64)
        {
            strcpy( p, "64" );
            strcat( p, libwine );
            if (check_platform( opts, buffer )) goto found;
        }
        switch(opts->target_cpu)
        {
        case CPU_x86:     strcpy( p, "/i386-linux-gnu" ); break;
        case CPU_x86_64:  strcpy( p, "/x86_64-linux-gnu" ); break;
        case CPU_ARM:     strcpy( p, "/arm-linux-gnueabi" ); break;
        case CPU_ARM64:   strcpy( p, "/aarch64-linux-gnu" ); break;
        case CPU_POWERPC: strcpy( p, "/powerpc-linux-gnu" ); break;
        default:
            assert(0);
        }
        strcat( p, libwine );
        if (check_platform( opts, buffer )) goto found;
        free( buffer );
        continue;

    found:
        buffer[strlen(buffer) - strlen(libwine)] = 0;
        return buffer;
    }
    return xstrdup( LIBDIR );
}

static void compile(struct options* opts, const char* lang)
{
    strarray* comp_args = strarray_alloc();
    unsigned int i, j;
    int gcc_defs = 0;
    strarray* gcc;
    strarray* gpp;

    strarray_addall(comp_args, get_translator(opts));
    switch(opts->processor)
    {
	case proc_cpp: gcc_defs = 1; break;
	case proc_as:  gcc_defs = 0; break;
	/* Note: if the C compiler is gcc we assume the C++ compiler is too */
	/* mixing different C and C++ compilers isn't supported in configure anyway */
	case proc_cc:
	case proc_cxx:
            gcc = strarray_fromstring(build_tool_name(opts, "gcc", CC), " ");
            gpp = strarray_fromstring(build_tool_name(opts, "g++", CXX), " ");
            for ( j = 0; !gcc_defs && j < comp_args->size; j++ )
            {
                const char *cc = comp_args->base[j];

                for (i = 0; !gcc_defs && i < gcc->size; i++)
                    gcc_defs = gcc->base[i][0] != '-' && strendswith(cc, gcc->base[i]);
                for (i = 0; !gcc_defs && i < gpp->size; i++)
                    gcc_defs = gpp->base[i][0] != '-' && strendswith(cc, gpp->base[i]);
            }
            strarray_free(gcc);
            strarray_free(gpp);
            break;
    }

    if (opts->target_platform == PLATFORM_WINDOWS || opts->target_platform == PLATFORM_CYGWIN)
        goto no_compat_defines;

    if (opts->processor != proc_cpp)
    {
	if (gcc_defs && !opts->wine_objdir && !opts->noshortwchar)
	{
            strarray_add(comp_args, "-fshort-wchar");
            strarray_add(comp_args, "-DWINE_UNICODE_NATIVE");
	}
        strarray_add(comp_args, "-D_REENTRANT");
        strarray_add(comp_args, "-fPIC");
    }

    if (opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64)
    {
        strarray_add(comp_args, "-DWIN64");
        strarray_add(comp_args, "-D_WIN64");
        strarray_add(comp_args, "-D__WIN64");
        strarray_add(comp_args, "-D__WIN64__");
    }

    strarray_add(comp_args, "-DWIN32");
    strarray_add(comp_args, "-D_WIN32");
    strarray_add(comp_args, "-D__WIN32");
    strarray_add(comp_args, "-D__WIN32__");
    strarray_add(comp_args, "-D__WINNT");
    strarray_add(comp_args, "-D__WINNT__");

    if (gcc_defs)
    {
        switch (opts->target_cpu)
        {
        case CPU_x86_64:
            strarray_add(comp_args, "-D__stdcall=__attribute__((ms_abi))");
            strarray_add(comp_args, "-D__cdecl=__attribute__((ms_abi))");
            strarray_add(comp_args, "-D_stdcall=__attribute__((ms_abi))");
            strarray_add(comp_args, "-D_cdecl=__attribute__((ms_abi))");
            strarray_add(comp_args, "-D__fastcall=__attribute__((ms_abi))");
            strarray_add(comp_args, "-D_fastcall=__attribute__((ms_abi))");
            break;
        case CPU_x86:
            strarray_add(comp_args, "-D__stdcall=__attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__))");
            strarray_add(comp_args, "-D__cdecl=__attribute__((__cdecl__)) __attribute__((__force_align_arg_pointer__))");
            strarray_add(comp_args, "-D_stdcall=__attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__))");
            strarray_add(comp_args, "-D_cdecl=__attribute__((__cdecl__)) __attribute__((__force_align_arg_pointer__))");
            strarray_add(comp_args, "-D__fastcall=__attribute__((__fastcall__))");
            strarray_add(comp_args, "-D_fastcall=__attribute__((__fastcall__))");
            break;
        case CPU_ARM:
        case CPU_ARM64:
        case CPU_POWERPC:
            strarray_add(comp_args, "-D__stdcall=");
            strarray_add(comp_args, "-D__cdecl=");
            strarray_add(comp_args, "-D_stdcall=");
            strarray_add(comp_args, "-D_cdecl=");
            strarray_add(comp_args, "-D__fastcall=");
            strarray_add(comp_args, "-D_fastcall=");
            break;
        }
	strarray_add(comp_args, "-D__declspec(x)=__declspec_##x");
	strarray_add(comp_args, "-D__declspec_align(x)=__attribute__((aligned(x)))");
	strarray_add(comp_args, "-D__declspec_allocate(x)=__attribute__((section(x)))");
	strarray_add(comp_args, "-D__declspec_deprecated=__attribute__((deprecated))");
	strarray_add(comp_args, "-D__declspec_dllimport=__attribute__((dllimport))");
	strarray_add(comp_args, "-D__declspec_dllexport=__attribute__((dllexport))");
	strarray_add(comp_args, "-D__declspec_naked=__attribute__((naked))");
	strarray_add(comp_args, "-D__declspec_noinline=__attribute__((noinline))");
	strarray_add(comp_args, "-D__declspec_noreturn=__attribute__((noreturn))");
	strarray_add(comp_args, "-D__declspec_nothrow=__attribute__((nothrow))");
	strarray_add(comp_args, "-D__declspec_novtable=__attribute__(())"); /* ignore it */
	strarray_add(comp_args, "-D__declspec_selectany=__attribute__((weak))");
	strarray_add(comp_args, "-D__declspec_thread=__thread");
    }

    strarray_add(comp_args, "-D__int8=char");
    strarray_add(comp_args, "-D__int16=short");
    strarray_add(comp_args, "-D__int32=int");
    if (opts->target_cpu == CPU_x86_64 || opts->target_cpu == CPU_ARM64)
        strarray_add(comp_args, "-D__int64=long");
    else
        strarray_add(comp_args, "-D__int64=long long");

no_compat_defines:
    strarray_add(comp_args, "-D__WINE__");

    /* options we handle explicitly */
    if (opts->compile_only)
	strarray_add(comp_args, "-c");
    if (opts->output_name)
    {
	strarray_add(comp_args, "-o");
	strarray_add(comp_args, opts->output_name);
    }

    /* the rest of the pass-through parameters */
    for ( j = 0 ; j < opts->compiler_args->size ; j++ ) 
        strarray_add(comp_args, opts->compiler_args->base[j]);

    /* the language option, if any */
    if (lang && strcmp(lang, "-xnone"))
	strarray_add(comp_args, lang);

    /* last, but not least, the files */
    for ( j = 0; j < opts->files->size; j++ )
    {
	if (opts->files->base[j][0] != '-')
	    strarray_add(comp_args, opts->files->base[j]);
    }

    /* standard includes come last in the include search path */
    if (!opts->wine_objdir && !opts->nostdinc)
    {
        if (opts->use_msvcrt)
        {
            strarray_add(comp_args, gcc_defs ? "-isystem" INCLUDEDIR "/msvcrt" : "-I" INCLUDEDIR "/msvcrt" );
            strarray_add(comp_args, "-D__MSVCRT__");
        }
        strarray_add(comp_args, gcc_defs ? "-isystem" INCLUDEDIR "/windows" : "-I" INCLUDEDIR "/windows" );
    }
    else if (opts->wine_objdir)
        strarray_add(comp_args, strmake("-I%s/include", opts->wine_objdir) );

    spawn(opts->prefix, comp_args, 0);
    strarray_free(comp_args);
}

static const char* compile_to_object(struct options* opts, const char* file, const char* lang)
{
    struct options copts;
    char* base_name;

    /* make a copy so we don't change any of the initial stuff */
    /* a shallow copy is exactly what we want in this case */
    base_name = get_basename(file);
    copts = *opts;
    copts.output_name = get_temp_file(base_name, ".o");
    copts.compile_only = 1;
    copts.files = strarray_alloc();
    strarray_add(copts.files, file);
    compile(&copts, lang);
    strarray_free(copts.files);
    free(base_name);

    return copts.output_name;
}

/* return the initial set of options needed to run winebuild */
static strarray *get_winebuild_args(struct options *opts)
{
    const char* winebuild = getenv("WINEBUILD");
    strarray *spec_args = strarray_alloc();

    if (!winebuild) winebuild = "winebuild";
    strarray_add( spec_args, winebuild );
    if (verbose) strarray_add( spec_args, "-v" );
    if (keep_generated) strarray_add( spec_args, "--save-temps" );
    if (opts->target)
    {
        strarray_add( spec_args, "--target" );
        strarray_add( spec_args, opts->target );
    }
    if (opts->unwind_tables) strarray_add( spec_args, "-fasynchronous-unwind-tables" );
    else strarray_add( spec_args, "-fno-asynchronous-unwind-tables" );
    return spec_args;
}

static const char* compile_resources_to_object(struct options* opts, const strarray *resources,
                                               const char *res_o_name)
{
    strarray *winebuild_args = get_winebuild_args( opts );

    strarray_add( winebuild_args, "--resources" );
    strarray_add( winebuild_args, "-o" );
    strarray_add( winebuild_args, res_o_name );
    strarray_addall( winebuild_args, resources );

    spawn( opts->prefix, winebuild_args, 0 );
    strarray_free( winebuild_args );
    return res_o_name;
}

/* check if there is a static lib associated to a given dll */
static char *find_static_lib( const char *dll )
{
    char *lib = strmake("%s.a", dll);
    if (get_file_type(lib) == file_arh) return lib;
    free( lib );
    return NULL;
}

/* add specified library to the list of files */
static void add_library( struct options *opts, strarray *lib_dirs, strarray *files, const char *library )
{
    char *static_lib, *fullname = 0;

    switch(get_lib_type(opts->target_platform, lib_dirs, library, opts->lib_suffix, &fullname))
    {
    case file_arh:
        strarray_add(files, strmake("-a%s", fullname));
        break;
    case file_dll:
        strarray_add(files, strmake("-d%s", fullname));
        if ((static_lib = find_static_lib(fullname)))
        {
            strarray_add(files, strmake("-a%s",static_lib));
            free(static_lib);
        }
        break;
    case file_so:
    default:
        /* keep it anyway, the linker may know what to do with it */
        strarray_add(files, strmake("-l%s", library));
        break;
    }
    free(fullname);
}

/* hack a main or WinMain function to work around Mingw's lack of Unicode support */
static const char *mingw_unicode_hack( struct options *opts )
{
    char *main_stub = get_temp_file( opts->output_name, ".c" );

    create_file( main_stub, 0644,
                 "typedef unsigned short wchar_t;\n"
                 "extern void * __stdcall LoadLibraryA(const char *);\n"
                 "extern void * __stdcall GetProcAddress(void *,const char *);\n"
                 "extern int wmain( int argc, wchar_t *argv[] );\n\n"
                 "int main( int argc, char *argv[] )\n{\n"
                 "    int wargc;\n"
                 "    wchar_t **wargv, **wenv;\n"
                 "    void *msvcrt = LoadLibraryA( \"msvcrt.dll\" );\n"
                 "    void (*__wgetmainargs)(int *argc, wchar_t** *wargv, wchar_t** *wenvp, int expand_wildcards,\n"
                 "                           int *new_mode) = GetProcAddress( msvcrt, \"__wgetmainargs\" );\n"
                 "    __wgetmainargs( &wargc, &wargv, &wenv, 0, 0 );\n"
                 "    return wmain( wargc, wargv );\n}\n" );
    return compile_to_object( opts, main_stub, NULL );
}

static void build(struct options* opts)
{
    strarray *lib_dirs, *files;
    strarray *spec_args, *link_args;
    char *output_file;
    const char *spec_o_name;
    const char *output_name, *spec_file, *lang;
    const char *prelink = NULL;
    int generate_app_loader = 1;
    int fake_module = 0;
    unsigned int j;

    /* NOTE: for the files array we'll use the following convention:
     *    -axxx:  xxx is an archive (.a)
     *    -dxxx:  xxx is a DLL (.def)
     *    -lxxx:  xxx is an unsorted library
     *    -oxxx:  xxx is an object (.o)
     *    -rxxx:  xxx is a resource (.res)
     *    -sxxx:  xxx is a shared lib (.so)
     *    -xlll:  lll is the language (c, c++, etc.)
     */

    output_file = strdup( opts->output_name ? opts->output_name : "a.out" );

    /* 'winegcc -o app xxx.exe.so' only creates the load script */
    if (opts->files->size == 1 && strendswith(opts->files->base[0], ".exe.so"))
    {
	create_file(output_file, 0755, app_loader_template, opts->files->base[0]);
	return;
    }

    /* generate app loader only for .exe */
    if (opts->shared || strendswith(output_file, ".so"))
	generate_app_loader = 0;

    if (strendswith(output_file, ".fake")) fake_module = 1;

    /* normalize the filename a bit: strip .so, ensure it has proper ext */
    if (strendswith(output_file, ".so")) 
	output_file[strlen(output_file) - 3] = 0;
    if ((output_name = strrchr(output_file, '/'))) output_name++;
    else output_name = output_file;
    if (!strchr(output_name, '.'))
        output_file = strmake("%s.%s", output_file, opts->shared ? "dll" : "exe");

    /* get the filename from the path */
    if ((output_name = strrchr(output_file, '/'))) output_name++;
    else output_name = output_file;

    /* prepare the linking path */
    if (!opts->wine_objdir)
    {
        char *lib_dir = get_lib_dir( opts );
        lib_dirs = strarray_dup(opts->lib_dirs);
        strarray_add( lib_dirs, strmake( "%s/wine", lib_dir ));
        strarray_add( lib_dirs, lib_dir );
    }
    else
    {
        lib_dirs = strarray_alloc();
        strarray_add(lib_dirs, strmake("%s/dlls", opts->wine_objdir));
        strarray_add(lib_dirs, strmake("%s/libs/wine", opts->wine_objdir));
        strarray_addall(lib_dirs, opts->lib_dirs);
    }

    /* mark the files with their appropriate type */
    spec_file = lang = 0;
    files = strarray_alloc();
    link_args = strarray_alloc();
    for ( j = 0; j < opts->files->size; j++ )
    {
	const char* file = opts->files->base[j];
	if (file[0] != '-')
	{
	    switch(get_file_type(file))
	    {
		case file_def:
		case file_spec:
		    if (spec_file)
			error("Only one spec file can be specified\n");
		    spec_file = file;
		    break;
		case file_rc:
		    /* FIXME: invoke wrc to build it */
		    error("Can't compile .rc file at the moment: %s\n", file);
	            break;
	    	case file_res:
		    strarray_add(files, strmake("-r%s", file));
		    break;
		case file_obj:
		    strarray_add(files, strmake("-o%s", file));
		    break;
		case file_arh:
		    strarray_add(files, strmake("-a%s", file));
		    break;
		case file_so:
		    strarray_add(files, strmake("-s%s", file));
		    break;
	    	case file_na:
		    error("File does not exist: %s\n", file);
		    break;
	        default:
		    file = compile_to_object(opts, file, lang);
		    strarray_add(files, strmake("-o%s", file));
		    break;
	    }
	}
	else if (file[1] == 'l')
            add_library(opts, lib_dirs, files, file + 2 );
	else if (file[1] == 'x')
	    lang = file;
    }

    /* building for Windows is completely different */

    if (opts->target_platform == PLATFORM_WINDOWS || opts->target_platform == PLATFORM_CYGWIN)
    {
        strarray *resources = strarray_alloc();
        char *res_o_name = NULL;

        if (opts->win16_app)
            error( "Building 16-bit code is not supported for Windows\n" );

        strarray_addall(link_args, get_translator(opts));

        if (opts->shared)
        {
            /* run winebuild to generate the .def file */
            char *spec_def_name = get_temp_file(output_name, ".spec.def");
            spec_args = get_winebuild_args( opts );
            strarray_add(spec_args, "--def");
            strarray_add(spec_args, "-o");
            strarray_add(spec_args, spec_def_name);
            if (spec_file)
            {
                strarray_add(spec_args, "--export");
                strarray_add(spec_args, spec_file);
            }
            spawn(opts->prefix, spec_args, 0);
            strarray_free(spec_args);

            strarray_add(link_args, "-shared");
            if (verbose) strarray_add(link_args, "-v");
            strarray_add(link_args, "-Wl,--kill-at");
            strarray_add(link_args, spec_def_name);
        }
        else
        {
            strarray_add(link_args, opts->gui_app ? "-mwindows" : "-mconsole");
            if (opts->nodefaultlibs) strarray_add(link_args, "-nodefaultlibs");
        }

        for ( j = 0 ; j < opts->linker_args->size ; j++ )
            strarray_add(link_args, opts->linker_args->base[j]);

        strarray_add(link_args, "-o");
        strarray_add(link_args, output_file);

        if (opts->image_base)
            strarray_add(link_args, strmake("-Wl,--image-base,%s", opts->image_base));

        if (opts->large_address_aware && opts->target_cpu == CPU_x86)
            strarray_add( link_args, "-Wl,--large-address-aware" );

        if (opts->unicode_app && !opts->shared)
            strarray_add(link_args, mingw_unicode_hack(opts));

        for ( j = 0; j < lib_dirs->size; j++ )
            strarray_add(link_args, strmake("-L%s", lib_dirs->base[j]));

        if (!opts->nodefaultlibs)
        {
            add_library(opts, lib_dirs, files, "winecrt0");
            add_library(opts, lib_dirs, files, "kernel32");
            add_library(opts, lib_dirs, files, "ntdll");
        }
        if (!opts->shared && opts->use_msvcrt && opts->target_platform == PLATFORM_CYGWIN)
            add_library(opts, lib_dirs, files, "msvcrt");

        for ( j = 0; j < files->size; j++ )
        {
            const char* name = files->base[j] + 2;

            switch(files->base[j][1])
            {
            case 'l':
            case 'd':
                strarray_add(link_args, strmake("-l%s", name));
                break;
            case 's':
            case 'o':
                strarray_add(link_args, name);
                break;
            case 'a':
                if (strchr(name, '/'))
                {
                    /* turn the path back into -Ldir -lfoo options
                     * this makes sure that we use the specified libs even
                     * when mingw adds its own import libs to the link */
                    char *lib = xstrdup( name );
                    char *p = strrchr( lib, '/' );

                    *p++ = 0;
                    if (!strncmp( p, "lib", 3 ))
                    {
                        char *ext = strrchr( p, '.' );

                        if (ext) *ext = 0;
                        p += 3;
                        strarray_add(link_args, strmake("-L%s", lib ));
                        strarray_add(link_args, strmake("-l%s", p ));
                        free( lib );
                        break;
                    }
                    free( lib );
                }
                strarray_add(link_args, name);
                break;
            case 'r':
                if (!res_o_name)
                {
                    res_o_name = get_temp_file( output_name, ".res.o" );
                    strarray_add( link_args, res_o_name );
                }
                strarray_add( resources, name );
                break;
            }
        }

        if (res_o_name) compile_resources_to_object( opts, resources, res_o_name );

        spawn(opts->prefix, link_args, 0);
        strarray_free (resources);
        strarray_free (link_args);
        strarray_free (lib_dirs);
        strarray_free (files);
        return;
    }

    /* add the default libraries, if needed */
    if (!opts->nostdlib && opts->use_msvcrt) add_library(opts, lib_dirs, files, "msvcrt");

    if (!opts->wine_objdir && !opts->nodefaultlibs) 
    {
        if (opts->gui_app) 
	{
	    add_library(opts, lib_dirs, files, "shell32");
	    add_library(opts, lib_dirs, files, "comdlg32");
	    add_library(opts, lib_dirs, files, "gdi32");
	}
        add_library(opts, lib_dirs, files, "advapi32");
        add_library(opts, lib_dirs, files, "user32");
    }

    if (!opts->nodefaultlibs)
    {
        add_library(opts, lib_dirs, files, "winecrt0");
        if (opts->win16_app) add_library(opts, lib_dirs, files, "kernel");
        add_library(opts, lib_dirs, files, "kernel32");
        add_library(opts, lib_dirs, files, "ntdll");
    }
    if (!opts->nostdlib) add_library(opts, lib_dirs, files, "wine");

    /* run winebuild to generate the .spec.o file */
    spec_args = get_winebuild_args( opts );
    strarray_add( spec_args, strmake( "--cc-cmd=%s", build_tool_name( opts, "gcc", CC )));
    strarray_add( spec_args, strmake( "--ld-cmd=%s", build_tool_name( opts, "ld", LD )));

    spec_o_name = get_temp_file(output_name, ".spec.o");
    if (opts->force_pointer_size)
        strarray_add(spec_args, strmake("-m%u", 8 * opts->force_pointer_size ));
    strarray_add(spec_args, "-D_REENTRANT");
    strarray_add(spec_args, "-fPIC");
    strarray_add(spec_args, opts->shared ? "--dll" : "--exe");
    if (fake_module)
    {
        strarray_add(spec_args, "--fake-module");
        strarray_add(spec_args, "-o");
        strarray_add(spec_args, output_file);
    }
    else
    {
        strarray_add(spec_args, "-o");
        strarray_add(spec_args, spec_o_name);
    }
    if (spec_file)
    {
        strarray_add(spec_args, "-E");
        strarray_add(spec_args, spec_file);
    }
    if (opts->win16_app) strarray_add(spec_args, "-m16");

    if (!opts->shared)
    {
        strarray_add(spec_args, "-F");
        strarray_add(spec_args, output_name);
        strarray_add(spec_args, "--subsystem");
        strarray_add(spec_args, opts->gui_app ? "windows" : "console");
        if (opts->unicode_app)
        {
            strarray_add(spec_args, "--entry");
            strarray_add(spec_args, "__wine_spec_exe_wentry");
        }
        if (opts->large_address_aware) strarray_add( spec_args, "--large-address-aware" );
    }

    for ( j = 0; j < lib_dirs->size; j++ )
	strarray_add(spec_args, strmake("-L%s", lib_dirs->base[j]));

    for ( j = 0 ; j < opts->winebuild_args->size ; j++ )
        strarray_add(spec_args, opts->winebuild_args->base[j]);

    /* add resource files */
    for ( j = 0; j < files->size; j++ )
	if (files->base[j][1] == 'r') strarray_add(spec_args, files->base[j]);

    /* add other files */
    strarray_add(spec_args, "--");
    for ( j = 0; j < files->size; j++ )
    {
	switch(files->base[j][1])
	{
	    case 'd':
	    case 'a':
	    case 'o':
		strarray_add(spec_args, files->base[j] + 2);
		break;
	}
    }

    spawn(opts->prefix, spec_args, 0);
    strarray_free (spec_args);
    if (fake_module) return;  /* nothing else to do */

    /* link everything together now */
    strarray_addall(link_args, get_translator(opts));
    strarray_addall(link_args, get_lddllflags(opts, link_args));

    strarray_add(link_args, "-o");
    strarray_add(link_args, strmake("%s.so", output_file));

    for ( j = 0 ; j < opts->linker_args->size ; j++ ) 
        strarray_add(link_args, opts->linker_args->base[j]);

    switch (opts->target_platform)
    {
    case PLATFORM_APPLE:
        if (opts->image_base)
        {
            strarray_add(link_args, "-image_base");
            strarray_add(link_args, opts->image_base);
        }
        if (opts->strip)
            strarray_add(link_args, "-Wl,-x");
        break;
    case PLATFORM_SOLARIS:
        {
            char *mapfile = get_temp_file( output_name, ".map" );
            const char *align = opts->section_align ? opts->section_align : "0x1000";

            create_file( mapfile, 0644, "text = A%s;\ndata = A%s;\n", align, align );
            strarray_add(link_args, strmake("-Wl,-M,%s", mapfile));
            strarray_add(tmp_files, mapfile);
        }
        break;
    case PLATFORM_ANDROID:
        /* not supported on Android */
        break;
    default:
        if (opts->image_base)
        {
            if (!try_link(opts->prefix, link_args, strmake("-Wl,-Ttext-segment=%s", opts->image_base)))
                strarray_add(link_args, strmake("-Wl,-Ttext-segment=%s", opts->image_base));
            else
                prelink = PRELINK;
        }
        break;
    }

    for ( j = 0; j < lib_dirs->size; j++ )
	strarray_add(link_args, strmake("-L%s", lib_dirs->base[j]));

    strarray_add(link_args, spec_o_name);

    for ( j = 0; j < files->size; j++ )
    {
	const char* name = files->base[j] + 2;
	switch(files->base[j][1])
	{
	    case 'l':
		strarray_add(link_args, strmake("-l%s", name));
		break;
	    case 's':
	    case 'a':
	    case 'o':
		strarray_add(link_args, name);
		break;
	}
    }

    if (!opts->nostdlib) 
    {
	strarray_add(link_args, "-lm");
	strarray_add(link_args, "-lc");
    }

    spawn(opts->prefix, link_args, 0);
    strarray_free (link_args);

    /* set the base address with prelink if linker support is not present */
    if (prelink && !opts->target)
    {
        if (prelink[0] && strcmp(prelink,"false"))
        {
            strarray *prelink_args = strarray_alloc();
            strarray_add(prelink_args, prelink);
            strarray_add(prelink_args, "--reloc-only");
            strarray_add(prelink_args, opts->image_base);
            strarray_add(prelink_args, strmake("%s.so", output_file));
            spawn(opts->prefix, prelink_args, 1);
            strarray_free(prelink_args);
        }
    }

    /* create the loader script */
    if (generate_app_loader)
        create_file(output_file, 0755, app_loader_template, strmake("%s.so", output_name));
}


static void forward(int argc, char **argv, struct options* opts)
{
    strarray* args = strarray_alloc();
    int j;

    strarray_addall(args, get_translator(opts));

    for( j = 1; j < argc; j++ ) 
	strarray_add(args, argv[j]);

    spawn(opts->prefix, args, 0);
    strarray_free (args);
}

/*
 *      Linker Options
 *          object-file-name  -llibrary -nostartfiles  -nodefaultlibs
 *          -nostdlib -s  -static  -static-libgcc  -shared  -shared-libgcc
 *          -symbolic -Wl,option  -Xlinker option -u symbol
 *	    -framework name
 */
static int is_linker_arg(const char* arg)
{
    static const char* link_switches[] = 
    {
	"-nostartfiles", "-nostdlib", "-s",
	"-static", "-static-libgcc", "-shared", "-shared-libgcc", "-symbolic",
	"-framework", "--coverage", "-fprofile-generate", "-fprofile-use"
    };
    unsigned int j;

    switch (arg[1]) 
    {
	case 'R':
	case 'z':
	case 'l':
	case 'u':
	    return 1;
        case 'W':
            if (strncmp("-Wl,", arg, 4) == 0) return 1;
	    break;
	case 'X':
	    if (strcmp("-Xlinker", arg) == 0) return 1;
	    break;
	case 'a':
	    if (strcmp("-arch", arg) == 0) return 1;
	    break;
    }

    for (j = 0; j < sizeof(link_switches)/sizeof(link_switches[0]); j++)
	if (strcmp(link_switches[j], arg) == 0) return 1;

    return 0;
}

/*
 *      Target Options
 *          -b machine  -V version
 */
static int is_target_arg(const char* arg)
{
    return arg[1] == 'b' || arg[1] == 'V';
}


/*
 *      Directory Options
 *          -Bprefix  -Idir  -I-  -Ldir  -specs=file
 */
static int is_directory_arg(const char* arg)
{
    return arg[1] == 'B' || arg[1] == 'L' || arg[1] == 'I' || strncmp("-specs=", arg, 7) == 0;
}

/*
 *      MinGW Options
 *	    -mno-cygwin -mwindows -mconsole -mthreads -municode
 */ 
static int is_mingw_arg(const char* arg)
{
    static const char* mingw_switches[] = 
    {
        "-mno-cygwin", "-mwindows", "-mconsole", "-mthreads", "-municode"
    };
    unsigned int j;

    for (j = 0; j < sizeof(mingw_switches)/sizeof(mingw_switches[0]); j++)
	if (strcmp(mingw_switches[j], arg) == 0) return 1;

    return 0;
}

static void parse_target_option( struct options *opts, const char *target )
{
    char *p, *platform, *spec = xstrdup( target );
    unsigned int i;

    /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */

    /* get the CPU part */

    if ((p = strchr( spec, '-' )))
    {
        *p++ = 0;
        for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
        {
            if (!strcmp( cpu_names[i].name, spec ))
            {
                opts->target_cpu = cpu_names[i].cpu;
                break;
            }
        }
        if (i == sizeof(cpu_names)/sizeof(cpu_names[0]))
            error( "Unrecognized CPU '%s'\n", spec );
        platform = p;
        if ((p = strrchr( p, '-' ))) platform = p + 1;
    }
    else if (!strcmp( spec, "mingw32" ))
    {
        opts->target_cpu = CPU_x86;
        platform = spec;
    }
    else
        error( "Invalid target specification '%s'\n", target );

    /* get the OS part */

    opts->target_platform = PLATFORM_UNSPECIFIED;  /* default value */
    for (i = 0; i < sizeof(platform_names)/sizeof(platform_names[0]); i++)
    {
        if (!strncmp( platform_names[i].name, platform, strlen(platform_names[i].name) ))
        {
            opts->target_platform = platform_names[i].platform;
            break;
        }
    }

    free( spec );
    opts->target = xstrdup( target );
}

int main(int argc, char **argv)
{
    int i, c, next_is_arg = 0, linking = 1;
    int raw_compiler_arg, raw_linker_arg;
    const char* option_arg;
    struct options opts;
    char* lang = 0;
    char* str;

#ifdef SIGHUP
    signal( SIGHUP, exit_on_signal );
#endif
    signal( SIGTERM, exit_on_signal );
    signal( SIGINT, exit_on_signal );
#ifdef HAVE_SIGADDSET
    sigemptyset( &signal_mask );
    sigaddset( &signal_mask, SIGHUP );
    sigaddset( &signal_mask, SIGTERM );
    sigaddset( &signal_mask, SIGINT );
#endif

    /* setup tmp file removal at exit */
    tmp_files = strarray_alloc();
    atexit(clean_temp_files);
    
    /* initialize options */
    memset(&opts, 0, sizeof(opts));
    opts.target_cpu = build_cpu;
    opts.target_platform = build_platform;
    opts.lib_dirs = strarray_alloc();
    opts.files = strarray_alloc();
    opts.linker_args = strarray_alloc();
    opts.compiler_args = strarray_alloc();
    opts.winebuild_args = strarray_alloc();

    /* determine the processor type */
    if (strendswith(argv[0], "winecpp")) opts.processor = proc_cpp;
    else if (strendswith(argv[0], "++")) opts.processor = proc_cxx;
    
    /* parse options */
    for ( i = 1 ; i < argc ; i++ ) 
    {
        if (argv[i][0] == '-')  /* option */
	{
	    /* determine if this switch is followed by a separate argument */
	    next_is_arg = 0;
	    option_arg = 0;
	    switch(argv[i][1])
	    {
		case 'x': case 'o': case 'D': case 'U':
		case 'I': case 'A': case 'l': case 'u':
		case 'b': case 'V': case 'G': case 'L':
		case 'B': case 'R': case 'z':
		    if (argv[i][2]) option_arg = &argv[i][2];
		    else next_is_arg = 1;
		    break;
		case 'i':
		    next_is_arg = 1;
		    break;
		case 'a':
		    if (strcmp("-aux-info", argv[i]) == 0)
			next_is_arg = 1;
		    if (strcmp("-arch", argv[i]) == 0)
			next_is_arg = 1;
		    break;
		case 'X':
		    if (strcmp("-Xlinker", argv[i]) == 0)
			next_is_arg = 1;
		    break;
		case 'M':
		    c = argv[i][2];
		    if (c == 'F' || c == 'T' || c == 'Q')
		    {
			if (argv[i][3]) option_arg = &argv[i][3];
			else next_is_arg = 1;
		    }
		    break;
		case 'f':
		    if (strcmp("-framework", argv[i]) == 0)
			next_is_arg = 1;
		    break;
		case '-':
		    if (strcmp("--param", argv[i]) == 0)
			next_is_arg = 1;
		    break;
	    }
	    if (next_is_arg)
            {
                if (i + 1 >= argc) error("option -%c requires an argument\n", argv[i][1]);
                option_arg = argv[i+1];
            }

	    /* determine what options go 'as is' to the linker & the compiler */
	    raw_compiler_arg = raw_linker_arg = 0;
	    if (is_linker_arg(argv[i])) 
	    {
		raw_linker_arg = 1;
	    }
	    else 
	    {
		if (is_directory_arg(argv[i]) || is_target_arg(argv[i]))
		    raw_linker_arg = 1;
		raw_compiler_arg = !is_mingw_arg(argv[i]);
	    }

	    /* these things we handle explicitly so we don't pass them 'as is' */
	    if (argv[i][1] == 'l' || argv[i][1] == 'I' || argv[i][1] == 'L')
		raw_linker_arg = 0;
	    if (argv[i][1] == 'c' || argv[i][1] == 'L')
		raw_compiler_arg = 0;
	    if (argv[i][1] == 'o' || argv[i][1] == 'b' || argv[i][1] == 'V')
		raw_compiler_arg = raw_linker_arg = 0;

	    /* do a bit of semantic analysis */
            switch (argv[i][1]) 
	    {
		case 'B':
		    str = strdup(option_arg);
		    if (strendswith(str, "/")) str[strlen(str) - 1] = 0;
		    if (strendswith(str, "/tools/winebuild"))
                    {
                        char *objdir = strdup(str);
                        objdir[strlen(objdir) - sizeof("/tools/winebuild") + 1] = 0;
                        opts.wine_objdir = objdir;
                        /* don't pass it to the compiler, this generates warnings */
                        raw_compiler_arg = raw_linker_arg = 0;
                    }
                    if (!opts.prefix) opts.prefix = strarray_alloc();
                    strarray_add(opts.prefix, str);
		    break;
                case 'b':
                    parse_target_option( &opts, option_arg );
                    break;
                case 'V':
                    opts.version = xstrdup( option_arg );
                    break;
                case 'c':        /* compile or assemble */
		    if (argv[i][2] == 0) opts.compile_only = 1;
		    /* fall through */
                case 'S':        /* generate assembler code */
                case 'E':        /* preprocess only */
                    if (argv[i][2] == 0) linking = 0;
                    break;
		case 'f':
		    if (strcmp("-fno-short-wchar", argv[i]) == 0)
                        opts.noshortwchar = 1;
		    else if (!strcmp("-fasynchronous-unwind-tables", argv[i]))
                        opts.unwind_tables = 1;
		    else if (!strcmp("-fno-asynchronous-unwind-tables", argv[i]))
                        opts.unwind_tables = 0;
		    break;
		case 'l':
		    strarray_add(opts.files, strmake("-l%s", option_arg));
		    break;
		case 'L':
		    strarray_add(opts.lib_dirs, option_arg);
		    break;
                case 'M':        /* map file generation */
                    linking = 0;
                    break;
		case 'm':
		    if (strcmp("-mno-cygwin", argv[i]) == 0)
			opts.use_msvcrt = 1;
		    else if (strcmp("-mwindows", argv[i]) == 0)
			opts.gui_app = 1;
		    else if (strcmp("-mconsole", argv[i]) == 0)
			opts.gui_app = 0;
		    else if (strcmp("-municode", argv[i]) == 0)
			opts.unicode_app = 1;
		    else if (strcmp("-m16", argv[i]) == 0)
			opts.win16_app = 1;
		    else if (strcmp("-m32", argv[i]) == 0)
                    {
                        if (opts.target_cpu == CPU_x86_64)
                            opts.target_cpu = CPU_x86;
                        else if (opts.target_cpu == CPU_ARM64)
                            opts.target_cpu = CPU_ARM;
                        opts.force_pointer_size = 4;
			raw_linker_arg = 1;
                    }
		    else if (strcmp("-m64", argv[i]) == 0)
                    {
                        if (opts.target_cpu == CPU_x86)
                            opts.target_cpu = CPU_x86_64;
                        else if (opts.target_cpu == CPU_ARM)
                            opts.target_cpu = CPU_ARM64;
                        opts.force_pointer_size = 8;
			raw_linker_arg = 1;
                    }
                    else if (!strcmp("-marm", argv[i] ) || !strcmp("-mthumb", argv[i] ))
                    {
                        strarray_add(opts.winebuild_args, argv[i]);
			raw_linker_arg = 1;
                    }
                    else if (strncmp("-mcpu=", argv[i], 6) == 0 || strncmp("-march=", argv[i], 7) == 0)
                        strarray_add(opts.winebuild_args, argv[i]);
		    break;
                case 'n':
                    if (strcmp("-nostdinc", argv[i]) == 0)
                        opts.nostdinc = 1;
                    else if (strcmp("-nodefaultlibs", argv[i]) == 0)
                        opts.nodefaultlibs = 1;
                    else if (strcmp("-nostdlib", argv[i]) == 0)
                        opts.nostdlib = 1;
                    else if (strcmp("-nostartfiles", argv[i]) == 0)
                        opts.nostartfiles = 1;
                    break;
		case 'o':
		    opts.output_name = option_arg;
		    break;
                case 's':
                    if (strcmp("-static", argv[i]) == 0) 
			linking = -1;
		    else if(strcmp("-save-temps", argv[i]) == 0)
			keep_generated = 1;
		    else if(strcmp("-shared", argv[i]) == 0)
		    {
			opts.shared = 1;
                        raw_compiler_arg = raw_linker_arg = 0;
		    }
                    else if (strcmp("-s", argv[i]) == 0 && opts.target_platform == PLATFORM_APPLE)
                    {
                        /* On Mac, change -s into -Wl,-x. ld's -s switch
                         * is deprecated, and it doesn't work on Tiger with
                         * MH_BUNDLEs anyway
                         */
                        opts.strip = 1;
                        raw_linker_arg = 0;
                    }
                    break;
                case 'v':
                    if (argv[i][2] == 0) verbose++;
                    break;
                case 'W':
                    if (strncmp("-Wl,", argv[i], 4) == 0)
		    {
                        unsigned int j;
                        strarray* Wl = strarray_fromstring(argv[i] + 4, ",");
                        for (j = 0; j < Wl->size; j++)
                        {
                            if (!strcmp(Wl->base[j], "--image-base") && j < Wl->size - 1)
                            {
                                opts.image_base = strdup( Wl->base[++j] );
                                continue;
                            }
                            if (!strcmp(Wl->base[j], "--section-alignment") && j < Wl->size - 1)
                            {
                                opts.section_align = strdup( Wl->base[++j] );
                                continue;
                            }
                            if (!strcmp(Wl->base[j], "--large-address-aware"))
                            {
                                opts.large_address_aware = 1;
                                continue;
                            }
                            if (!strcmp(Wl->base[j], "-static")) linking = -1;
                            strarray_add(opts.linker_args, strmake("-Wl,%s",Wl->base[j]));
                        }
                        strarray_free(Wl);
                        raw_compiler_arg = raw_linker_arg = 0;
                    }
		    else if (strncmp("-Wb,", argv[i], 4) == 0)
		    {
			strarray* Wb = strarray_fromstring(argv[i] + 4, ",");
			strarray_addall(opts.winebuild_args, Wb);
			strarray_free(Wb);
                        /* don't pass it to the compiler, it generates errors */
                        raw_compiler_arg = raw_linker_arg = 0;
		    }
                    break;
		case 'x':
		    lang = strmake("-x%s", option_arg);
		    strarray_add(opts.files, lang);
		    /* we'll pass these flags ourselves, explicitly */
                    raw_compiler_arg = raw_linker_arg = 0;
		    break;
                case '-':
                    if (strcmp("-static", argv[i]+1) == 0)
                        linking = -1;
                    else if (!strncmp("--sysroot", argv[i], 9) && opts.wine_objdir)
                    {
                        if (argv[i][9] == '=') opts.wine_objdir = argv[i] + 10;
                        else opts.wine_objdir = argv[++i];
                        raw_compiler_arg = raw_linker_arg = 0;
                    }
                    else if (!strncmp("--lib-suffix", argv[i], 12) && opts.wine_objdir)
                    {
                        if (argv[i][12] == '=') opts.lib_suffix = argv[i] + 13;
                        else opts.lib_suffix = argv[++i];
                        raw_compiler_arg = raw_linker_arg = 0;
                    }
                    break;
            }

	    /* put the arg into the appropriate bucket */
	    if (raw_linker_arg) 
	    {
		strarray_add(opts.linker_args, argv[i]);
		if (next_is_arg && (i + 1 < argc)) 
		    strarray_add(opts.linker_args, argv[i + 1]);
	    }
	    if (raw_compiler_arg)
	    {
		strarray_add(opts.compiler_args, argv[i]);
		if (next_is_arg && (i + 1 < argc))
		    strarray_add(opts.compiler_args, argv[i + 1]);
	    }

	    /* skip the next token if it's an argument */
	    if (next_is_arg) i++;
        }
	else
	{
	    strarray_add(opts.files, argv[i]);
	} 
    }

    if (opts.processor == proc_cpp) linking = 0;
    if (linking == -1) error("Static linking is not supported\n");

    if (opts.files->size == 0) forward(argc, argv, &opts);
    else if (linking) build(&opts);
    else compile(&opts, lang);

    return 0;
}
