Stubs declared in .spec files were not generated or exported for PE (MinGW)
builds. The patch below fixes that. It adds a new mode to winebuild, --pedll,
which generates the stubs.
Since it's a global change I'm sending it here for review first.
Ge van Geldorp.
Index: Make.rules.in
===================================================================
RCS file: /home/wine/wine/Make.rules.in,v
retrieving revision 1.179
diff -u -r1.179 Make.rules.in
--- Make.rules.in 7 Oct 2004 03:12:44 -0000 1.179
+++ Make.rules.in 24 Nov 2004 20:49:51 -0000
@@ -104,7 +104,7 @@
api_manext = 3w
conf_manext = 5
CLEAN_FILES = *.o *.a *.so *.ln *.$(LIBEXT) \\\#*\\\# *~ *% .\\\#* *.bak *.orig *.rej \
- *.flc *.spec.c *.spec.def *.dbg.c *.tab.c *.tab.h @LEX_OUTPUT_ROOT@.c core
+ *.flc *.spec.c *.spec.def *.dbg.c *.pedll.c *.tab.c *.tab.h @LEX_OUTPUT_ROOT@.c core
OBJS = $(C_SRCS:.c=.o) $(EXTRA_OBJS)
@@ -113,7 +113,7 @@
# Implicit rules
-.SUFFIXES: .mc .rc .mc.rc .res .res.o .spec .spec.c .spec.def .idl .h .ok .sfd .ttf
+.SUFFIXES: .mc .rc .mc.rc .res .res.o .spec .spec.c .spec.def .pedll.c .idl .h .ok .sfd .ttf
.c.o:
$(CC) -c $(ALLCFLAGS) -o $@ $<
@@ -135,6 +135,9 @@
.spec.spec.def:
$(WINEBUILD) -w $(DEFS) -o $@ --def $<
+
+.spec.pedll.c:
+ $(WINEBUILD) $(DEFS) -o $@ --pedll $<
.idl.h:
$(WIDL) $(IDLFLAGS) -h -H $@ $<
Index: dlls/Makedll.rules.in
===================================================================
RCS file: /home/wine/wine/dlls/Makedll.rules.in,v
retrieving revision 1.69
diff -u -r1.69 Makedll.rules.in
--- dlls/Makedll.rules.in 19 Oct 2004 23:06:12 -0000 1.69
+++ dlls/Makedll.rules.in 24 Nov 2004 20:49:53 -0000
@@ -31,8 +31,8 @@
# Rules for .dll files
-$(MODULE): $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(SPEC_DEF) $(IMPORTLIBS) Makefile.in
- $(DLLWRAP) -k --def $(SPEC_DEF) -o $@ $(RCOBJS) $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(ALL_LIBS)
+$(MODULE): $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(MODULE:%.dll=%).pedll.o $(SPEC_DEF) $(IMPORTLIBS) $(DLLDIR)/libntdll.$(IMPLIBEXT) Makefile.in
+ $(DLLWRAP) -k --def $(SPEC_DEF) -o $@ $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(MODULE:%.dll=%).pedll.o -L$(DLLDIR) $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) -lntdll $(ALL_LIBS)
$(SPEC_DEF): $(WINEBUILD)
Index: tools/winebuild/build.h
===================================================================
RCS file: /home/wine/wine/tools/winebuild/build.h,v
retrieving revision 1.54
diff -u -r1.54 build.h
--- tools/winebuild/build.h 8 Oct 2004 21:11:18 -0000 1.54
+++ tools/winebuild/build.h 24 Nov 2004 20:50:34 -0000
@@ -185,6 +185,7 @@
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 void BuildPedllFile( FILE *outfile, DLLSPEC *spec );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
extern int parse_def_file( FILE *file, DLLSPEC *spec );
Index: tools/winebuild/main.c
===================================================================
RCS file: /home/wine/wine/tools/winebuild/main.c,v
retrieving revision 1.57
diff -u -r1.57 main.c
--- tools/winebuild/main.c 19 Oct 2004 23:09:02 -0000 1.57
+++ tools/winebuild/main.c 24 Nov 2004 20:50:34 -0000
@@ -77,7 +77,8 @@
MODE_DEF,
MODE_DEBUG,
MODE_RELAY16,
- MODE_RELAY32
+ MODE_RELAY32,
+ MODE_PEDLL
};
static enum exec_mode_values exec_mode = MODE_NONE;
@@ -164,7 +165,8 @@
" --exe=NAME Build a .c file for the named executable\n"
" --debug [FILES] Build a .c file with the debug channels declarations\n"
" --relay16 Build the 16-bit relay assembly routines\n"
-" --relay32 Build the 32-bit relay assembly routines\n\n"
+" --relay32 Build the 32-bit relay assembly routines\n"
+" --pedll Build a .c file for PE dll\n\n"
"The mode options are mutually exclusive; you must specify one and only one.\n\n";
enum long_options_values
@@ -178,7 +180,8 @@
LONG_OPT_RELAY16,
LONG_OPT_RELAY32,
LONG_OPT_SUBSYSTEM,
- LONG_OPT_VERSION
+ LONG_OPT_VERSION,
+ LONG_OPT_PEDLL
};
static const char short_options[] = "C:D:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:w";
@@ -195,6 +198,7 @@
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
{ "subsystem",1, 0, LONG_OPT_SUBSYSTEM },
{ "version", 0, 0, LONG_OPT_VERSION },
+ { "pedll", 1, 0, LONG_OPT_PEDLL },
/* aliases for short options */
{ "source-dir", 1, 0, 'C' },
{ "delay-lib", 1, 0, 'd' },
@@ -356,6 +360,11 @@
case LONG_OPT_VERSION:
printf( "winebuild version " PACKAGE_VERSION "\n" );
exit(0);
+ case LONG_OPT_PEDLL:
+ set_exec_mode( MODE_PEDLL );
+ spec_file_name = xstrdup( optarg );
+ set_dll_file_name( optarg, spec );
+ break;
case '?':
usage(1);
break;
@@ -460,6 +469,11 @@
case MODE_RELAY32:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
BuildRelays32( output_file );
+ break;
+ case MODE_PEDLL:
+ if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
+ if (!parse_input_file( spec )) break;
+ BuildPedllFile( output_file, spec );
break;
default:
usage(1);
Index: tools/winebuild/spec32.c
===================================================================
RCS file: /home/wine/wine/tools/winebuild/spec32.c,v
retrieving revision 1.84
diff -u -r1.84 spec32.c
--- tools/winebuild/spec32.c 18 Oct 2004 21:27:52 -0000 1.84
+++ tools/winebuild/spec32.c 24 Nov 2004 20:50:34 -0000
@@ -860,12 +860,10 @@
int is_data = 0;
if (!odp) continue;
- if (odp->flags & FLAG_REGISTER) continue;
- if (odp->type == TYPE_STUB) continue;
-
if (odp->name) name = odp->name;
+ else if (odp->type == TYPE_STUB) name = make_internal_name( odp, spec, "stub" );
else if (odp->export_name) name = odp->export_name;
- else continue;
+ else name = make_internal_name( odp, spec, "noname_export" );
fprintf(outfile, " %s", name);
@@ -895,11 +893,37 @@
}
break;
}
+ case TYPE_STUB:
+ {
+ if (!kill_at)
+ {
+ const char *check = name + strlen(name);
+ while (name != check &&
+ '0' <= check[-1] && check[-1] <= '9')
+ {
+ check--;
+ }
+ if (name != check && check != name + strlen(name) &&
+ '@' == check[-1])
+ {
+ fprintf(outfile, "%s", check - 1);
+ }
+ }
+ if (NULL != odp->name)
+ {
+ fprintf(outfile, "=%s", make_internal_name( odp, spec, "stub" ));
+ }
+ break;
+ }
default:
assert(0);
}
fprintf( outfile, " @%d", odp->ordinal );
+#if 0 /* MinGW binutils cannot handle this correctly */
if (!odp->name) fprintf( outfile, " NONAME" );
+#else
+ if (!odp->name && (odp->type == TYPE_STUB || odp->export_name)) fprintf( outfile, " NONAME" );
+#endif
if (is_data) fprintf( outfile, " DATA" );
if (odp->flags & FLAG_PRIVATE) fprintf( outfile, " PRIVATE" );
fprintf( outfile, "\n" );
@@ -1005,4 +1029,25 @@
"}\n", prefix );
free( prefix );
+}
+
+
+/*******************************************************************
+ * BuildPedllFile
+ *
+ * Build a PE DLL C file from a spec file.
+ */
+void BuildPedllFile( FILE *outfile, DLLSPEC *spec )
+{
+ int nr_exports;
+
+ nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
+ output_standard_file_header( outfile );
+
+ if (nr_exports)
+ {
+ /* Output the stub functions */
+
+ output_stub_funcs( outfile, spec );
+ }
}