Support .exe's with exported functions
Dimitrie O. Paun
dpaun at rogers.com
Tue Mar 8 00:12:58 CST 2005
To build an .exe with exported functions, simply specify
the .spec file on the command line.
ChangeLog
Add support for .exe's with exported functions
Index: Make.rules.in
===================================================================
RCS file: /var/cvs/wine/Make.rules.in,v
retrieving revision 1.182
diff -u -r1.182 Make.rules.in
--- Make.rules.in 8 Feb 2005 12:13:10 -0000 1.182
+++ Make.rules.in 8 Mar 2005 05:23:50 -0000
@@ -131,10 +131,10 @@
$(WINDRES) -i $< -o $@
.spec.spec.c:
- $(WINEBUILD) $(DEFS) -o $@ --main-module $(MODULE) --dll $<
+ $(WINEBUILD) $(DEFS) --dll -o $@ --main-module $(MODULE) --export $<
.spec.spec.def:
- $(WINEBUILD) -w $(DEFS) -o $@ --def $<
+ $(WINEBUILD) -w $(DEFS) --def -o $@ --export $<
.idl.h:
$(WIDL) $(IDLFLAGS) -h -H $@ $<
Index: ./dlls/shell32/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/Makefile.in,v
retrieving revision 1.86
diff -u -r1.86 Makefile.in
--- ./dlls/shell32/Makefile.in 27 Oct 2004 00:47:53 -0000 1.86
+++ ./dlls/shell32/Makefile.in 8 Mar 2005 05:22:27 -0000
@@ -77,7 +77,7 @@
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
shell.spec.c: shell.spec version16.res
- $(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res version16.res --dll $(SRCDIR)/shell.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --main-module $(MODULE) --res version16.res --export $(SRCDIR)/shell.spec
authors.c: $(TOPSRCDIR)/AUTHORS
(LC_ALL=C; export LC_ALL; echo 'const char * const SHELL_Authors[] = {' && \
Index: ./dlls/kernel/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/kernel/Makefile.in,v
retrieving revision 1.116
diff -u -r1.116 Makefile.in
--- ./dlls/kernel/Makefile.in 3 Feb 2005 16:58:21 -0000 1.116
+++ ./dlls/kernel/Makefile.in 8 Mar 2005 05:21:40 -0000
@@ -106,7 +106,7 @@
# 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 --dll $(SRCDIR)/krnl386.exe.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --dll-name kernel --main-module $(MODULE) --res version16.res --export $(SRCDIR)/krnl386.exe.spec
version16.res: version16.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
Index: ./dlls/Makedll.rules.in
===================================================================
RCS file: /var/cvs/wine/dlls/Makedll.rules.in,v
retrieving revision 1.70
diff -u -r1.70 Makedll.rules.in
--- ./dlls/Makedll.rules.in 7 Jan 2005 17:15:47 -0000 1.70
+++ ./dlls/Makedll.rules.in 8 Mar 2005 05:19:10 -0000
@@ -56,7 +56,7 @@
# Rule to explicitly generate the .spec.c for debugging
$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD)
- $(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
# Rules for auto documentation
Index: ./dlls/gdi/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/gdi/Makefile.in,v
retrieving revision 1.63
diff -u -r1.63 Makefile.in
--- ./dlls/gdi/Makefile.in 11 Aug 2004 23:59:07 -0000 1.63
+++ ./dlls/gdi/Makefile.in 8 Mar 2005 05:18:38 -0000
@@ -71,7 +71,7 @@
# 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 --dll $(SRCDIR)/gdi.exe.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --heap 65520 --main-module $(MODULE) --res version16.res --export $(SRCDIR)/gdi.exe.spec
version16.res: version16.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
Index: ./dlls/user/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/user/Makefile.in,v
retrieving revision 1.86
diff -u -r1.86 Makefile.in
--- ./dlls/user/Makefile.in 9 Dec 2004 13:48:56 -0000 1.86
+++ ./dlls/user/Makefile.in 8 Mar 2005 05:20:49 -0000
@@ -161,13 +161,13 @@
# 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 --dll $(SRCDIR)/user.exe.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --heap 65520 --main-module $(MODULE) --res resources/version16.res --export $(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 --dll $(SRCDIR)/display.drv.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --main-module $(MODULE) --res resources/display.res --export $(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 --dll $(SRCDIR)/mouse.drv.spec
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --main-module $(MODULE) --res resources/mouse.res --export $(SRCDIR)/mouse.drv.spec
resources/display.res: resources/display.rc
$(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/resources/display.rc
Index: tools/winebuild/main.c
===================================================================
RCS file: /var/cvs/wine/tools/winebuild/main.c,v
retrieving revision 1.59
diff -u -r1.59 main.c
--- tools/winebuild/main.c 7 Dec 2004 17:19:54 -0000 1.59
+++ tools/winebuild/main.c 8 Mar 2005 05:25:45 -0000
@@ -98,7 +98,6 @@
{
if (!strcmp( p, ".spec" ) || !strcmp( p, ".def" )) *p = 0;
}
- if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".dll" );
}
/* set the dll subsystem */
@@ -144,6 +143,7 @@
" -C --source-dir=DIR Look for source files in DIR\n"
" -d --delay-lib=LIB Import the specified library in delayed mode\n"
" -D SYM Ignored for C flags compatibility\n"
+" -E --export=FILE Export the symbols defined in the .spec or .def file\n"
" -e --entry=FUNC Set the DLL entry point function (default: DllMain)\n"
" -f FLAGS Compiler flags (only -fPIC is supported)\n"
" -F --filename=DLLFILE Set the DLL filename (default: from input file name)\n"
@@ -165,9 +165,9 @@
" --version Print the version and exit\n"
" -w --warnings Turn on warnings\n"
"\nMode options:\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"
+" --dll Build a .c file from a .spec or .def file\n"
+" --def Build a .def file from a .spec file\n"
+" --exe Build a .c file for an 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"
@@ -187,13 +187,13 @@
LONG_OPT_VERSION
};
-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 char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:w";
static const struct option long_options[] =
{
- { "dll", 1, 0, LONG_OPT_DLL },
- { "def", 1, 0, LONG_OPT_DEF },
- { "exe", 1, 0, LONG_OPT_EXE },
+ { "dll", 0, 0, LONG_OPT_DLL },
+ { "def", 0, 0, LONG_OPT_DEF },
+ { "exe", 0, 0, LONG_OPT_EXE },
{ "debug", 0, 0, LONG_OPT_DEBUG },
{ "ld-cmd", 1, 0, LONG_OPT_LDCMD },
{ "nm-cmd", 1, 0, LONG_OPT_NMCMD },
@@ -204,6 +204,7 @@
/* aliases for short options */
{ "source-dir", 1, 0, 'C' },
{ "delay-lib", 1, 0, 'd' },
+ { "export", 1, 0, 'E' },
{ "entry", 1, 0, 'e' },
{ "filename", 1, 0, 'F' },
{ "help", 0, 0, 'h' },
@@ -248,6 +249,10 @@
case 'D':
/* ignored */
break;
+ case 'E':
+ spec_file_name = xstrdup( optarg );
+ set_dll_file_name( optarg, spec );
+ break;
case 'F':
spec->file_name = xstrdup( optarg );
break;
@@ -324,21 +329,12 @@
break;
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 );
- spec_file_name = xstrdup( optarg );
- set_dll_file_name( optarg, spec );
break;
case LONG_OPT_EXE:
set_exec_mode( MODE_EXE );
- if ((p = strrchr( optarg, '/' ))) p++;
- else p = optarg;
- spec->file_name = xmalloc( strlen(p) + 5 );
- strcpy( spec->file_name, p );
- if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".exe" );
if (!spec->subsystem) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
break;
case LONG_OPT_DEBUG:
@@ -367,6 +363,10 @@
break;
}
}
+
+ if (spec->file_name && !strchr( spec->file_name, '.' ))
+ strcat( spec->file_name, exec_mode == MODE_EXE ? ".exe" : ".dll" );
+
return &argv[optind];
}
@@ -405,12 +405,14 @@
{
FILE *input_file = open_input_file( NULL, spec_file_name );
char *extension = strrchr( spec_file_name, '.' );
+ int result;
if (extension && !strcmp( extension, ".def" ))
- return parse_def_file( input_file, spec );
+ result = parse_def_file( input_file, spec );
else
- return parse_spec_file( input_file, spec );
+ result = parse_spec_file( input_file, spec );
close_input_file( input_file );
+ return result;
}
@@ -435,6 +437,7 @@
case MODE_DLL:
spec->characteristics |= IMAGE_FILE_DLL;
load_resources( argv, spec );
+ if (!spec_file_name) fatal_error( "missing .spec file\n" );
if (!parse_input_file( spec )) break;
switch (spec->type)
{
@@ -452,13 +455,16 @@
break;
case MODE_EXE:
if (spec->type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" );
+ if (!spec->file_name) fatal_error( "executable must be named via the -F option\n" );
load_resources( argv, spec );
+ if (spec_file_name && !parse_input_file( spec )) break;
read_undef_symbols( argv );
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 (!spec_file_name) fatal_error( "missing .spec file\n" );
if (!parse_input_file( spec )) break;
BuildDef32File( output_file, spec );
break;
Index: tools/winebuild/winebuild.man.in
===================================================================
RCS file: /var/cvs/wine/tools/winebuild/winebuild.man.in,v
retrieving revision 1.29
diff -u -r1.29 winebuild.man.in
--- tools/winebuild/winebuild.man.in 2 Mar 2005 13:53:50 -0000 1.29
+++ tools/winebuild/winebuild.man.in 8 Mar 2005 05:00:53 -0000
@@ -19,13 +19,12 @@
You have to specify exactly one of the following options, depending on
what you want winebuild to generate.
.TP
-.BI \--dll= filename
+.BI \--dll
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
+details), or from a standard Windows .def file. The .spec/.def file
+is specified via the -E option. The resulting C file must be compiled
+and linked to the other object files to build a working Wine dll.
+In this mode, the
.I input files
should be the list of all object files that will be linked into the
final dll, to allow
@@ -33,18 +32,20 @@
to get the list of all undefined symbols that need to be imported from
other dlls.
.TP
-.BI \--exe= name
-Build a C file for the named executable. This is basically the same as
-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
-as
+.BI \--exe
+Build a C file for an executable. This is basically the same as
+the --dll mode except that it doesn't require a .spec/.def file as input,
+since an executable need not export functions. Some executables however
+do export functions, and for those a .spec/.def file can be specified via
+the -E option. The executable is named from the .spec/.def file name if
+present, or explicitly through the -F option. 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 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.
+.BI \--def
+Build a .def file from a spec file. The .spec file is specified via the
+-E option. This is used when building dlls with a PE (Win32) compiler.
.TP
.B \--debug
Build a C file containing the definitions for debugging channels. In
@@ -83,6 +84,11 @@
.B main
is used instead). This is only valid for Win32 modules.
.TP
+.BI \-E,\ --export= filename
+Specify a .spec file (see \fBSPEC FILE SYNTAX\fR for details),
+or a standard Windows .def file that defines the exports
+of the DLL or executable that is being built.
+.TP
.BI \-f\ flags
Ignored for compatibility with the C compiler.
.TP
@@ -431,4 +437,5 @@
.UE
.SH "SEE ALSO"
.BR wine (1),
+.BR winegcc (1),
.BR wrc (1).
Index: tools/winegcc/winegcc.c
===================================================================
RCS file: /var/cvs/wine/tools/winegcc/winegcc.c,v
retrieving revision 1.34
diff -u -r1.34 winegcc.c
--- tools/winegcc/winegcc.c 7 Dec 2004 17:19:54 -0000 1.34
+++ tools/winegcc/winegcc.c 8 Mar 2005 05:09:09 -0000
@@ -339,7 +339,7 @@
struct options copts;
char* base_name;
- /* make a copy we so don't change any of the initial stuff */
+ /* make a copy so we don't change any of the initial stuff */
/* a shallow copy is exactly what we want in this case */
base_name = get_basename(file);
copts = *opts;
@@ -429,10 +429,8 @@
{
case file_def:
case file_spec:
- if (!opts->shared)
- error("Spec file %s not supported in non-shared mode", file);
if (spec_file)
- error("Only one spec file can be specified in shared mode");
+ error("Only one spec file can be specified.");
spec_file = file;
break;
case file_rc:
@@ -513,17 +511,19 @@
strarray_add(spec_args, "--ld-cmd");
strarray_add(spec_args, LD);
strarray_addall(spec_args, strarray_fromstring(DLLFLAGS, " "));
+ strarray_add(spec_args, opts->shared ? "--dll" : "--exe");
strarray_add(spec_args, "-o");
strarray_add(spec_args, spec_c_name);
- if (opts->shared)
+ if (spec_file)
{
- strarray_add(spec_args, "--dll");
+ strarray_add(spec_args, "-E");
strarray_add(spec_args, spec_file);
}
- else
+
+ if (!opts->shared)
{
- strarray_add(spec_args, "--exe");
- strarray_add(spec_args, output_name);
+ strarray_add(spec_args, "-F");
+ strarray_add(spec_args, strmake("%s.exe", output_name));
strarray_add(spec_args, "--subsystem");
strarray_add(spec_args, opts->gui_app ? "windows" : "console");
}
--
Dimi.
More information about the wine-patches
mailing list