User forums > Help

How to reduce the size of wxWidgets .exes produced by mingw?

(1/3) > >>

marty:
Hello,

I'm new to Code::Blocks and wxWidgets and was wondering if anyone knew of any good techniques for reducing the size of a "Hello World" application using wxWidgets and compiled by mingw. I followed the wiki page tutorial for compiling a Unicode, release build, monolithic DLL with mingw-make, but the final DLL was about 9MB! I got the sample program of Code::Blocks to compile and run correctly with the DLL, but I don't want the program size to be so large. (By the way, I believe there were two instances of C-strings that needed to be converted to Unicode strings with a macro in the sample source code outputted by C::B.)

I also built a Unicode, release build, non-monolithic library (not a DLL) and had success with getting that to work and link with the sample code using C::B and mingw, but the resulting .exe was about 5MB. I removed some extra libraries like opengl and obdc that I wasn't using, but that didn't help the size of the exe much.

With MS VC++ 6.0, I was able to compile the wxWidgets library (release + non Unicode + non DLL), and could link it into a "Hello World" application resulting in an .exe size of only 960KB. I only included the base and core wxWidget libraries and the typical Windows libraries. I would really like to use Code::Blocks instead, especially since it is open-source and contains wxSmith, but I just can't seem to be able to keep the size of the resulting application down.

I tried linking the library I built with MS VC++ 6.0 compiling with the mingw compiler of C::B, but I got a number of link errors. I tried doing that in hopes that I'd get the reduced size I could achieve with VC++. Here is some of the output:


--- Code: ---Project   : wxWidgets application
Compiler  : GNU GCC Compiler (called directly)
Directory : E:\Documents and Settings\Marty\Desktop\xw-vslib-nounicode\
--------------------------------------------------------------------------------
Switching to target: default
Precompiling header: wx_pch.h
Compiling: main.cpp
Linking executable: E:\Documents and Settings\Marty\Desktop\xw-vslib-nounicode\wxWidgets.exe
.objs\main.o: In function `ZN8wxStringaSERKS_':
E:/wxWidgets-2.6.3/include/wx/window.h:(.text+0x4c): undefined reference to `wxAppConsole::CheckBuildOptions(char const*, char const*)'
.objs\main.o: In function `WinMain':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:297: undefined reference to `wxEntry(HINSTANCE__*, HINSTANCE__*, char*, int)'
.objs\main.o: In function `ZN7MyFrameC2EP7wxFrameRK8wxString':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxFrameNameStr'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxDefaultSize'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxDefaultPosition'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:23: undefined reference to `wxMenuBar::wxMenuBar()'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:32: undefined reference to `wxFrameBase::SetMenuBar(wxMenuBar*)'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:32: undefined reference to `wxFrame::~wxFrame()'
.objs\main.o: In function `ZN7MyFrameC1EP7wxFrameRK8wxString':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxFrameNameStr'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxDefaultSize'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:22: undefined reference to `wxDefaultPosition'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:23: undefined reference to `wxMenuBar::wxMenuBar()'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:32: undefined reference to `wxFrameBase::SetMenuBar(wxMenuBar*)'
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:32: undefined reference to `wxFrame::~wxFrame()'
.objs\main.o: In function `ZN7MyFrameD2Ev':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:36: undefined reference to `wxFrame::~wxFrame()'
.objs\main.o: In function `ZN7MyFrameD1Ev':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:36: undefined reference to `wxFrame::~wxFrame()'
.objs\main.o: In function `ZN7MyFrameD0Ev':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:36: undefined reference to `wxFrame::~wxFrame()'
.objs\main.o: In function `ZN7MyFrame6OnQuitER14wxCommandEvent':
E:/Documents and Settings/Marty/Desktop/xw-vslib-nounicode/main.cpp:41: undefined reference to `wxWindowBase::Close(bool)'
...

--- End code ---

Did anyone ever manage to make a wxWidgets application with a file size that is less than 2MB? Also, does anyone know why the functions are not linking correctly when I use the MS VC++ 6.0 library? I am assuming that mingw's link program is not compatable with VC++ libraries.

Thanks! Btw, C::B looks really great and I hope to use it for all of my C++ applications from now on!

thomas:
Look at the wxWidgets site, there is a section in the FAQ dealing with this issue.

In short words, it boils down to this:
1. wxWidgets is huge
2. GCC does not do a good job deadstripping code here, so it is even bigger
3. strip your executables and use an exe packer

Unluckily, there is no real solution. If you are courageous, you can try to disable wxWidgets components that you don't need, but chances are good that you'll just break it, and the gains are not *that* big, either.

takeshimiya:
Here is the link: http://www.wxwidgets.org/wiki/index.php/Reducing_Executable_Size


--- Quote ---I would really like to use Code::Blocks instead, especially since it is open-source and contains wxSmith, but I just can't seem to be able to keep the size of the resulting application down.
--- End quote ---

I want to note that if you're really worried about executable size, you can still use the MSVC compiler inside Code::Blocks and even with wxSmith. :)

See here: http://wiki.codeblocks.org/index.php?title=Integrating_Microsoft_Visual_C_6_with_Code::Blocks_IDE

marty:

--- Quote ---Look at the wxWidgets site, there is a section in the FAQ dealing with this issue.

In short words, it boils down to this:
1. wxWidgets is huge
2. GCC does not do a good job deadstripping code here, so it is even bigger
3. strip your executables and use an exe packer

Unluckily, there is no real solution. If you are courageous, you can try to disable wxWidgets components that you don't need, but chances are good that you'll just break it, and the gains are not *that* big, either.
--- End quote ---

I appreciate the quick reply! I just took a look and saw the section in the FAQ you were talking about. It said that most developers use MSVC++ to compile their wxWidgets applications because it (most likely) outputs the smallest size. I also stripped my executables of the debug information but that didn't help too much. I'm going to take a look at some exe packers.


--- Quote ---I want to note that if you're really worried about executable size, you can still use the MSVC compiler inside Code::Blocks and even with wxSmith. :)


See here: http://wiki.codeblocks.org/index.php?title=Integrating_Microsoft_Visual_C_6_with_Code::Blocks_IDE
--- End quote ---

Thanks a lot for the link and fast reply. I didn't realize MS VC++ 6 would work with C::B. I followed all of the instructions, and got C::B to compile the sample Windows GUI application with the VC++ 6 compiler. However, when I tried opening up my previous project and compiled, I had to remove a lot of compiler arguments that were not being recognized. This removed the pre-compiled header functionality and I'm not really sure at the present moment how to fix that.

Also, I now get a large number of link errors that state the "MSVCRT.lib" library is conflicting with others, but the strange thing is that it is not listed in the included libraries of C::B. I suppose it is automatically included. I'm am going to take a look into figuring out the command line argument for not including it.

Here is some sample output:

--- Code: ---Switching to target: default
main.cpp
Linking executable: E:\Documents and Settings\Martin Piecyk\Desktop\xw-vslib-nounicode\wxWidgets.exe
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _free already defined in LIBC.lib(free.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _malloc already defined in LIBC.lib(malloc.obj)
MSVCRT.lib(MSVCRT.dll) : error LNK2005: _toupper already defined in LIBC.lib(toupper.obj)

--- End code ---

marty:
Ok, now I figured out how to stop MSVCRT.lib (and LIBC.lib, I forgot to mention this one in my last post) from automatically being included. In the linker options, I had to add these arguments:

/NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBC

But now when I compile, I'm getting link errors about missing the delete operator. The libraries I included were:

wxmsw26_core
wxbase26
shell32
comctl32
kernel32
user32
gdi32
comdlg32

Here is the error I am getting. The delete operator seems to be the only thing I am missing. Does anyone have any ideas?


--- Code: ---wxbase26.lib(clntdata.obj) : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)
wxmsw26_core.lib(timercmn.obj) : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)
wxmsw26_core.lib(timer.obj) : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)
wxmsw26_core.lib(dcprint.obj) : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)
wxmsw26_core.lib(clipcmn.obj) : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)
--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version