Added C++ support & small cleanups.
[wine] / tools / winegcc.c
1 /*
2  * MinGW wrapper: makes gcc behave like MinGW.
3  *
4  * Copyright 2000 Manuel Novoa III
5  * Copyright 2002 Dimitrie O. Paun
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32
33 void error(const char *s, ...)
34 {
35     va_list ap;
36     
37     va_start(ap, s);
38     fprintf(stderr, "Error: ");
39     vfprintf(stderr, s, ap);
40     fprintf(stderr, "\n");
41     va_end(ap);
42     exit(2);
43 }
44
45 int main(int argc, char **argv)
46 {
47     char **gcc_argv;
48     int i, j;
49     int linking = 1, verbose = 0, cpp = 0, use_static_linking = 0;
50     int use_stdinc = 1, use_stdlib = 1, use_msvcrt = 0, gui_app = 0;
51
52     for ( i = 1 ; i < argc ; i++ ) 
53     {
54         if (argv[i][0] == '-')  /* option */
55         {
56             switch (argv[i][1]) 
57             {
58                 case 'c':        /* compile or assemble */
59                 case 'S':        /* generate assembler code */
60                 case 'E':        /* preprocess only */
61                 case 'M':        /* map file generation */
62                     if (argv[i][2] == 0) linking = 0;
63                     break;
64                 case 'm':
65                     if (strcmp("-mno-cygwin", argv[i]) == 0)
66                         use_msvcrt = 1;
67                     else if (strcmp("-mwindows", argv[i]) == 0)
68                         gui_app = 1;
69                     break;
70                 case 'n':
71                     if (strcmp("-nostdinc", argv[i]) == 0)
72                         use_stdinc = 0;
73                     else if (strcmp("-nodefaultlibs", argv[i]) == 0)
74                         use_stdlib = 0;
75                     else if (strcmp("-nostdlib", argv[i]) == 0)
76                         use_stdlib = 0;
77                     break;
78                 case 's':
79                     if (strcmp("-static", argv[i]) == 0) use_static_linking = 1;
80                     break;
81                 case 'v':        /* verbose */
82                     if (argv[i][2] == 0) verbose = 1;
83                     break;
84                 case 'V':
85                     printf("winegcc v0.3\n");
86                     exit(0);
87                     break;
88                 case 'W':
89                     if (strncmp("-Wl,", argv[i], 4) == 0)
90                     {
91                         if (strstr(argv[i], "-static"))
92                             use_static_linking = 1;
93                     }
94                     break;
95                 case 'x':
96                     if (strcmp("-xc++", argv[i]) == 0) cpp = 1;
97                     break;
98                 case '-':
99                     if (strcmp("-static", argv[i]+1) == 0)
100                         use_static_linking = 1;
101                     break;
102             }
103         } 
104     }
105
106     if (use_static_linking) error("Static linking is not supported.");
107
108     gcc_argv = malloc(sizeof(char*) * (argc + 20));
109
110     i = 0;
111     if (linking)
112     {
113         gcc_argv[i++] = BINDIR "/winewrap";
114         if (gui_app) gcc_argv[i++] = "-mgui";
115         if (cpp) gcc_argv[i++] = "-C";
116     }
117     else
118     {
119         gcc_argv[i++] = cpp ? "g++" : "gcc";
120
121         gcc_argv[i++] = "-fshort-wchar";
122         gcc_argv[i++] = "-fPIC";
123         if (use_stdinc)
124         {
125             if (use_msvcrt) gcc_argv[i++] = "-I" INCLUDEDIR "/msvcrt";
126             gcc_argv[i++] = "-I" INCLUDEDIR "/windows";
127         }
128         gcc_argv[i++] = "-DWINE_UNICODE_NATIVE";
129         gcc_argv[i++] = "-D__int8=char";
130         gcc_argv[i++] = "-D__int16=short";
131         gcc_argv[i++] = "-D__int32=int";
132         gcc_argv[i++] = "-D__int64=long long";
133     }
134
135     for ( j = 1 ; j < argc ; j++ ) 
136     {
137         if (strcmp("-mno-cygwin", argv[j]) == 0)
138             ; /* ignore this option */
139         else if (strcmp("-mwindows", argv[j]) == 0)
140             ; /* ignore this option */
141         else if (strcmp("-s", argv[j]) == 0)
142             ; /* ignore this option */
143         else
144             gcc_argv[i++] = argv[j];
145     }
146
147     if (linking)
148     {
149         if (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt";
150     }
151     gcc_argv[i] = NULL;
152
153     if (verbose)
154     {
155         for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]);
156         printf("\n");
157     }
158
159     execvp(gcc_argv[0], gcc_argv);
160
161     return 1;
162 }