/*
 * 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 },
    { "sparc",   CPU_SPARC },
    { "alpha",   CPU_ALPHA },
    { "powerpc", CPU_POWERPC },
    { "arm",     CPU_ARM }
};

static const struct
{
    const char *name;
    enum target_platform platform;
} platform_names[] =
{
    { "macos",   PLATFORM_APPLE },
    { "darwin",  PLATFORM_APPLE },
    { "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;
    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;
    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(__sparc__)
static const enum target_cpu build_cpu = CPU_SPARC;
#elif defined(__ALPHA__)
static const enum target_cpu build_cpu = CPU_ALPHA;
#elif defined(__powerpc__)
static const enum target_cpu build_cpu = CPU_POWERPC;
#elif defined(__arm__)
static const enum target_cpu build_cpu = CPU_ARM;
#else
#error Unsupported CPU
#endif

#ifdef __APPLE__
static enum target_platform build_platform = PLATFORM_APPLE;
#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 /tmp */
        free(tmp);
        tmp = strmake("/tmp/%s-XXXXXX%s", 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 const strarray* get_translator(struct options *opts)
{
    const char *str = NULL;
    strarray *ret;

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

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

    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:
            for ( j = 0; !gcc_defs && j < comp_args->size; j++ )
            {
                const char *cc = comp_args->base[j];

                gcc_defs = strendswith(cc, "gcc") || strendswith(cc, "g++");
            }
            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_addall(comp_args, strarray_fromstring(DLLFLAGS, " "));
    }

    if (opts->target_cpu == CPU_x86_64)
    {
        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)
    {
        int fastcall_done = 0;
        if (opts->target_cpu == 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))");
            fastcall_done = 1;
        }
        else if (opts->target_platform == PLATFORM_APPLE)
        {
            /* Mac OS X uses a 16-byte aligned stack and not a 4-byte one */
            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__))");
        }
        else
        {
            strarray_add(comp_args, "-D__stdcall=__attribute__((__stdcall__))");
            strarray_add(comp_args, "-D__cdecl=__attribute__((__cdecl__))");
            strarray_add(comp_args, "-D_stdcall=__attribute__((__stdcall__))");
            strarray_add(comp_args, "-D_cdecl=__attribute__((__cdecl__))");
        }

	if (!fastcall_done)
        {
            strarray_add(comp_args, "-D__fastcall=__attribute__((__fastcall__))");
            strarray_add(comp_args, "-D_fastcall=__attribute__((__fastcall__))");
        }
	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)
        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,
                 "#include <stdarg.h>\n"
                 "#include <windef.h>\n"
                 "#include <winbase.h>\n"
                 "int main( int argc, char *argv[] )\n{\n"
                 "    int wargc;\n"
                 "    wchar_t **wargv, **wenv;\n"
                 "    HMODULE msvcrt = LoadLibraryA( \"msvcrt.dll\" );\n"
                 "    void __cdecl (*__wgetmainargs)(int *argc, wchar_t** *wargv, wchar_t** *wenvp, int expand_wildcards,\n"
                 "                                   int *new_mode) = (void *)GetProcAddress( msvcrt, \"__wgetmainargs\" );\n"
                 "    __wgetmainargs( &wargc, &wargv, &wenv, 0, NULL );\n"
                 "    return wmain( wargc, wargv );\n}\n" );
    return compile_to_object( opts, main_stub, NULL );
}

static void build(struct options* opts)
{
    static const char *stdlibpath[] = { DLLDIR, LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
    strarray *lib_dirs, *files;
    strarray *spec_args, *link_args;
    char *output_file;
    const char *spec_o_name;
    const char *output_name, *spec_file, *lang;
    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)
    {
        lib_dirs = strarray_dup(opts->lib_dirs);
	for ( j = 0; j < sizeof(stdlibpath)/sizeof(stdlibpath[0]); j++ )
	    strarray_add(lib_dirs, stdlibpath[j]);
    }
    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" );

        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);

            if (opts->target) strarray_add(link_args, strmake("%s-dllwrap", opts->target));
            else strarray_add(link_args, "dllwrap");
            if (verbose) strarray_add(link_args, "-v");
            strarray_add(link_args, "-k");
            strarray_add(link_args, "--def");
            strarray_add(link_args, spec_def_name);
        }
        else
        {
            strarray_addall(link_args, get_translator(opts));
            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) 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->nostdlib) add_library(opts, lib_dirs, files, "wine");
        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 );
    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_addall(spec_args, strarray_fromstring(DLLFLAGS, " "));
    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, strarray_fromstring(LDDLLFLAGS, " "));

    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);
        }
        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;
    default:
        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 */
    if (opts->image_base)
    {
        const char *prelink = PRELINK;
        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[2] == '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, '-' ))) error( "Invalid target specification '%s'\n", target );
    *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;

    /* 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 tihs 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) 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')
		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, "/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 (strendswith(str, "/")) str[strlen(str) - 1] = 0;
                    if (!opts.prefix) opts.prefix = strarray_alloc();
                    strarray_add(opts.prefix, str);
		    break;
                case 'b':
                    parse_target_option( &opts, 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;
                        opts.force_pointer_size = 4;
			raw_linker_arg = 1;
                    }
		    else if (strcmp("-m64", argv[i]) == 0)
                    {
                        opts.force_pointer_size = 8;
			raw_linker_arg = 1;
                    }
		    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;
		    }
                    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;
}
