Author Topic: Abnormal difference of exe size using C::B wizard against wxWidgets 2.9 ?!  (Read 15108 times)

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Hello,

Upgrading from wxWidgets 2.8.12 to wxWidgets 2.9.3, I was very surprise to see my exe increased dramatically. So, I've asked in the wxWidgets (here :) and it sounds like this is quite bigger than what I could expect (for example, doublemax on wxWidgets forum tell me he got a 1MB difference only in a minimal project).

So, I've done some tests using Code::Blocks Wizard. I've created two minimal projects with same wizard options (ie. GUI w/frame, using wxSmith, linking to unicode monolithic static wxWidgets). Here are the results for release builds :

- Project using wxWidgets 2.8 is 2.44 MB :)
- Project using wxWidgets 2.9 is 7.07 MB :(

Also, knowing I'm with Code::Blocks under Windows using TDM-GCC compiler.

So, what to do to get an acceptable size w/ wxWidgets 2.9 ? Is it related to something forced by C::B wizard about GCC compiler ? A little bit worried ::)
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Do you have -s option for stripping enabled?
Are you sure both libs are compiled in release mode by the same compiler?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Do you have -s option for stripping enabled?

Yes, oBFusCATed, compiler options in C::B indicates "-s" (strip all symbols) and "-O2" (optimize for speed)

Are you sure both libs are compiled in release mode by the same compiler?

Yes, both have been compiled with same version of TDM-GCC (the tdm-gcc-4.6.1.exe package) using this command line :

Code
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release CXXFLAGS="-fno-keep-inline-dllexport"
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline ptDev

  • Almost regular
  • **
  • Posts: 222
The considerable difference in size between executables compiled with wx 2.8 and 2.9 is a widely known issue.

wxWidgets 2.9 generates bigger executables due to increased debug checks that included in the release build, an increased amount of class libraries and recently, in wx2.9.4, due to strings being UTF32 based by default (this carries with it the performance penalty due the repeated conversions back and forth between UTF32 and UTF8 as well - although ways to facilitate these needs are still being worked on).

The only sensible advice, besides using optimal compiler settings, is to edit the setup.h header, enforce wxDEBUG_LEVEL to 0 for release builds (which is not the case by default), judiciously disable every single option you will never use, and recompile wxWidgets. Removing wx 2.8 backwards compatibility will also reduce the API size, at the expense of forcing you to rewrite some parts of your applications.

EDIT: Also consider a non-monolithic build: you will only need to distribute the used DLLs with your application.

Offline eranon

  • Almost regular
  • **
  • Posts: 180
OK, thanks for these lighted advice ptDev : I'll take a look to the 2.9's setup.h. Also, I've bookmarked this page, given to me by doublemax on the wxWidgets forum : http://wxwidgets.blogspot.de/2009/09/debug-build-changes-in-wx3.html (maybe there are some additional info over there).

About 2.8 compatibility : since I'm using wxWidgets recently, it could be manageable to rewrite some parts of code. So, could you indicate me the right page which talk about deprecated 2.8 features/classes/methods ?

About my use of static lib (no shared), it's just because I've to produce portable applis w/o possibility to check about presence of DLL at setup-time (since there's not any setup) ::)

--
EDIT : Combining your info, devPt, and the one from doublemax in wxWidgets forum, I've modified setup.h's like below and relaunched my wxWidgets 2.9 build session from a batch... I'll see tomorrow morning if it's better.

Code
WXWIN_COMPATIBILITY_2_8 0

#ifdef NDEBUG
   #define wxDEBUG_LEVEL 0
#else
   #define wxDEBUG_LEVEL 2
#endif

Also, I've kept the two libwxmsw29u.a built with defaut setup.h
- libwxmsw29u.a for DLL was : 24 188 KB
- libwxmsw29u.a as LIB was : 45 958 KB

I'll tell you the new size tomorrow... Hoping [-o<

--
EDIT 2 : result after my re-compil of wxWidgets 2.9.3 removing backward compatibility to 2.8 and adding wxDEBUG_LEVEL 0 :

Code
libwxmsw29u.a (static LIB) is now 41 530 KB (was 45 958) : so, a very little difference (- 7%)

Also, I've rebuilt the minimal Code::Blocks project :

Code
executable (release) is now 5.65 MB (was 7.07 MB) : so, a valuable difference (- 20%), but still a big exe

I continue to search (using compilers option about size, looking at no-monolithic side and, maybe, others compilers)... However, if I don't succeed I'll have to return to the 2.8.
« Last Edit: May 28, 2012, 07:43:39 am by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline ptDev

  • Almost regular
  • **
  • Posts: 222
Thank you for posting your results. Maybe you could also post them in the wxWidgets C++ forum, and link to it in the wx-dev mailing list.
The wxWidgets developers should be aware of the implications of certain choices in the current wxWidgets design. ;)

Offline xunxun

  • Almost regular
  • **
  • Posts: 187
Except wxDEBUG_LEVEL

If you don't use wx EXCEPTIONS, you can make USE_EXCEPTIONS=0.

If you don't use wx RTTI, you can make USE_RTTI=0. (C::B uses wx RTTI!)

Maybe you can change the compiler option to -Os

If wx shared build, may also add "-fvisibility=hidden -fvisibility-inlines-hidden".


LTO/PGO may reduce exe size, too.
Regards,
xunxun

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Yes, ptDev : even if nothing done towards wx-dev mailing list (I've subscribed to user side, but not dev one yet), I've already opened a thread about this in the wxWidgets forum. It's here : http://forums.wxwidgets.org/viewtopic.php?f=1&t=35103&p=143804

Thanks for these added info, xunxun ; until now, I've pushed a little bit further (see my results below), but wouldn't fall in a too specific optimization ; knowing same wx libs should work for several projects, and it's difficult to remember to not use this or that... Well, here are my results until now (and a problem too) :

--
So, as said above, I've tried to reduce the exe size a little bit more like this :

Quote
- Rebuild wxWidgets 2.9.3 w/ "WXWIN_COMPATIBILITY_2_8 0" & "wxDEBUG_LEVEL 0" in setup.h => my mini_wx29_project's exe becomes 5.65 MB
- Post-build w/ "strip --strip-all XXX.exe" (read it's sometime better than GCC -Os) : negligible, but I keep-it (- 0.01 MB)
- Rebuild wxWidgets 2.9.3 adding theses make options : CFLAGS='-Os -fdata-sections -ffunction-sections' CXXFLAGS='-Os -fdata-sections -ffunction-sections -fno-keep-inline-dllexport' LDFLAGS='-Wl,--gc-sections' => mini_wx29_project  is now 3.64 MB, but w/ a lot of warnings about sections.

Thus, now my initial minimalist project of 7.07 MB is 3.64 MB, but linker returns a lot of warnings (about 300 lines like the ones below) :

Code
Linking executable: bin\Release\wx29_cb-mini.exe
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_gdicmn.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_window.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_window.o): warning: duplicate section `.rdata$_ZTV13wxTransform2D[vtable for wxTransform2D]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_mdi.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_mdi.o): warning: duplicate section `.rdata$_ZTV21wxMDIClientWindowBase[vtable for wxMDIClientWindowBase]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_mdi.o): warning: duplicate section `.rdata$_ZTS19wxNavigationEnabledI16wxNonOwnedWindowE[typeinfo name for wxNavigationEnabled<wxNonOwnedWindow>]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_appbase.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size

[...]

Output size is 3.64 MB
Running target post-build steps
strip --strip-all wx29_cb-mini.exe
Process terminated with status 0 (0 minutes, 28 seconds)
0 errors, 305 warnings (0 minutes, 28 seconds)
Do you have an idea to avoid these hundreds of warnings ?

I've asked in the wxWidgets forum too (see URL I indicate at top of this post).

Next step could be to use no-monolithic linking, but, before, I would like to remove theses warnings ::)

--
EDIT : I try to advance. Now, I've got only 6 warnings (rather than hunderds) but two errors too (so, it doesn't build)

Here are the options I've indicated :

Quote
For compiler :
-ffunction-sections
-fdata-sections
-Wl,-allow-multiple-definition
-flto

For linker :
-flto
-Os
-Wl,--gc-sections
-Wl,-allow-multiple-definition

And I get this :

Code
Compiling: resource.rc
Compiling: wx29_cb_miniMain.cpp
Linking executable: bin\Release\wx29_cb-mini.exe
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans0.ltrans.o: warning: duplicate section `.rdata$_ZTS19wxNavigationEnabledI16wxNonOwnedWindowE[typeinfo name for wxNavigationEnabled<wxNonOwnedWindow>]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans0.ltrans.o: warning: duplicate section `.rdata$_ZTV13wxTransform2D[vtable for wxTransform2D]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans0.ltrans.o: warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans1.ltrans.o: warning: duplicate section `.rdata$_ZTS19wxNavigationEnabledI16wxNonOwnedWindowE[typeinfo name for wxNavigationEnabled<wxNonOwnedWindow>]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans1.ltrans.o: warning: duplicate section `.rdata$_ZTS19wxNavigationEnabledI8wxWindowE[typeinfo name for wxNavigationEnabled<wxWindow>]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans1.ltrans.o: warning: duplicate section `.rdata$_ZTS17wxWindowWithItemsI9wxControl15wxItemContainerE[typeinfo name for wxWindowWithItems<wxControl, wxItemContainer>]' has different size
C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans0.ltrans.o:cctYhhpd.ltrans0.o:(.text+0xd22): undefined reference to `wxTheAssertHandler'
C:\DOCUME~1\eln\LOCALS~1\Temp\cctYhhpd.ltrans0.ltrans.o:cctYhhpd.ltrans0.o:(.text+0xd51): undefined reference to `wxOnAssert(char const*, int, char const*, char const*, wchar_t const*)'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 39 seconds)
2 errors, 6 warnings (0 minutes, 39 seconds)

Knowing I've maybe made obvious mistake with theses options : I'm new in GCC as in C::B and wxWidgets :o Do you have an idea, an advice ?
« Last Edit: May 28, 2012, 01:49:05 pm by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Some of your warnings look like the lib and the project were built with different flags.

Have you done a full rebuild of both, ensuring that both builds use the exact same set of optimization flags?

Offline eranon

  • Almost regular
  • **
  • Posts: 180
No, effectively, Alpha, you're right... But, here is progress

About wxWidgets 2.9.3
- I've changed setup.h with "WXWIN_COMPATIBILITY_2_8 0" and "wxDEBUG_LEVEL 0"
- I've cleaned with "mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release clean"

- Then built with :
Quote
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release CFLAGS="-Os -fdata-sections -ffunction-sections" CXXFLAGS="-Os -fdata-sections -ffunction-sections -fno-keep-inline-dllexport" LDFLAGS="-Wl,--gc-sections"

About the test project
Initially, default Code::Blocks project settings gave me 305 warnings and 0 error :
Code
GCC with "-Wall -s -O2 -pipe -mthreads -Wno-attributes -include wx_pch.h -Winvalid-pch", and linker with "-mthreads"

And the same (305 warnings and 0 error) if I just add the same options as the ones provided during wxWidget building :
Code
"GCC with default setting above  + "-fdata-sections -ffunction-sections -fno-keep-inline-dllexport"
Linker with default setting above + "-Wl,--gc-sections"

Then, I've tried to remove these warnings using differents options (but, effectivelly, w/o rebuild of wxWidgets itself)... After some hours, I've got this combination which gave me 2 errors and 6 warnings :
Code
GCC with default setting above + "-Os -ffunction-sections -fdata-sections -Wl,-allow-multiple-definition -flto"
Linker with default setting above +  "-flto -Os -Wl,--gc-sections"-Wl,-allow-multiple-definition"

So, what should I do from this point : remove options in my test project or add ones in a new wxWidgets rebuild ?

PS : also, in parallel, maybe I'l take a try w/ MSVC compiler... But it would be great to obtains something acceptable with GCC.

--
EDIT : knowing, of course, after every change in build options, I do a complete rebuild (with clean ahead)
« Last Edit: May 28, 2012, 07:08:44 pm by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline xunxun

  • Almost regular
  • **
  • Posts: 187
Note: You can't use -ffunction-sections -fdata-sections and -Wl,--gc-sections on Windows GCC.
Because binutils lacks --gc-sections implement at present, though it has a experimental patch.

Before the bug is fixed, if you use -ffunction-sections -fdata-sections, it will make larger.

It only works on Linux.
Regards,
xunxun

Offline xunxun

  • Almost regular
  • **
  • Posts: 187
And if you use -flto above gcc4.6 (including 4.6), you should use the linker option : -flto -fuse-linker-plugin.
Regards,
xunxun

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Wahou, impressed ! In fact, on my side, I didn't used GCC before to go to wxWidgets (ie. some weeks ago). So, I just try and see... Well, I'll apply you advice and will be back to tell you the result. Just now, I have to advance in my project (and playiong with compiler take a lot of time). Thanks and soon, xunxun  ;)

--
EDIT : OK, I try a new wxWidgets 2.9.3 building today. Could you tell me if this cmdline like make sense and is a good idea in the goal to reduce size of final project ?

Quote
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release clean
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release CFLAGS="-fwhole -flto -O2 -Os -s -fno-keep-inline-dllexport" CXXFLAGS="-fwhole -flto -O2 -Os -s -fno-keep-inline-dllexport" LDFLAGS="-flto -fuse-linker-plugin"

Knowing setup.h has "wxDEBUG_LEVEL 0" (but I've restored "WXWIN_COMPATIBILITY_2_8 1" that I disabled yesterday).

Also, I will use these build options for my mini test project (Code::Blocks's default + added ones to be on the same line as the prepared wxWidgets 2.9) :

Quote
Compiler : "-Wall -fwhole -flto -O2 -Os -s -pipe -mthreads -Wno-attributes -include wx_pch.h -Winvalid-pch"
Linker : "-mthreads -flto -fuse-linker-plugin"

Do you think all of this is OK ?
« Last Edit: May 29, 2012, 11:46:38 am by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Since I think it's a good advancement, I create a new post rather than do an EDIT of previous one.

Well, tried as said just above (with and without -fwhole) and got errors at project building time. So, I've tried to return to a basic compil using :

Quote
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release CFLAGS="-O2 -Os -fno-keep-inline-dllexport" CXXFLAGS="-O2 -Os -fno-keep-inline-dllexport"

Then, I've tried to rebuild my mini-test-project with default Code::Blocks's options + "-Os" to, simply, try to optimize for size. And, here again, a ton of warnings (exactly 307) which complains about things like :

Quote
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_gdicmn.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size
c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../../mingw32/bin/ld.exe: C:\devlibs\wxWidgets\lib\gcc_lib/libwxmsw29u.a(monolib_window.o): warning: duplicate section `.rdata$_ZTV20wxThreadHelperThread[vtable for wxThreadHelperThread]' has different size

Nevertheless, this mini-test-project (which does quite nothing except an empty frame with two item menus : one to quit, one about) is built and has a size of 3.46 Mo, which is acceptable hoping it will dedcrease when I'll go no-monolithic and using packer in post-building.

So, my only one question now is : how to remove these f@*$#!§g 307 warnings about "duplicate section with different sizes" ?

--
EDIT : if I remove all optimization in speed (ie. without -O, -O1, -O2, -O3) in my mini-test project's options, all warnings disappear. Knowing I've used -O2 during wx29 compil. So, I've only kept the optimization in size (-Os) and symbols removing (-s), and it builds without warning. Size of mini-test exe is now 3.45MB :) Does this inspire you something (I mean the impossibility to use speed optimization) ?
« Last Edit: May 29, 2012, 04:18:27 pm by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]