Commit 1862a67d authored by Alexandre Julliard's avatar Alexandre Julliard

In -spec and -exe mode, accept multiple object files and link them

together internally to find the undefined symbols. In -glue mode, accept multiple C files and generate a single glue file for all of them.
parent 2a91e3f9
...@@ -139,6 +139,8 @@ extern void fatal_error( const char *msg, ... ); ...@@ -139,6 +139,8 @@ extern void fatal_error( const char *msg, ... );
extern void fatal_perror( const char *msg, ... ); extern void fatal_perror( const char *msg, ... );
extern void warning( const char *msg, ... ); extern void warning( const char *msg, ... );
extern void output_standard_file_header( FILE *outfile ); extern void output_standard_file_header( FILE *outfile );
extern FILE *open_input_file( const char *srcdir, const char *name );
extern void close_input_file( FILE *file );
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, extern void dump_bytes( FILE *outfile, const unsigned char *data, int len,
const char *label, int constant ); const char *label, int constant );
extern const char *make_c_identifier( const char *str ); extern const char *make_c_identifier( const char *str );
...@@ -146,6 +148,7 @@ extern int get_alignment(int alignBoundary); ...@@ -146,6 +148,7 @@ extern int get_alignment(int alignBoundary);
extern void add_import_dll( const char *name, int delay ); extern void add_import_dll( const char *name, int delay );
extern void add_ignore_symbol( const char *name ); extern void add_ignore_symbol( const char *name );
extern void read_undef_symbols( char **argv );
extern int resolve_imports( void ); extern int resolve_imports( void );
extern int output_imports( FILE *outfile ); extern int output_imports( FILE *outfile );
extern void load_res32_file( const char *name ); extern void load_res32_file( const char *name );
...@@ -156,13 +159,13 @@ extern int output_res16_directory( unsigned char *buffer ); ...@@ -156,13 +159,13 @@ extern int output_res16_directory( unsigned char *buffer );
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor ); extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
extern void parse_debug_channels( const char *srcdir, const char *filename ); extern void parse_debug_channels( const char *srcdir, const char *filename );
extern void BuildGlue( FILE *outfile, FILE *infile ); extern void BuildGlue( FILE *outfile, const char *srcdir, char **argv );
extern void BuildRelays16( FILE *outfile ); extern void BuildRelays16( FILE *outfile );
extern void BuildRelays32( FILE *outfile ); extern void BuildRelays32( FILE *outfile );
extern void BuildSpec16File( FILE *outfile ); extern void BuildSpec16File( FILE *outfile );
extern void BuildSpec32File( FILE *outfile ); extern void BuildSpec32File( FILE *outfile );
extern void BuildDef32File( FILE *outfile ); extern void BuildDef32File( FILE *outfile );
extern void BuildDebugFile( FILE *outfile ); extern void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv );
extern SPEC_TYPE ParseTopLevel( FILE *file, int def_only ); extern SPEC_TYPE ParseTopLevel( FILE *file, int def_only );
/* global variables */ /* global variables */
...@@ -184,7 +187,7 @@ extern char DLLName[80]; ...@@ -184,7 +187,7 @@ extern char DLLName[80];
extern char DLLFileName[80]; extern char DLLFileName[80];
extern char owner_name[80]; extern char owner_name[80];
extern char *init_func; extern char *init_func;
extern const char *input_file_name; extern char *input_file_name;
extern const char *output_file_name; extern const char *output_file_name;
extern char **debug_channels; extern char **debug_channels;
extern char **lib_path; extern char **lib_path;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "build.h" #include "build.h"
...@@ -55,6 +56,8 @@ static char **ignore_symbols; /* list of symbols to ignore */ ...@@ -55,6 +56,8 @@ static char **ignore_symbols; /* list of symbols to ignore */
static int nb_ignore_symbols; static int nb_ignore_symbols;
static int ignore_size; static int ignore_size;
static const char *ld_tmp_file; /* ld temp file name */
static struct import **dll_imports = NULL; static struct import **dll_imports = NULL;
static int nb_imports = 0; /* number of imported dlls (delayed or not) */ static int nb_imports = 0; /* number of imported dlls (delayed or not) */
static int nb_delayed = 0; /* number of delayed dlls */ static int nb_delayed = 0; /* number of delayed dlls */
...@@ -103,6 +106,12 @@ inline static void sort_symbols( char **table, int size ) ...@@ -103,6 +106,12 @@ inline static void sort_symbols( char **table, int size )
qsort( table, size, sizeof(*table), name_cmp ); qsort( table, size, sizeof(*table), name_cmp );
} }
/* remove the temp file at exit */
static void remove_ld_tmp_file(void)
{
if (ld_tmp_file) unlink( ld_tmp_file );
}
/* open the .so library for a given dll in a specified path */ /* open the .so library for a given dll in a specified path */
static char *try_library_path( const char *path, const char *name ) static char *try_library_path( const char *path, const char *name )
{ {
...@@ -385,15 +394,46 @@ static void warn_unused( const struct import* imp ) ...@@ -385,15 +394,46 @@ static void warn_unused( const struct import* imp )
current_line = curline; current_line = curline;
} }
/* combine a list of object files with ld into a single object file */
/* returns the name of the combined file */
static const char *ldcombine_files( char **argv )
{
int i, len = 0;
char *cmd;
int fd, err;
char buffer[] = "/tmp/winebuild.tmp.XXXXXX";
if ((fd = mkstemp( buffer ) == -1)) fatal_error( "could not generate a temp file\n" );
close( fd );
ld_tmp_file = xstrdup( buffer );
atexit( remove_ld_tmp_file );
for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1;
cmd = xmalloc( len + strlen(ld_tmp_file) + 10 );
sprintf( cmd, "ld -r -o %s", ld_tmp_file );
for (i = 0; argv[i]; i++) sprintf( cmd + strlen(cmd), " %s", argv[i] );
err = system( cmd );
if (err) fatal_error( "ld -r failed with status %d\n", err );
free( cmd );
return ld_tmp_file;
}
/* read in the list of undefined symbols */ /* read in the list of undefined symbols */
void read_undef_symbols( const char *name ) void read_undef_symbols( char **argv )
{ {
FILE *f; FILE *f;
char buffer[1024]; char buffer[1024];
int err; int err;
const char *name;
if (!argv[0]) return;
undef_size = nb_undef_symbols = 0; undef_size = nb_undef_symbols = 0;
/* if we have multiple object files, link them together */
if (argv[1]) name = ldcombine_files( argv );
else name = argv[0];
sprintf( buffer, "nm -u %s", name ); sprintf( buffer, "nm -u %s", name );
if (!(f = popen( buffer, "r" ))) if (!(f = popen( buffer, "r" )))
fatal_error( "Cannot execute '%s'\n", buffer ); fatal_error( "Cannot execute '%s'\n", buffer );
......
...@@ -62,8 +62,8 @@ char *init_func = NULL; ...@@ -62,8 +62,8 @@ char *init_func = NULL;
char **debug_channels = NULL; char **debug_channels = NULL;
char **lib_path = NULL; char **lib_path = NULL;
const char *input_file_name; char *input_file_name = NULL;
const char *output_file_name; const char *output_file_name = NULL;
static FILE *input_file; static FILE *input_file;
static FILE *output_file; static FILE *output_file;
...@@ -82,17 +82,6 @@ static enum ...@@ -82,17 +82,6 @@ static enum
MODE_RELAY32 MODE_RELAY32
} exec_mode = MODE_NONE; } exec_mode = MODE_NONE;
/* open the input file */
static void open_input( const char *name )
{
input_file_name = name;
if (!(input_file = fopen( name, "r" )))
{
fprintf( stderr, "Cannot open input file '%s'\n", name );
exit(1);
}
}
/* set the dll file name from the input file name */ /* set the dll file name from the input file name */
static void set_dll_file_name( const char *name ) static void set_dll_file_name( const char *name )
{ {
...@@ -135,11 +124,11 @@ static void do_module( const char *arg ); ...@@ -135,11 +124,11 @@ static void do_module( const char *arg );
static void do_spec( const char *arg ); static void do_spec( const char *arg );
static void do_def( const char *arg ); static void do_def( const char *arg );
static void do_exe( const char *arg ); static void do_exe( const char *arg );
static void do_glue( const char *arg ); static void do_glue(void);
static void do_relay16(void); static void do_relay16(void);
static void do_relay32(void); static void do_relay32(void);
static void do_debug(void); static void do_debug(void);
static void do_sym( const char *arg ); static void do_sym(void);
static void do_chdir( const char *arg ); static void do_chdir( const char *arg );
static void do_lib( const char *arg ); static void do_lib( const char *arg );
static void do_import( const char *arg ); static void do_import( const char *arg );
...@@ -161,13 +150,13 @@ static const struct option_descr option_table[] = ...@@ -161,13 +150,13 @@ static const struct option_descr option_table[] =
{ "-l", 1, do_import, "-l lib.dll Import the specified library" }, { "-l", 1, do_import, "-l lib.dll Import the specified library" },
{ "-dl", 1, do_dimport, "-dl lib.dll Delay-import the specified library" }, { "-dl", 1, do_dimport, "-dl lib.dll Delay-import the specified library" },
{ "-res", 1, do_rsrc, "-res rsrc.res Load resources from rsrc.res" }, { "-res", 1, do_rsrc, "-res rsrc.res Load resources from rsrc.res" },
{ "-o", 1, do_output, "-o name Set the output file name (default: stdout)" }, { "-o", 1, do_output, "-o name Set the output file name (default: stdout)\n" },
{ "-sym", 1, do_sym, "-sym file.o Read the list of undefined symbols from 'file.o'\n" }, { "-sym", 0, do_sym, NULL }, /* ignored for backwards compatibility */
{ "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" }, { "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" },
{ "-def", 1, do_def, "-def file.spec Build a .def file from a spec file" }, { "-def", 1, do_def, "-def file.spec Build a .def file from a spec file" },
{ "-exe", 1, do_exe, "-exe name Build a .c file from the named executable" }, { "-exe", 1, do_exe, "-exe name Build a .c file from the named executable" },
{ "-debug", 0, do_debug, "-debug [files] Build a .c file containing debug channels declarations" }, { "-debug", 0, do_debug, "-debug [files] Build a .c file containing debug channels declarations" },
{ "-glue", 1, do_glue, "-glue file.c Build the 16-bit glue for a .c file" }, { "-glue", 0, do_glue, "-glue [files] Build the 16-bit glue for the source files" },
{ "-relay16", 0, do_relay16, "-relay16 Build the 16-bit relay assembly routines" }, { "-relay16", 0, do_relay16, "-relay16 Build the 16-bit relay assembly routines" },
{ "-relay32", 0, do_relay32, "-relay32 Build the 32-bit relay assembly routines" }, { "-relay32", 0, do_relay32, "-relay32 Build the 32-bit relay assembly routines" },
{ NULL, 0, NULL, NULL } { NULL, 0, NULL, NULL }
...@@ -194,7 +183,9 @@ static void do_usage(void) ...@@ -194,7 +183,9 @@ static void do_usage(void)
const struct option_descr *opt; const struct option_descr *opt;
fprintf( stderr, "Usage: winebuild [options]\n\n" ); fprintf( stderr, "Usage: winebuild [options]\n\n" );
fprintf( stderr, "Options:\n" ); fprintf( stderr, "Options:\n" );
for (opt = option_table; opt->name; opt++) fprintf( stderr, " %s\n", opt->usage ); for (opt = option_table; opt->name; opt++)
if (opt->usage) fprintf( stderr, " %s\n", opt->usage );
fprintf( stderr, "\nExactly one of -spec, -def, -exe, -debug, -glue, -relay16 or -relay32 must be specified.\n\n" ); fprintf( stderr, "\nExactly one of -spec, -def, -exe, -debug, -glue, -relay16 or -relay32 must be specified.\n\n" );
exit(1); exit(1);
} }
...@@ -231,7 +222,7 @@ static void do_spec( const char *arg ) ...@@ -231,7 +222,7 @@ static void do_spec( const char *arg )
{ {
if (exec_mode != MODE_NONE || !arg[0]) do_usage(); if (exec_mode != MODE_NONE || !arg[0]) do_usage();
exec_mode = MODE_SPEC; exec_mode = MODE_SPEC;
open_input( arg ); input_file = open_input_file( NULL, arg );
set_dll_file_name( arg ); set_dll_file_name( arg );
} }
...@@ -239,7 +230,7 @@ static void do_def( const char *arg ) ...@@ -239,7 +230,7 @@ static void do_def( const char *arg )
{ {
if (exec_mode != MODE_NONE || !arg[0]) do_usage(); if (exec_mode != MODE_NONE || !arg[0]) do_usage();
exec_mode = MODE_DEF; exec_mode = MODE_DEF;
open_input( arg ); input_file = open_input_file( NULL, arg );
set_dll_file_name( arg ); set_dll_file_name( arg );
} }
...@@ -270,11 +261,10 @@ static void do_module( const char *arg ) ...@@ -270,11 +261,10 @@ static void do_module( const char *arg )
strcpy( owner_name, arg ); strcpy( owner_name, arg );
} }
static void do_glue( const char *arg ) static void do_glue(void)
{ {
if (exec_mode != MODE_NONE || !arg[0]) do_usage(); if (exec_mode != MODE_NONE) do_usage();
exec_mode = MODE_GLUE; exec_mode = MODE_GLUE;
open_input( arg );
} }
static void do_debug(void) static void do_debug(void)
...@@ -300,10 +290,9 @@ static void do_relay32(void) ...@@ -300,10 +290,9 @@ static void do_relay32(void)
exec_mode = MODE_RELAY32; exec_mode = MODE_RELAY32;
} }
static void do_sym( const char *arg ) static void do_sym(void)
{ {
extern void read_undef_symbols( const char *name ); /* nothing */
read_undef_symbols( arg );
} }
static void do_lib( const char *arg ) static void do_lib( const char *arg )
...@@ -331,10 +320,10 @@ static void do_rsrc( const char *arg ) ...@@ -331,10 +320,10 @@ static void do_rsrc( const char *arg )
static void parse_options( char *argv[] ) static void parse_options( char *argv[] )
{ {
const struct option_descr *opt; const struct option_descr *opt;
char * const * ptr; char **ptr, **last;
const char* arg=NULL; const char* arg=NULL;
for (ptr = argv + 1; *ptr; ptr++) for (ptr = last = argv + 1; *ptr; ptr++)
{ {
for (opt = option_table; opt->name; opt++) for (opt = option_table; opt->name; opt++)
{ {
...@@ -355,21 +344,18 @@ static void parse_options( char *argv[] ) ...@@ -355,21 +344,18 @@ static void parse_options( char *argv[] )
} }
} }
if (!opt->name) if (opt->name)
{ {
if (exec_mode == MODE_DEBUG && **ptr != '-') if (opt->has_arg && arg != NULL) opt->func( arg );
{ else opt->func( "" );
/* this a file name to parse for debug channels */ }
parse_debug_channels( current_src_dir, *ptr ); else /* keep this argument */
continue; {
} if (last != ptr) *last = *ptr;
fprintf( stderr, "Unrecognized option '%s'\n", *ptr ); last++;
do_usage();
} }
if (opt->has_arg && arg!=NULL) opt->func( arg );
else opt->func( "" );
} }
*last = NULL;
} }
...@@ -387,18 +373,23 @@ int main(int argc, char **argv) ...@@ -387,18 +373,23 @@ int main(int argc, char **argv)
switch (ParseTopLevel( input_file, 0 )) switch (ParseTopLevel( input_file, 0 ))
{ {
case SPEC_WIN16: case SPEC_WIN16:
if (argv[1])
fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
BuildSpec16File( output_file ); BuildSpec16File( output_file );
break; break;
case SPEC_WIN32: case SPEC_WIN32:
read_undef_symbols( argv + 1 );
BuildSpec32File( output_file ); BuildSpec32File( output_file );
break; break;
default: assert(0); default: assert(0);
} }
break; break;
case MODE_EXE: case MODE_EXE:
read_undef_symbols( argv + 1 );
BuildSpec32File( output_file ); BuildSpec32File( output_file );
break; break;
case MODE_DEF: case MODE_DEF:
if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
switch (ParseTopLevel( input_file, 1 )) switch (ParseTopLevel( input_file, 1 ))
{ {
case SPEC_WIN16: case SPEC_WIN16:
...@@ -411,15 +402,17 @@ int main(int argc, char **argv) ...@@ -411,15 +402,17 @@ int main(int argc, char **argv)
} }
break; break;
case MODE_DEBUG: case MODE_DEBUG:
BuildDebugFile( output_file ); BuildDebugFile( output_file, current_src_dir, argv + 1 );
break; break;
case MODE_GLUE: case MODE_GLUE:
BuildGlue( output_file, input_file ); BuildGlue( output_file, current_src_dir, argv + 1 );
break; break;
case MODE_RELAY16: case MODE_RELAY16:
if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
BuildRelays16( output_file ); BuildRelays16( output_file );
break; break;
case MODE_RELAY32: case MODE_RELAY32:
if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
BuildRelays32( output_file ); BuildRelays32( output_file );
break; break;
default: default:
......
...@@ -595,20 +595,8 @@ void parse_debug_channels( const char *srcdir, const char *filename ) ...@@ -595,20 +595,8 @@ void parse_debug_channels( const char *srcdir, const char *filename )
{ {
FILE *file; FILE *file;
int eol_seen = 1; int eol_seen = 1;
char *fullname = NULL;
if (srcdir) file = open_input_file( srcdir, filename );
{
fullname = xmalloc( strlen(srcdir) + strlen(filename) + 2 );
strcpy( fullname, srcdir );
strcat( fullname, "/" );
strcat( fullname, filename );
}
else fullname = xstrdup( filename );
if (!(file = fopen( fullname, "r" ))) fatal_error( "Cannot open file '%s'\n", fullname );
input_file_name = fullname;
current_line = 1;
while (fgets( ParseBuffer, sizeof(ParseBuffer), file )) while (fgets( ParseBuffer, sizeof(ParseBuffer), file ))
{ {
char *channel, *end, *p = ParseBuffer; char *channel, *end, *p = ParseBuffer;
...@@ -645,8 +633,5 @@ void parse_debug_channels( const char *srcdir, const char *filename ) ...@@ -645,8 +633,5 @@ void parse_debug_channels( const char *srcdir, const char *filename )
} }
current_line++; current_line++;
} }
fclose( file ); close_input_file( file );
input_file_name = NULL;
current_line = 0;
free( fullname );
} }
...@@ -458,10 +458,7 @@ static void BuildCallTo16Func( FILE *outfile, const char *profile, const char *p ...@@ -458,10 +458,7 @@ static void BuildCallTo16Func( FILE *outfile, const char *profile, const char *p
if (!strncmp( "word_", profile, 5 )) short_ret = 1; if (!strncmp( "word_", profile, 5 )) short_ret = 1;
else if (strncmp( "long_", profile, 5 )) else if (strncmp( "long_", profile, 5 ))
{ fatal_error( "Invalid function name '%s'\n", profile );
fprintf( stderr, "Invalid function name '%s'.\n", profile );
exit(1);
}
fprintf( outfile, "unsigned %s __stdcall %s_CallTo16_%s( void (*proc)()", fprintf( outfile, "unsigned %s __stdcall %s_CallTo16_%s( void (*proc)()",
short_ret? "short" : "int", prefix, profile ); short_ret? "short" : "int", prefix, profile );
...@@ -473,6 +470,7 @@ static void BuildCallTo16Func( FILE *outfile, const char *profile, const char *p ...@@ -473,6 +470,7 @@ static void BuildCallTo16Func( FILE *outfile, const char *profile, const char *p
{ {
case 'w': fprintf( outfile, "unsigned short" ); argsize += 2; break; case 'w': fprintf( outfile, "unsigned short" ); argsize += 2; break;
case 'l': fprintf( outfile, "unsigned int" ); argsize += 4; break; case 'l': fprintf( outfile, "unsigned int" ); argsize += 4; break;
default: fatal_error( "Invalid letter '%c' in function name '%s'\n", args[i], profile );
} }
fprintf( outfile, " arg%d", i+1 ); fprintf( outfile, " arg%d", i+1 );
} }
...@@ -907,7 +905,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -907,7 +905,7 @@ void BuildSpec16File( FILE *outfile )
* *
* Build the 16-bit-to-Wine/Wine-to-16-bit callback glue code * Build the 16-bit-to-Wine/Wine-to-16-bit callback glue code
*/ */
void BuildGlue( FILE *outfile, FILE *infile ) void BuildGlue( FILE *outfile, const char *srcdir, char **argv )
{ {
char buffer[1024]; char buffer[1024];
...@@ -924,26 +922,33 @@ void BuildGlue( FILE *outfile, FILE *infile ) ...@@ -924,26 +922,33 @@ void BuildGlue( FILE *outfile, FILE *infile )
/* Build the callback glue functions */ /* Build the callback glue functions */
while (fgets( buffer, sizeof(buffer), infile )) while (*argv)
{
if (strstr( buffer, "### start build ###" )) break;
}
while (fgets( buffer, sizeof(buffer), infile ))
{ {
char *p; FILE *infile = open_input_file( srcdir, *argv );
if ( (p = strstr( buffer, "CallTo16_" )) != NULL )
while (fgets( buffer, sizeof(buffer), infile ))
{ {
char *q, *profile = p + strlen( "CallTo16_" ); current_line++;
for (q = profile; (*q == '_') || isalpha(*q); q++ ) if (strstr( buffer, "### start build ###" )) break;
;
*q = '\0';
for (q = p-1; q > buffer && ((*q == '_') || isalnum(*q)); q-- )
;
if ( ++q < p ) p[-1] = '\0'; else q = "";
BuildCallTo16Func( outfile, profile, q );
} }
if (strstr( buffer, "### stop build ###" )) break; while (fgets( buffer, sizeof(buffer), infile ))
{
char *p;
if ( (p = strstr( buffer, "CallTo16_" )) != NULL )
{
char *q, *profile = p + strlen( "CallTo16_" );
for (q = profile; (*q == '_') || isalpha(*q); q++ )
;
*q = '\0';
for (q = p-1; q > buffer && ((*q == '_') || isalnum(*q)); q-- )
;
if ( ++q < p ) p[-1] = '\0'; else q = "";
BuildCallTo16Func( outfile, profile, q );
}
current_line++;
if (strstr( buffer, "### stop build ###" )) break;
}
close_input_file( infile );
argv++;
} }
fclose( infile );
} }
...@@ -894,11 +894,13 @@ void BuildDef32File(FILE *outfile) ...@@ -894,11 +894,13 @@ void BuildDef32File(FILE *outfile)
* *
* Build the debugging channels source file. * Build the debugging channels source file.
*/ */
void BuildDebugFile( FILE *outfile ) void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv )
{ {
int nr_debug; int nr_debug;
char *prefix, *p; char *prefix, *p;
while (*argv) parse_debug_channels( srcdir, *argv++ );
output_standard_file_header( outfile ); output_standard_file_header( outfile );
nr_debug = output_debug( outfile ); nr_debug = output_debug( outfile );
if (!nr_debug) if (!nr_debug)
......
...@@ -153,6 +153,46 @@ void dump_bytes( FILE *outfile, const unsigned char *data, int len, ...@@ -153,6 +153,46 @@ void dump_bytes( FILE *outfile, const unsigned char *data, int len,
/******************************************************************* /*******************************************************************
* open_input_file
*
* Open a file in the given srcdir and set the input_file_name global variable.
*/
FILE *open_input_file( const char *srcdir, const char *name )
{
char *fullname;
FILE *file;
if (srcdir)
{
fullname = xmalloc( strlen(srcdir) + strlen(name) + 2 );
strcpy( fullname, srcdir );
strcat( fullname, "/" );
strcat( fullname, name );
}
else fullname = xstrdup( name );
if (!(file = fopen( fullname, "r" ))) fatal_error( "Cannot open file '%s'\n", fullname );
input_file_name = fullname;
current_line = 1;
return file;
}
/*******************************************************************
* close_input_file
*
* Close the current input file (must have been opened with open_input_file).
*/
void close_input_file( FILE *file )
{
fclose( file );
free( input_file_name );
input_file_name = NULL;
current_line = 0;
}
/*******************************************************************
* make_c_identifier * make_c_identifier
* *
* Map a string to a valid C identifier. * Map a string to a valid C identifier.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.SH NAME .SH NAME
winebuild \- Wine dll builder winebuild \- Wine dll builder
.SH SYNOPSIS .SH SYNOPSIS
.BI "winebuild " "[options] " "[inputfile]" .BI winebuild\ [options]\ [input\ files]
.SH DESCRIPTION .SH DESCRIPTION
.B winebuild .B winebuild
generates the C and assembly files that are necessary to build a Wine generates the C and assembly files that are necessary to build a Wine
...@@ -23,29 +23,42 @@ what you want winebuild to generate. ...@@ -23,29 +23,42 @@ what you want winebuild to generate.
Build a C file from a spec file (see \fBSPEC FILE SYNTAX\fR for Build a C file from a spec file (see \fBSPEC FILE SYNTAX\fR for
details). The resulting C file must be compiled and linked to the details). The resulting C file must be compiled and linked to the
other object files to build a working Wine dll. other object files to build a working Wine dll.
.TP .br
.BI \-def\ file.spec In that mode, the
Build a .def file from a spec file. This is used when building dlls .I input files
with a PE (Win32) compiler. should be the list of all object files that will be linked into the
final dll, to allow
.B winebuild
to get the list of all undefined symbols that need to be imported from
other dlls.
.TP .TP
.BI \-exe\ name .BI \-exe\ name
Build a C file for the named executable. This is basically the same as Build a C file for the named executable. This is basically the same as
the -spec mode except that it doesn't require a .spec file as input, the -spec mode except that it doesn't require a .spec file as input,
since an executable doesn't export functions. The resulting C file since an executable doesn't export functions. The resulting C file
must be compiled and linked to the other object files to build a must be compiled and linked to the other object files to build a
working Wine executable. working Wine executable, and all the other object files must be listed
as
.I input files.
.TP
.BI \-def\ file.spec
Build a .def file from a spec file. This is used when building dlls
with a PE (Win32) compiler.
.TP .TP
.BI \-debug\ [files] .B \-debug
Build a C file containing the definitions for debugging channels. The Build a C file containing the definitions for debugging channels. In
\fIfiles\fR argument is a list of C files to search for debug channel that mode the
.I input files
should be a list of C files to search for debug channel
definitions. The resulting C file must be compiled and linked with the definitions. The resulting C file must be compiled and linked with the
dll. dll.
.TP .TP
.BI \-glue\ file.c .B \-glue
Build a C file containing the glue code for the 16-bit calls contained Build a C file containing the glue code for the 16-bit calls contained
in the \fIfile.c\fR source. These calls must be specified in the in the
source file using special markers, as described in the \fBGLUE .I input files.
FUNCTIONS\fR section. These calls must be specified in the source files using special
markers, as described in the \fBGLUE FUNCTIONS\fR section.
.TP .TP
.B \-relay16 .B \-relay16
Generate the assembly code for the 16-bit relay routines. This is for Generate the assembly code for the 16-bit relay routines. This is for
...@@ -58,7 +71,8 @@ Wine internal usage only, you should never need to use this option. ...@@ -58,7 +71,8 @@ Wine internal usage only, you should never need to use this option.
.TP .TP
.BI \-C\ directory .BI \-C\ directory
Change to the specified directory before reading source files. Only Change to the specified directory before reading source files. Only
meaningful in \fB-debug\fR mode. meaningful in
.BR \-debug\ and\ -glue\ modes.
.TP .TP
.BI \-D\ symbol .BI \-D\ symbol
Ignored for compatibility with the C compiler. Ignored for compatibility with the C compiler.
...@@ -125,8 +139,6 @@ Load resources from the specified binary resource file. The ...@@ -125,8 +139,6 @@ Load resources from the specified binary resource file. The
\fIrsrc.res\fR can be produced from a source resource file with \fIrsrc.res\fR can be produced from a source resource file with
.BR wrc(1) .BR wrc(1)
(or with a Windows resource compiler). (or with a Windows resource compiler).
.BI \-sym\ file.o
Read the list of undefined symbols from the object file file.o.
.TP .TP
.B \-w .B \-w
Turn on warnings. Turn on warnings.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment