the patch below fixes a few things in winemaker.
It seems to work with my app, but needs more testing, especially for MFC
apps.
Changelog:
- adapt winemaker to the new way winebuild handles imports.
- fix crashes due to winemaker-generated wrapper app closing
libraries (is this one correct??)
- Fix some minor bugs in the wrapper.c template.
- change semantics of --nomfc option such that it overrides
automatic setting of --mfc if stdafx.h or stdafx.cpp are found.
(this may cause problems to some people. For me the old behaviour
was a pain in the neck, because VC++ generates stdafx.h always,
even for pure C projects). Feedback, please !
- Add --nodlls option to suppress auto-generated import list for
simple apps.
- Adapt man page.
--
Martin Wilck Phone: +49 5251 8 15113
Fujitsu Siemens Computers Fax: +49 5251 8 20409
Heinz-Nixdorf-Ring 1 mailto:
[email protected]
D-33106 Paderborn
http://www.fujitsu-siemens.com/primergy
Index: tools/winemaker
===================================================================
RCS file: /home/wine/wine/tools/winemaker,v
retrieving revision 1.39
diff -u -r1.39 winemaker
--- tools/winemaker 14 Apr 2002 19:31:23 -0000 1.39
+++ tools/winemaker 22 May 2002 16:49:18 -0000
@@ -233,6 +233,14 @@
my $TF_MFC=4;
##
+# User has specified --nomfc option for this target or globally
+my $TF_NOMFC=8;
+
+##
+# --nodlls option: Do not use standard DLL set
+my $TF_NODLLS=16;
+
+##
# Initialize a target:
# - set the target type to TT_SETTINGS, i.e. no real target will
# be generated.
@@ -435,23 +443,37 @@
push @{@$target[$T_LIBRARY_PATH]},$option;
} elsif ($option =~ /^-l/) {
push @{@$target[$T_LIBRARIES]},"$'";
- } elsif (@$target[$T_TYPE] != $TT_DLL and $option =~ /^--wrap/) {
- @$target[$T_FLAGS]|=$TF_WRAP;
- } elsif (@$target[$T_TYPE] != $TT_DLL and $option =~ /^--nowrap/) {
- @$target[$T_FLAGS]&=~$TF_WRAP;
- } elsif ($option =~ /^--mfc/) {
- @$target[$T_FLAGS]|=$TF_MFC;
+ } elsif ($option =~ /^--wrap/) {
if (@$target[$T_TYPE] != $TT_DLL) {
@$target[$T_FLAGS]|=$TF_WRAP;
+ } else {
+ print STDERR "warning: option --wrap is illegal for DLLs - ignoring";
+ };
+ } elsif ($option =~ /^--nowrap/) {
+ if (@$target[$T_TYPE] != $TT_DLL) {
+ @$target[$T_FLAGS]&=~$TF_WRAP;
+ } else {
+ print STDERR "warning: option --nowrap is illegal for DLLs - ignoring";
}
+ } elsif ($option =~ /^--mfc/) {
+ @$target[$T_FLAGS]|=$TF_MFC;
+ @$target[$T_FLAGS]&=~$TF_NOMFC;
} elsif ($option =~ /^--nomfc/) {
@$target[$T_FLAGS]&=~$TF_MFC;
- @$target[$T_FLAGS]&=~($TF_MFC|$TF_WRAP);
+ @$target[$T_FLAGS]|=$TF_NOMFC;
+ } elsif ($option =~ /^--nodlls/) {
+ @$target[$T_FLAGS]|=$TF_NODLLS;
} else {
print STDERR "error: unknown option "$option"\n";
return 0;
}
}
+ if (@$target[$T_TYPE] != $TT_DLL &&
+ @$target[$T_FLAGS] & $TF_MFC &&
+ !(@$target[$T_FLAGS] & $TF_WRAP)) {
+ print STDERR "info: option --mfc requires --wrap";
+ @$target[$T_FLAGS]|=$TF_WRAP;
+ }
return 1;
}
@@ -541,7 +563,7 @@
} elsif ($dentry =~ /.c$/i and $dentry !~ /.spec.c$/) {
push @sources_c,"$dentry";
} elsif ($dentry =~ /.(cpp|cxx)$/i) {
- if ($dentry =~ /^stdafx.cpp$/i) {
+ if ($dentry =~ /^stdafx.cpp$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
push @sources_misc,"$dentry";
@$project_settings[$T_FLAGS]|=$TF_MFC;
} else {
@@ -551,7 +573,7 @@
push @sources_rc,"$dentry";
} elsif ($dentry =~ /.(h|hxx|hpp|inl|rc2|dlg)$/i) {
push @sources_misc,"$dentry";
- if ($dentry =~ /^stdafx.h$/i) {
+ if ($dentry =~ /^stdafx.h$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
@$project_settings[$T_FLAGS]|=$TF_MFC;
}
} elsif ($dentry =~ /.dsp$/i) {
@@ -774,10 +796,13 @@
push @exe_list,$target;
}
# This is the default link list of Visual Studio, except odbccp32
- # which we don't have in Wine. Also I add ntdll which seems
- # necessary for Winelib.
- my @std_dlls=qw(advapi32.dll comdlg32.dll gdi32.dll kernel32.dll ntdll.dll odbc32.dll ole32.dll oleaut32.dll shell32.dll user32.dll winspool.drv);
- @$target[$T_DLLS]=@std_dlls;
+ # which we don't have in Wine.
+ my @std_dlls=qw(advapi32.dll comdlg32.dll gdi32.dll kernel32.dll odbc32.dll ole32.dll oleaut32.dll shell32.dll user32.dll winspool.drv);
+ if (@$target[$T_FLAGS] & $TF_NODLLS == 0) {
+ @$target[$T_DLLS]=@std_dlls;
+ } else {
+ $target[$T_DLLS]=[];
+ }
push @{@$project[$P_TARGETS]},$target;
# Ask for target-specific options
@@ -982,7 +1007,8 @@
@$wrapper[$T_TYPE]=@$target[$T_TYPE];
@$wrapper[$T_INIT]=get_default_init(@$target[$T_TYPE]);
@$wrapper[$T_FLAGS]=$TF_WRAPPER | (@$target[$T_FLAGS] & $TF_MFC);
- @$wrapper[$T_DLLS]=[ "kernel32.dll", "ntdll.dll", "user32.dll" ];
+ @$wrapper[$T_DLLS]=[ "kernel32.dll", "user32.dll" ];
+ push @{@$wrapper[$T_LIBRARIES]}, "dl";
push @{@$wrapper[$T_SOURCES_C]},"@$wrapper[$T_NAME]_wrapper.c";
my $index=bsearch(@$target[$T_SOURCES_C],"@$wrapper[$T_NAME]_wrapper.c");
@@ -1634,32 +1660,10 @@
$rcname =~ s+([^/\w])+\$1+g;
print FILEO "rsrc $rcname.res\n";
}
- print FILEO "\n";
- my %dlls;
- foreach $dll (@{$global_settings[$T_DLLS]}) {
- if (!defined $dlls{$dll}) {
- print FILEO "import $dll\n";
- $dlls{$dll}=1;
- }
- }
- if (defined $project_settings) {
- foreach $dll (@{@$project_settings[$T_DLLS]}) {
- if (!defined $dlls{$dll}) {
- print FILEO "import $dll\n";
- $dlls{$dll}=1;
- }
- }
- }
- foreach $dll (@{@$target[$T_DLLS]}) {
- if (!defined $dlls{$dll}) {
- print FILEO "import $dll\n";
- $dlls{$dll}=1;
- }
- }
# Don't forget to export the 'Main' function for wrapped executables,
# except for MFC ones!
- if (@$target[$T_FLAGS] == $TF_WRAP) {
+ if ((@$target[$T_FLAGS]&($TF_WRAP|$TF_WRAPPER|$TF_MFC)) == $TF_WRAP) {
if (@$target[$T_TYPE] == $TT_GUIEXE) {
print FILEO "\n@ stdcall @$target[$T_INIT](long long ptr long) @$target[$T_INIT]\n";
} elsif (@$target[$T_TYPE] == $TT_CUIEXE) {
@@ -1867,6 +1871,7 @@
generate_list("${canon}_LIBRARY_PATH",1,@$target[$T_LIBRARY_PATH]);
generate_list("${canon}_LIBRARIES",1,@$target[$T_LIBRARIES]);
generate_list("${canon}_DEPENDS",1,@$target[$T_DEPENDS]);
+ generate_list("${canon}_IMPORTS",1,@$target[$T_DLLS]);
print FILEO "\n";
generate_list("${canon}_OBJS",1,["$(${canon}_C_SRCS:.c=.o)","$(${canon}_CXX_SRCS:.cpp=.o)","$(EXTRA_OBJS)"]);
print FILEO "\n\n\n";
@@ -1952,7 +1957,7 @@
print FILEO "\t-$(STRIP) $(STRIPFLAGS) $@\n";
print FILEO "\n";
print FILEO "$(${canon}_SPEC_SRCS:.spec=.spec.c): $(${canon}_SPEC_SRCS) $(${canon}_SPEC_SRCS:.spec=.tmp.o) $(${canon}_RC_SRCS:.rc=.res)\n";
- print FILEO "\t$(LD_PATH) $(WINEBUILD) -fPIC $(${canon}_DLL_PATH) $(WINE_DLL_PATH) -sym $(${canon}_SPEC_SRCS:.spec=.tmp.o) -o $@ -spec $(SRCDIR)/$(${canon}_SPEC_SRCS)\n";
+ print FILEO "\t$(LD_PATH) $(WINEBUILD) -fPIC $(${canon}_DLL_PATH) $(WINE_DLL_PATH) -sym $(${canon}_SPEC_SRCS:.spec=.tmp.o) -o $@ -spec $(SRCDIR)/$(${canon}_SPEC_SRCS) $(${canon}_IMPORTS:%=-l%)\n";
print FILEO "\n";
my $t_name=@$target[$T_NAME];
if (@$target[$T_TYPE]!=$TT_DLL) {
@@ -2168,7 +2173,7 @@
print STDERR "Usage: winemaker [--nobanner] [--backup|--nobackup] [--nosource-fix]\n";
print STDERR " [--lower-none|--lower-all|--lower-uppercase]\n";
print STDERR " [--lower-include|--nolower-include]\n";
- print STDERR " [--guiexe|--windows|--cuiexe|--console|--dll]\n";
+ print STDERR " [--guiexe|--windows|--cuiexe|--console|--dll|--nodlls]\n";
print STDERR " [--wrap|--nowrap] [--mfc|--nomfc]\n";
print STDERR " [-Dmacro[=defn]] [-Idir] [-Pdir] [-idll] [-Ldir] [-llibrary]\n";
print STDERR " [--interactive] [--single-target name]\n";
@@ -2181,9 +2186,6 @@
exit (2);
}
-
-project_init(@main_project,"");
-
while (@ARGV>0) {
my $arg=shift @ARGV;
# General options
@@ -2244,11 +2246,13 @@
$opt_flags&=~$TF_WRAP;
} elsif ($arg eq "--mfc") {
$opt_flags|=$TF_MFC;
- $opt_flags|=$TF_MFC|$TF_WRAP;
$needs_mfc=1;
} elsif ($arg eq "--nomfc") {
- $opt_flags&=~($TF_MFC|$TF_WRAP);
+ $opt_flags&=~$TF_MFC;
+ $opt_flags|=$TF_NOMFC;
$needs_mfc=0;
+ } elsif ($arg eq "--nodlls") {
+ $opt_flags|=$TF_NODLLS;
# Catch errors
} else {
@@ -2263,6 +2267,11 @@
usage();
}
}
+
+ if ($opt_flags & $TF_MFC && $opt_target_type != $TT_DLL) {
+ print STDERR "info: option --mfc requires --wrap\n";
+ $opt_flags |= $TF_WRAP;
+ };
}
if (!defined $opt_work_dir) {
@@ -2278,6 +2287,8 @@
print_banner();
}
+project_init(@main_project,"");
+
# Fix the file and directory names
fix_file_and_directory_names(".");
@@ -3094,6 +3105,8 @@
* This is either CUIEXE for a console based application or
* GUIEXE for a regular windows application.
*/
+#define GUIEXE 0
+#define CUIEXE 1
#define APP_TYPE ##WINEMAKER_APP_TYPE##
/**
@@ -3138,11 +3151,11 @@
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
#else
-int WINAPI Main(int argc, char** argv, char** envp)
+int WINAPI main(int argc, char** argv, char** envp)
#endif
{
void* appLibrary;
- HINSTANCE hApp,hMFC,hMain;
+ HINSTANCE hApp = 0, hMFC = 0, hMain = 0;
void* appMain;
char* libName;
int retcode;
@@ -3212,7 +3225,7 @@
}
/* Get the address of the application's entry point */
- appMain=(WinMainFunc*)GetProcAddress(hMain, appInit);
+ appMain=GetProcAddress(hMain, appInit);
if (appMain==NULL) {
char format[]="Could not get the address of %s (%d)";
char* msg;
@@ -3232,11 +3245,6 @@
#endif
/* Cleanup and done */
- FreeLibrary(hApp);
- if (hMFC!=NULL) {
- FreeLibrary(hMFC);
- }
- dlclose(appLibrary);
free(libName);
return retcode;
Index: documentation/winemaker.man
===================================================================
RCS file: /home/wine/wine/documentation/winemaker.man,v
retrieving revision 1.5
diff -u -r1.5 winemaker.man
--- documentation/winemaker.man 2 Oct 2001 17:47:34 -0000 1.5
+++ documentation/winemaker.man 22 May 2002 16:49:19 -0000
@@ -17,7 +17,7 @@
]
.br
[
-.IR "--guiexe " "| " "--windows " "| " "--cuiexe " "| " "--console " "| " "--dll "
+.IR "--guiexe " "| " "--windows " "| " "--cuiexe " "| " "--console " "| " "--dll " "| " "--nodlls "
]
.br
[
@@ -121,6 +121,14 @@
i.e. for which it does not know whether it is an executable or a library,
it should assume it is a library.
.TP
+.I --nodlls
+This option tells winemaker not to use the standard set of winelib libraries
+for imports. That is, any DLL your code uses must be explicitly passed to
+winemaker with -i options.
+The standard set of libraries is: advapi32.dll, comdlg32.dll, gdi32.dll,
+kernel32.dll, odbc32.dll, ole32.dll, oleaut32.dll, shell32.dll, user32.dll,
+winspool.drv.
+.TP
.I --wrap
Specifies that executable targets should be built as libraries and a small
executable wrapper generated for them. This technique is sometimes required
@@ -137,7 +145,9 @@
generates wrappers for these targets that are executables.
.TP
.I --nomfc
-Specifies that targets are not MFC-based. This is the default.
+Specifies that targets are not MFC-based. This option disables use of MFC libraries
+even if winemaker encounters files "stdafx.cpp" or "stdafx.h" that would cause it
+to enable MFC automatically if neither --nomfc nor --mfc was specified.
.TP
.I -Dmacro[=defn]
Adds the specified macro definition to the global list of macro definitions.
@@ -149,8 +159,7 @@
Appends the specified directory to the global library path.
.TP
.I -idll
-Adds the Winelib library to the global list of Winelib libraries to import
-in the spec file.
+Adds the Winelib library to the global list of Winelib libraries to import.
.TP
.I -llibrary
Adds the specified library to the global list of libraries to link with.