Hi, the patch below fixes a few things in winemaker. It seems to work with my app, but needs more testing, especially for MFC apps.
Modified files: tools: winemaker documentation: winemaker.man 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.