Commit 492ac292 authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for building a dll from a .def file for cases where we

don't want to write a full .spec. Renamed --spec option to --dll for consistency.
parent 14743a0f
......@@ -129,7 +129,7 @@ LINTS = $(C_SRCS:.c=.ln)
$(WINDRES) -i $< -o $@
.spec.spec.c:
$(WINEBUILD) $(DEFS) -o $@ --main-module $(MODULE) --spec $<
$(WINEBUILD) $(DEFS) -o $@ --main-module $(MODULE) --dll $<
.spec.spec.def:
$(WINEBUILD) $(DEFS) -o $@ --def $<
......
......@@ -27,7 +27,7 @@ all: $(MODULE)$(DLLEXT) $(SUBDIRS)
# Rules for .so files
$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --spec $(SRCDIR)/$(MAINSPEC) $(DLLMODE:%=--mode %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll $(SRCDIR)/$(MAINSPEC) $(DLLMODE:%=--mode %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
$(MODULE).so: $(MAINSPEC).o $(ALL_OBJS) Makefile.in
$(LDDLL) $(MAINSPEC).o $(ALL_OBJS) -o $@ -L$(DLLDIR) $(ALL_LIBS) -lc
......
......@@ -76,7 +76,7 @@ EXTRASUBDIRS = \
# Special rules for 16-bit resource and spec files
gdi.exe.spec.c: gdi.exe.spec version16.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --heap 65520 --main-module $(MODULE) --res version16.res --spec $(SRCDIR)/gdi.exe.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --heap 65520 --main-module $(MODULE) --res version16.res --dll $(SRCDIR)/gdi.exe.spec
version16.res: version16.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
......
......@@ -113,7 +113,7 @@ relay16asm.s: $(WINEBUILD)
# Special rules for 16-bit resource and spec files
krnl386.exe.spec.c: krnl386.exe.spec version16.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll-name kernel --main-module $(MODULE) --res version16.res --spec $(SRCDIR)/krnl386.exe.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll-name kernel --main-module $(MODULE) --res version16.res --dll $(SRCDIR)/krnl386.exe.spec
version16.res: version16.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
......
......@@ -72,10 +72,10 @@ version16.res: version16.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
shell.spec.c: shell.spec version16.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res version16.res --spec $(SRCDIR)/shell.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res version16.res --dll $(SRCDIR)/shell.spec
authors.c: $(TOPSRCDIR)/AUTHORS
(LANG=C; echo 'const char * const SHELL_Authors[] = {' && \
(LC_ALL=C; echo 'const char * const SHELL_Authors[] = {' && \
sed -e '1,2d' -e 's/\(.*\)/ \"\1\",/' $(TOPSRCDIR)/AUTHORS && \
echo ' 0 };') >$@ || ($(RM) $@ && false)
......
......@@ -168,13 +168,13 @@ EXTRASUBDIRS = \
# Special rules for 16-bit resource and spec files
user.exe.spec.c: user.exe.spec resources/version16.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --heap 65520 --main-module $(MODULE) --res resources/version16.res --spec $(SRCDIR)/user.exe.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --heap 65520 --main-module $(MODULE) --res resources/version16.res --dll $(SRCDIR)/user.exe.spec
display.drv.spec.c: display.drv.spec resources/display.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res resources/display.res --spec $(SRCDIR)/display.drv.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res resources/display.res --dll $(SRCDIR)/display.drv.spec
mouse.drv.spec.c: mouse.drv.spec resources/mouse.res
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res resources/mouse.res --spec $(SRCDIR)/mouse.drv.spec
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res resources/mouse.res --dll $(SRCDIR)/mouse.drv.spec
resources/display.res: resources/display.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/resources/display.rc
......
......@@ -68,7 +68,6 @@ typedef struct
typedef struct
{
int n_args;
char arg_types[21];
} ORD_FUNCTION;
......@@ -170,6 +169,9 @@ 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,
const char *label, int constant );
extern int remove_stdcall_decoration( char *name );
extern DLLSPEC *alloc_dll_spec(void);
extern void free_dll_spec( DLLSPEC *spec );
extern const char *make_c_identifier( const char *str );
extern int get_alignment(int alignBoundary);
......@@ -184,7 +186,6 @@ extern void load_res16_file( const char *name, DLLSPEC *spec );
extern int output_res16_data( FILE *outfile, DLLSPEC *spec );
extern int output_res16_directory( unsigned char *buffer, DLLSPEC *spec );
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
extern int parse_debug_channels( const char *srcdir, const char *filename );
extern void BuildRelays16( FILE *outfile );
extern void BuildRelays32( FILE *outfile );
......@@ -192,7 +193,10 @@ extern void BuildSpec16File( FILE *outfile, DLLSPEC *spec );
extern void BuildSpec32File( FILE *outfile, DLLSPEC *spec );
extern void BuildDef32File( FILE *outfile, DLLSPEC *spec );
extern void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv );
extern int ParseTopLevel( FILE *file, DLLSPEC *spec );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
extern int parse_def_file( FILE *file, DLLSPEC *spec );
extern int parse_debug_channels( const char *srcdir, const char *filename );
/* global variables */
......
......@@ -56,17 +56,17 @@ char **lib_path = NULL;
char *input_file_name = NULL;
const char *output_file_name = NULL;
static FILE *input_file;
static FILE *output_file;
static const char *current_src_dir;
static int nb_res_files;
static char **res_files;
static char *spec_file_name;
/* execution mode */
enum exec_mode_values
{
MODE_NONE,
MODE_SPEC,
MODE_DLL,
MODE_EXE,
MODE_DEF,
MODE_DEBUG,
......@@ -87,7 +87,10 @@ static void set_dll_file_name( const char *name, DLLSPEC *spec )
if ((p = strrchr( name, '/' ))) name = p + 1;
spec->file_name = xmalloc( strlen(name) + 5 );
strcpy( spec->file_name, name );
if ((p = strrchr( spec->file_name, '.' )) && !strcmp( p, ".spec" )) *p = 0;
if ((p = strrchr( spec->file_name, '.' )))
{
if (!strcmp( p, ".spec" ) || !strcmp( p, ".def" )) *p = 0;
}
if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".dll" );
}
......@@ -126,7 +129,7 @@ static const char usage_str[] =
" --version Print the version and exit\n"
" -w --warnings Turn on warnings\n"
"\nMode options:\n"
" --spec=FILE.SPEC Build a .c file from a spec file\n"
" --dll=FILE Build a .c file from a .spec or .def file\n"
" --def=FILE.SPEC Build a .def file from a spec file\n"
" --exe=NAME Build a .c file for the named executable\n"
" --debug [FILES] Build a .c file with the debug channels declarations\n"
......@@ -136,7 +139,7 @@ static const char usage_str[] =
enum long_options_values
{
LONG_OPT_SPEC = 1,
LONG_OPT_DLL = 1,
LONG_OPT_DEF,
LONG_OPT_EXE,
LONG_OPT_DEBUG,
......@@ -149,13 +152,14 @@ static const char short_options[] = "C:D:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:w";
static const struct option long_options[] =
{
{ "spec", 1, 0, LONG_OPT_SPEC },
{ "dll", 1, 0, LONG_OPT_DLL },
{ "def", 1, 0, LONG_OPT_DEF },
{ "exe", 1, 0, LONG_OPT_EXE },
{ "debug", 0, 0, LONG_OPT_DEBUG },
{ "relay16", 0, 0, LONG_OPT_RELAY16 },
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
{ "version", 0, 0, LONG_OPT_VERSION },
{ "spec", 1, 0, LONG_OPT_DLL }, /* for backwards compatibility */
/* aliases for short options */
{ "source-dir", 1, 0, 'C' },
{ "delay-lib", 1, 0, 'd' },
......@@ -287,14 +291,14 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case 'w':
display_warnings = 1;
break;
case LONG_OPT_SPEC:
set_exec_mode( MODE_SPEC );
input_file = open_input_file( NULL, optarg );
case LONG_OPT_DLL:
set_exec_mode( MODE_DLL );
spec_file_name = xstrdup( optarg );
set_dll_file_name( optarg, spec );
break;
case LONG_OPT_DEF:
set_exec_mode( MODE_DEF );
input_file = open_input_file( NULL, optarg );
spec_file_name = xstrdup( optarg );
set_dll_file_name( optarg, spec );
break;
case LONG_OPT_EXE:
......@@ -357,65 +361,59 @@ static void load_resources( char *argv[], DLLSPEC *spec )
}
}
static int parse_input_file( DLLSPEC *spec )
{
FILE *input_file = open_input_file( NULL, spec_file_name );
char *extension = strrchr( spec_file_name, '.' );
if (extension && !strcmp( extension, ".def" ))
return parse_def_file( input_file, spec );
else
return parse_spec_file( input_file, spec );
close_input_file( input_file );
}
/*******************************************************************
* main
*/
int main(int argc, char **argv)
{
DLLSPEC spec;
spec.file_name = NULL;
spec.dll_name = NULL;
spec.owner_name = NULL;
spec.init_func = NULL;
spec.type = SPEC_WIN32;
spec.mode = SPEC_MODE_DLL;
spec.base = MAX_ORDINALS;
spec.limit = 0;
spec.stack_size = 0;
spec.heap_size = 0;
spec.nb_entry_points = 0;
spec.alloc_entry_points = 0;
spec.nb_names = 0;
spec.nb_resources = 0;
spec.entry_points = NULL;
spec.names = NULL;
spec.ordinals = NULL;
spec.resources = NULL;
DLLSPEC *spec = alloc_dll_spec();
output_file = stdout;
argv = parse_options( argc, argv, &spec );
argv = parse_options( argc, argv, spec );
switch(exec_mode)
{
case MODE_SPEC:
load_resources( argv, &spec );
if (!ParseTopLevel( input_file, &spec )) break;
switch (spec.type)
case MODE_DLL:
load_resources( argv, spec );
if (!parse_input_file( spec )) break;
switch (spec->type)
{
case SPEC_WIN16:
if (argv[0])
fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
BuildSpec16File( output_file, &spec );
BuildSpec16File( output_file, spec );
break;
case SPEC_WIN32:
read_undef_symbols( argv );
BuildSpec32File( output_file, &spec );
BuildSpec32File( output_file, spec );
break;
default: assert(0);
}
break;
case MODE_EXE:
if (spec.type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" );
load_resources( argv, &spec );
if (spec->type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" );
load_resources( argv, spec );
read_undef_symbols( argv );
BuildSpec32File( output_file, &spec );
BuildSpec32File( output_file, spec );
break;
case MODE_DEF:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
if (spec.type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
if (!ParseTopLevel( input_file, &spec )) break;
BuildDef32File( output_file, &spec );
if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
if (!parse_input_file( spec )) break;
BuildDef32File( output_file, spec );
break;
case MODE_DEBUG:
BuildDebugFile( output_file, current_src_dir, argv );
......
......@@ -210,6 +210,83 @@ void close_input_file( FILE *file )
/*******************************************************************
* remove_stdcall_decoration
*
* Remove a possible @xx suffix from a function name.
* Return the numerical value of the suffix, or -1 if none.
*/
int remove_stdcall_decoration( char *name )
{
char *p, *end = strrchr( name, '@' );
if (!end || !end[1] || end == name) return -1;
/* make sure all the rest is digits */
for (p = end + 1; *p; p++) if (!isdigit(*p)) return -1;
*end = 0;
return atoi( end + 1 );
}
/*******************************************************************
* alloc_dll_spec
*
* Create a new dll spec file descriptor
*/
DLLSPEC *alloc_dll_spec(void)
{
DLLSPEC *spec;
spec = xmalloc( sizeof(*spec) );
spec->file_name = NULL;
spec->dll_name = NULL;
spec->owner_name = NULL;
spec->init_func = NULL;
spec->type = SPEC_WIN32;
spec->mode = SPEC_MODE_DLL;
spec->base = MAX_ORDINALS;
spec->limit = 0;
spec->stack_size = 0;
spec->heap_size = 0;
spec->nb_entry_points = 0;
spec->alloc_entry_points = 0;
spec->nb_names = 0;
spec->nb_resources = 0;
spec->entry_points = NULL;
spec->names = NULL;
spec->ordinals = NULL;
spec->resources = NULL;
return spec;
}
/*******************************************************************
* free_dll_spec
*
* Free dll spec file descriptor
*/
void free_dll_spec( DLLSPEC *spec )
{
int i;
for (i = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
free( odp->name );
free( odp->export_name );
free( odp->link_name );
}
free( spec->file_name );
free( spec->dll_name );
free( spec->owner_name );
free( spec->init_func );
free( spec->entry_points );
free( spec->names );
free( spec->ordinals );
free( spec->resources );
free( spec );
}
/*******************************************************************
* make_c_identifier
*
* Map a string to a valid C identifier.
......
......@@ -19,10 +19,11 @@ option can be specified, as described in the \fBOPTIONS\fR section.
You have to specify exactly one of the following options, depending on
what you want winebuild to generate.
.TP
.BI \--spec=\ file.spec
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
other object files to build a working Wine dll.
.BI \--dll=\ filename
Build a C file from a .spec file (see \fBSPEC FILE SYNTAX\fR for
details), or from a standard Windows .def file. The resulting C file
must be compiled and linked to the other object files to build a
working Wine dll.
.br
In that mode, the
.I input files
......@@ -34,7 +35,7 @@ other dlls.
.TP
.BI \--exe=\ name
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 --dll mode except that it doesn't require a .spec file as input,
since an executable doesn't export functions. The resulting C file
must be compiled and linked to the other object files to build a
working Wine executable, and all the other object files must be listed
......@@ -130,7 +131,7 @@ imported from it is actually called).
.BI \-M,\ --main-module= module
Specify that we are building a 16-bit dll, that will ultimately be
linked together with the 32-bit dll specified in \fImodule\fR. Only
meaningful in \fB--spec\fR mode.
meaningful in \fB--dll\fR mode.
.TP
.BI \-m,\ --mode= mode
Set the executable or dll mode, which can be one of the following:
......
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