mingw links in comdlg32, shell32, and advapi32 by default.
[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
118         if (cpp) gcc_argv[i++] = "-C";  
119         for ( j = 1 ; j < argc ; j++ ) 
120         {
121             if ( argv[j][0] == '-' )
122             {
123                 switch (argv[j][1])
124                 {
125                 case 'L':
126                 case 'o':
127                     gcc_argv[i++] = argv[j];
128                     break;
129                 case 'l':
130                     gcc_argv[i++] = strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid"; 
131                     break;
132                 default:
133                     ; /* ignore the rest */
134                 }
135             }
136             else
137                 gcc_argv[i++] = argv[j];
138         }
139         if (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt";
140         if (gui_app) gcc_argv[i++] = "-lcomdlg32";
141         if (gui_app) gcc_argv[i++] = "-lshell32";
142         gcc_argv[i++] = "-ladvapi32";
143     }
144     else
145     {
146         gcc_argv[i++] = cpp ? "g++" : "gcc";
147
148         gcc_argv[i++] = "-fshort-wchar";
149         gcc_argv[i++] = "-fPIC";
150         if (use_stdinc)
151         {
152             if (use_msvcrt) gcc_argv[i++] = "-I" INCLUDEDIR "/msvcrt";
153             gcc_argv[i++] = "-I" INCLUDEDIR "/windows";
154         }
155         gcc_argv[i++] = "-D__WINE__";
156         gcc_argv[i++] = "-D__WIN32__";
157         gcc_argv[i++] = "-DWINE_UNICODE_NATIVE";
158         gcc_argv[i++] = "-D__int8=char";
159         gcc_argv[i++] = "-D__int16=short";
160         gcc_argv[i++] = "-D__int32=int";
161         gcc_argv[i++] = "-D__int64=long long";
162
163         for ( j = 1 ; j < argc ; j++ ) 
164         {
165             if (strcmp("-mno-cygwin", argv[j]) == 0)
166                 ; /* ignore this option */
167             else if (strcmp("-mwindows", argv[j]) == 0)
168                 ; /* ignore this option */
169             else if (strcmp("-s", argv[j]) == 0)
170                 ; /* ignore this option */
171             else
172                 gcc_argv[i++] = argv[j];
173         }
174     }
175
176     gcc_argv[i] = NULL;
177
178     if (verbose)
179     {
180         for (i = 0; gcc_argv[i]; i++) printf("%s ", gcc_argv[i]);
181         printf("\n");
182     }
183
184     execvp(gcc_argv[0], gcc_argv);
185
186     return 1;
187 }