4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Martin von Loewis
6 * Copyright 1995, 1996, 1997 Alexandre Julliard
7 * Copyright 1997 Eric Youngdale
8 * Copyright 1999 Ulrich Weigand
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "wine/port.h"
35 ORDDEF *EntryPoints[MAX_ORDINALS];
36 ORDDEF *Ordinals[MAX_ORDINALS];
37 ORDDEF *Names[MAX_ORDINALS];
39 SPEC_MODE SpecMode = SPEC_MODE_DLL;
40 int Base = MAX_ORDINALS;
45 int nb_entry_points = 0;
47 int nb_debug_channels = 0;
49 int display_warnings = 0;
51 /* we only support relay debugging on i386 */
52 #if defined(__i386__) && !defined(NO_TRACE_MSGS)
61 char *init_func = NULL;
62 char **debug_channels = NULL;
63 char **lib_path = NULL;
65 const char *input_file_name;
66 const char *output_file_name;
68 static FILE *input_file;
69 static FILE *output_file;
70 static const char *current_src_dir;
83 } exec_mode = MODE_NONE;
85 /* open the input file */
86 static void open_input( const char *name )
88 input_file_name = name;
89 if (!(input_file = fopen( name, "r" )))
91 fprintf( stderr, "Cannot open input file '%s'\n", name );
96 /* cleanup on program exit */
97 static void cleanup(void)
99 if (output_file_name) unlink( output_file_name );
103 /*******************************************************************
104 * command-line option handling
115 static void do_output( const char *arg );
116 static void do_usage(void);
117 static void do_warnings(void);
118 static void do_f_flags( const char *arg );
119 static void do_define( const char *arg );
120 static void do_include( const char *arg );
121 static void do_exe_mode( const char *arg );
122 static void do_spec( const char *arg );
123 static void do_def( const char *arg );
124 static void do_exe( const char *arg );
125 static void do_glue( const char *arg );
126 static void do_relay16(void);
127 static void do_relay32(void);
128 static void do_debug(void);
129 static void do_sym( const char *arg );
130 static void do_chdir( const char *arg );
131 static void do_lib( const char *arg );
132 static void do_import( const char *arg );
133 static void do_dimport( const char *arg );
134 static void do_rsrc( const char *arg );
136 static const struct option_descr option_table[] =
138 { "-h", 0, do_usage, "-h Display this help message" },
139 { "-w", 0, do_warnings,"-w Turn on warnings" },
140 { "-C", 1, do_chdir, "-C dir Change directory to <dir> before opening source files" },
141 { "-f", 1, do_f_flags, "-f flags Compiler flags (only -fPIC is supported)" },
142 { "-D", 1, do_define, "-D sym Ignored for C flags compatibility" },
143 { "-I", 1, do_include, "-I dir Ignored for C flags compatibility" },
144 { "-m", 1, do_exe_mode,"-m mode Set the executable mode (cui|gui|cuiw|guiw)" },
145 { "-L", 1, do_lib, "-L directory Look for imports libraries in 'directory'" },
146 { "-l", 1, do_import, "-l lib.dll Import the specified library" },
147 { "-dl", 1, do_dimport, "-dl lib.dll Delay-import the specified library" },
148 { "-res", 1, do_rsrc, "-res rsrc.res Load resources from rsrc.res" },
149 { "-o", 1, do_output, "-o name Set the output file name (default: stdout)" },
150 { "-sym", 1, do_sym, "-sym file.o Read the list of undefined symbols from 'file.o'\n" },
151 { "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" },
152 { "-def", 1, do_def, "-def file.spec Build a .def file from a spec file" },
153 { "-exe", 1, do_exe, "-exe name Build a .c file from the named executable" },
154 { "-debug", 0, do_debug, "-debug [files] Build a .c file containing debug channels declarations" },
155 { "-glue", 1, do_glue, "-glue file.c Build the 16-bit glue for a .c file" },
156 { "-relay16", 0, do_relay16, "-relay16 Build the 16-bit relay assembly routines" },
157 { "-relay32", 0, do_relay32, "-relay32 Build the 32-bit relay assembly routines" },
158 { NULL, 0, NULL, NULL }
161 static void do_output( const char *arg )
163 if ( ( unlink ( arg ) ) == -1 && ( errno != ENOENT ) )
165 fprintf ( stderr, "Unable to create output file '%s'\n", arg );
168 if (!(output_file = fopen( arg, "w" )))
170 fprintf( stderr, "Unable to create output file '%s'\n", arg );
173 output_file_name = arg;
174 atexit( cleanup ); /* make sure we remove the output file on exit */
177 static void do_usage(void)
179 const struct option_descr *opt;
180 fprintf( stderr, "Usage: winebuild [options]\n\n" );
181 fprintf( stderr, "Options:\n" );
182 for (opt = option_table; opt->name; opt++) fprintf( stderr, " %s\n", opt->usage );
183 fprintf( stderr, "\nExactly one of -spec, -def, -exe, -debug, -glue, -relay16 or -relay32 must be specified.\n\n" );
187 static void do_warnings(void)
189 display_warnings = 1;
192 static void do_f_flags( const char *arg )
194 if (!strcmp( arg, "PIC" )) UsePIC = 1;
195 /* ignore all other flags */
198 static void do_define( const char *arg )
203 static void do_include( const char *arg )
208 static void do_spec( const char *arg )
210 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
211 exec_mode = MODE_SPEC;
215 static void do_def( const char *arg )
217 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
218 exec_mode = MODE_DEF;
222 static void do_exe( const char *arg )
226 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
227 exec_mode = MODE_EXE;
228 if ((p = strrchr( arg, '/' ))) p++;
230 strcpy( DLLName, p );
231 strcpy( DLLFileName, p );
232 if (!strchr( DLLFileName, '.' )) strcat( DLLFileName, ".exe" );
233 if (SpecMode == SPEC_MODE_DLL) SpecMode = SPEC_MODE_GUIEXE;
236 static void do_exe_mode( const char *arg )
238 if (!strcmp( arg, "gui" )) SpecMode = SPEC_MODE_GUIEXE;
239 else if (!strcmp( arg, "cui" )) SpecMode = SPEC_MODE_CUIEXE;
240 else if (!strcmp( arg, "guiw" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE;
241 else if (!strcmp( arg, "cuiw" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE;
245 static void do_glue( const char *arg )
247 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
248 exec_mode = MODE_GLUE;
252 static void do_debug(void)
254 if (exec_mode != MODE_NONE) do_usage();
255 exec_mode = MODE_DEBUG;
258 static void do_chdir( const char *arg )
260 current_src_dir = arg;
263 static void do_relay16(void)
265 if (exec_mode != MODE_NONE) do_usage();
266 exec_mode = MODE_RELAY16;
269 static void do_relay32(void)
271 if (exec_mode != MODE_NONE) do_usage();
272 exec_mode = MODE_RELAY32;
275 static void do_sym( const char *arg )
277 extern void read_undef_symbols( const char *name );
278 read_undef_symbols( arg );
281 static void do_lib( const char *arg )
283 lib_path = xrealloc( lib_path, (nb_lib_paths+1) * sizeof(*lib_path) );
284 lib_path[nb_lib_paths++] = xstrdup( arg );
287 static void do_import( const char *arg )
289 add_import_dll( arg, 0 );
292 static void do_dimport( const char *arg )
294 add_import_dll( arg, 1 );
297 static void do_rsrc( const char *arg )
299 load_res32_file( arg );
302 /* parse options from the argv array and remove all the recognized ones */
303 static void parse_options( char *argv[] )
305 const struct option_descr *opt;
307 const char* arg=NULL;
309 for (ptr = argv + 1; *ptr; ptr++)
311 for (opt = option_table; opt->name; opt++)
313 if (opt->has_arg && !strncmp( *ptr, opt->name, strlen(opt->name) ))
315 arg=*ptr+strlen(opt->name);
323 if (!strcmp( *ptr, opt->name ))
332 if (exec_mode == MODE_DEBUG && **ptr != '-')
334 /* this a file name to parse for debug channels */
335 parse_debug_channels( current_src_dir, *ptr );
338 fprintf( stderr, "Unrecognized option '%s'\n", *ptr );
342 if (opt->has_arg && arg!=NULL) opt->func( arg );
343 else opt->func( "" );
348 /*******************************************************************
351 int main(int argc, char **argv)
353 output_file = stdout;
354 parse_options( argv );
359 switch (ParseTopLevel( input_file, 0 ))
362 BuildSpec16File( output_file );
365 BuildSpec32File( output_file );
371 BuildSpec32File( output_file );
374 switch (ParseTopLevel( input_file, 1 ))
377 fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
380 BuildDef32File( output_file );
386 BuildDebugFile( output_file );
389 BuildGlue( output_file, input_file );
392 BuildRelays16( output_file );
395 BuildRelays32( output_file );
401 if (output_file_name)
403 fclose( output_file );
404 output_file_name = NULL;