2 * MinGW wrapper: makes gcc behave like MinGW.
4 * Copyright 2000 Manuel Novoa III
5 * Copyright 2002 Dimitrie O. Paun
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.
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.
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
23 #include "wine/port.h"
33 static int keep_generated = 0;
34 static strarray *tmp_files;
36 static int strendswith(const char *str, const char *end)
41 return l >= m && strcmp(str + l - m, end) == 0;
44 static void clean_temp_files()
49 for (i = 0; i < tmp_files->size; i++)
50 unlink(tmp_files->base[i]);
52 strarray_free(tmp_files);
55 static char *get_temp_file(const char *suffix)
57 char *tmp = strmake("wgcc.XXXXXX%s", suffix);
58 int fd = mkstemps( tmp, strlen(suffix) );
61 /* could not create it in current directory, try in /tmp */
63 tmp = strmake("/tmp/wgcc.XXXXXX%s", suffix);
64 fd = mkstemps( tmp, strlen(suffix) );
65 if (fd == -1) error( "could not create temp file" );
68 strarray_add(tmp_files, tmp);
73 static char *get_obj_file(char **argv, int n)
79 if (strendswith(argv[n], ".o")) return argv[n];
80 if (strendswith(argv[n], ".a")) return argv[n];
81 if (strendswith(argv[n], ".res")) return argv[n];
83 tmpobj = get_temp_file(".o");
85 compargv = strarray_alloc();
86 strarray_add(compargv,"winegcc");
87 strarray_add(compargv, "-c");
88 strarray_add(compargv, "-o");
89 strarray_add(compargv, tmpobj);
90 for (j = 1; j <= n; j++)
91 if (argv[j]) strarray_add(compargv, argv[j]);
92 strarray_add(compargv, NULL);
95 strarray_free(compargv);
101 int main(int argc, char **argv)
105 int linking = 1, cpp = 0, preprocessor = 0, use_static_linking = 0;
106 int use_stdinc = 1, use_stdlib = 1, use_msvcrt = 0, gui_app = 0;
108 tmp_files = strarray_alloc();
109 atexit(clean_temp_files);
111 if (strendswith(argv[0], "winecpp")) preprocessor = 1;
112 else if (strendswith(argv[0], "++")) cpp = 1;
114 for ( i = 1 ; i < argc ; i++ )
116 if (argv[i][0] == '-') /* option */
120 case 'c': /* compile or assemble */
121 case 'S': /* generate assembler code */
122 case 'E': /* preprocess only */
123 if (argv[i][2] == 0) linking = 0;
125 case 'M': /* map file generation */
129 if (strcmp("-mno-cygwin", argv[i]) == 0)
131 else if (strcmp("-mwindows", argv[i]) == 0)
133 else if (strcmp("-mconsole", argv[i]) == 0)
137 if (strcmp("-nostdinc", argv[i]) == 0)
139 else if (strcmp("-nodefaultlibs", argv[i]) == 0)
141 else if (strcmp("-nostdlib", argv[i]) == 0)
145 if (strcmp("-static", argv[i]) == 0) use_static_linking = 1;
147 case 'v': /* verbose */
148 if (argv[i][2] == 0) verbose = 1;
151 if (strncmp("-Wl,", argv[i], 4) == 0)
153 if (strstr(argv[i], "-static"))
154 use_static_linking = 1;
158 if (strcmp("-static", argv[i]+1) == 0)
159 use_static_linking = 1;
165 if (preprocessor) linking = 0;
166 if (use_static_linking) error("Static linking is not supported.");
168 gcc_argv = strarray_alloc();
172 int has_input_files = 0;
176 /* we need a copy in case we decide to pass args straight to gcc
177 * and we erase some of the original parameters as we go along
179 copy_argv = strarray_alloc();
180 strarray_add(copy_argv, cpp ? "g++" : "gcc");
181 for( j = 1; j < argc ; j++ )
182 strarray_add(copy_argv, argv[j]);
184 strarray_add(gcc_argv, "winewrap");
185 if (gui_app) strarray_add(gcc_argv, "-mgui");
187 if (cpp) strarray_add(gcc_argv, "-C");
189 for ( j = 1 ; j < argc ; j++ )
191 if ( argv[j][0] == '-' )
197 strarray_add(gcc_argv, argv[j]);
198 if (!argv[j][2] && j + 1 < argc)
201 strarray_add(gcc_argv, argv[++j]);
206 strarray_add(gcc_argv, strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid");
210 ; /* ignore the rest */
215 strarray_add(gcc_argv, get_obj_file(argv, j));
223 if (use_stdlib && use_msvcrt) strarray_add(gcc_argv, "-lmsvcrt");
224 if (gui_app) strarray_add(gcc_argv, "-lcomdlg32");
225 strarray_add(gcc_argv, "-ladvapi32");
226 strarray_add(gcc_argv, "-lshell32");
230 /* if we have nothing to process, just forward stuff to gcc */
231 strarray_free(gcc_argv);
232 gcc_argv = copy_argv;
237 strarray_add(gcc_argv, preprocessor ? "cpp" : cpp ? "g++" : "gcc");
241 strarray_add(gcc_argv, "-fshort-wchar");
242 strarray_add(gcc_argv, "-fPIC");
248 strarray_add(gcc_argv, "-I" INCLUDEDIR "/msvcrt");
249 strarray_add(gcc_argv, "-D__MSVCRT__");
251 strarray_add(gcc_argv, "-I" INCLUDEDIR "/windows");
253 strarray_add(gcc_argv, "-DWIN32");
254 strarray_add(gcc_argv, "-D_WIN32");
255 strarray_add(gcc_argv, "-D__WIN32");
256 strarray_add(gcc_argv, "-D__WIN32__");
257 strarray_add(gcc_argv, "-D__WINNT");
258 strarray_add(gcc_argv, "-D__WINNT__");
260 strarray_add(gcc_argv, "-D__stdcall=__attribute__((__stdcall__))");
261 strarray_add(gcc_argv, "-D__cdecl=__attribute__((__cdecl__))");
262 strarray_add(gcc_argv, "-D__fastcall=__attribute__((__fastcall__))");
263 strarray_add(gcc_argv, "-D_stdcall=__attribute__((__stdcall__))");
264 strarray_add(gcc_argv, "-D_cdecl=__attribute__((__cdecl__))");
265 strarray_add(gcc_argv, "-D_fastcall=__attribute__((__fastcall__))");
266 strarray_add(gcc_argv, "-D__declspec(x)=__declspec_##x");
267 strarray_add(gcc_argv, "-D__declspec_align(x)=__attribute__((aligned(x)))");
268 strarray_add(gcc_argv, "-D__declspec_allocate(x)=__attribute__((section(x)))");
269 strarray_add(gcc_argv, "-D__declspec_deprecated=__attribute__((deprecated))");
270 strarray_add(gcc_argv, "-D__declspec_dllimport=__attribute__((dllimport))");
271 strarray_add(gcc_argv, "-D__declspec_dllexport=__attribute__((dllexport))");
272 strarray_add(gcc_argv, "-D__declspec_naked=__attribute__((naked))");
273 strarray_add(gcc_argv, "-D__declspec_noinline=__attribute__((noinline))");
274 strarray_add(gcc_argv, "-D__declspec_noreturn=__attribute__((noreturn))");
275 strarray_add(gcc_argv, "-D__declspec_nothrow=__attribute__((nothrow))");
276 strarray_add(gcc_argv, "-D__declspec_novtable=__attribute__(())"); /* ignore it */
277 strarray_add(gcc_argv, "-D__declspec_selectany=__attribute__((weak))");
278 strarray_add(gcc_argv, "-D__declspec_thread=__thread");
280 /* Wine specific defines */
281 strarray_add(gcc_argv, "-D__WINE__");
282 strarray_add(gcc_argv, "-DWINE_UNICODE_NATIVE");
283 strarray_add(gcc_argv, "-D__int8=char");
284 strarray_add(gcc_argv, "-D__int16=short");
285 strarray_add(gcc_argv, "-D__int32=int");
286 strarray_add(gcc_argv, "-D__int64=long long");
288 for ( j = 1 ; j < argc ; j++ )
290 if (strcmp("-mno-cygwin", argv[j]) == 0)
291 ; /* ignore this option */
292 else if (strcmp("-mwindows", argv[j]) == 0)
293 ; /* ignore this option */
294 else if (strcmp("-mconsole", argv[j]) == 0)
295 ; /* ignore this option */
296 else if (strcmp("-mthreads", argv[j]) == 0)
297 ; /* ignore this option */
298 else if (strncmp("-Wl,", argv[j], 4) == 0)
299 ; /* do not pass linking options to compiler */
300 else if (strcmp("-s", argv[j]) == 0)
301 ; /* ignore this option */
303 strarray_add(gcc_argv, argv[j]);
307 strarray_add(gcc_argv, NULL);
311 strarray_free(gcc_argv);