Properly handle the -M switch.
[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                     if (argv[i][2] == 0) linking = 0;
62                     break;
63                 case 'M':        /* map file generation */
64                     linking = 0;
65                     break;
66                 case 'm':
67                     if (strcmp("-mno-cygwin", argv[i]) == 0)
68                         use_msvcrt = 1;
69                     else if (strcmp("-mwindows", argv[i]) == 0)
70                         gui_app = 1;
71                     break;
72                 case 'n':
73                     if (strcmp("-nostdinc", argv[i]) == 0)
74                         use_stdinc = 0;
75                     else if (strcmp("-nodefaultlibs", argv[i]) == 0)
76                         use_stdlib = 0;
77                     else if (strcmp("-nostdlib", argv[i]) == 0)
78                         use_stdlib = 0;
79                     break;
80                 case 's':
81                     if (strcmp("-static", argv[i]) == 0) use_static_linking = 1;
82                     break;
83                 case 'v':        /* verbose */
84                     if (argv[i][2] == 0) verbose = 1;
85                     break;
86                 case 'V':
87                     printf("winegcc v0.3\n");
88                     exit(0);
89                     break;
90                 case 'W':
91                     if (strncmp("-Wl,", argv[i], 4) == 0)
92                     {
93                         if (strstr(argv[i], "-static"))
94                             use_static_linking = 1;
95                     }
96                     break;
97                 case 'x':
98                     if (strcmp("-xc++", argv[i]) == 0) cpp = 1;
99                     break;
100                 case '-':
101                     if (strcmp("-static", argv[i]+1) == 0)
102                         use_static_linking = 1;
103                     break;
104             }
105         } 
106     }
107
108     if (use_static_linking) error("Static linking is not supported.");
109
110     gcc_argv = malloc(sizeof(char*) * (argc + 20));
111
112     i = 0;
113     if (linking)
114     {
115         gcc_argv[i++] = BINDIR "/winewrap";
116         if (gui_app) gcc_argv[i++] = "-mgui";
117         if (cpp) gcc_argv[i++] = "-C";
118     }
119     else
120     {
121         gcc_argv[i++] = cpp ? "g++" : "gcc";
122
123         gcc_argv[i++] = "-fshort-wchar";
124         gcc_argv[i++] = "-fPIC";
125         if (use_stdinc)
126         {
127             if (use_msvcrt) gcc_argv[i++] = "-I" INCLUDEDIR "/msvcrt";
128             gcc_argv[i++] = "-I" INCLUDEDIR "/windows";
129         }
130         gcc_argv[i++] = "-DWINE_UNICODE_NATIVE";
131         gcc_argv[i++] = "-D__int8=char";
132         gcc_argv[i++] = "-D__int16=short";
133         gcc_argv[i++] = "-D__int32=int";
134         gcc_argv[i++] = "-D__int64=long long";
135     }
136
137     for ( j = 1 ; j < argc ; j++ ) 
138     {
139         if (strcmp("-mno-cygwin", argv[j]) == 0)
140             ; /* ignore this option */
141         else if (strcmp("-mwindows", argv[j]) == 0)
142             ; /* ignore this option */
143         else if (strcmp("-s", argv[j]) == 0)
144             ; /* ignore this option */
145         else
146             gcc_argv[i++] = argv[j];
147     }
148
149     if (linking)
150     {
151         if (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt";
152     }
153     gcc_argv[i] = NULL;
154
155     if (verbose)
156     {
157         for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]);
158         printf("\n");
159     }
160
161     execvp(gcc_argv[0], gcc_argv);
162
163     return 1;
164 }