Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes a tripling of EXE size in C++ Builder XE4 compared to C++Builder 2010?

I have upgraded a project from RAD Studio 2010 to RAD Studio XE4. The project is mostly C++ using the C++ Builder half of RAD Studio, with smatterings of Delphi.

Under 2010, the Release build was 22MB. Under XE4, the same Release build is 55MB.

This is a problem because:

  • 55MB is remarkably large for an EXE
  • It takes noticeably longer to start the program (not much, but some.)
  • Many of our customers download new versions from remote areas or on board ship while at sea. Size matters.

What could cause this, and how do I fix it?


Notes

  • Oddly enough, the debug build is still only 23MB. Project settings seem very similar. I diffed an export of the option sets and saw only <UsePackages>True</UsePackages> as something present in Release not Debug; removing it made no difference. Beyond that there's code optimisation turned on and lack of a _DEBUG define.
  • Debug info is generated for the Release build, but goes into an external .tds file. (This will be used for EurekaLog in future, and currently allows us to debug release builds of the program.) I wondered if the linker was linking in debug info, but as far as I know the C++ linker always places the debug info in an external file, which exists, plus EurekaLog is not yet enabled in the build.
  • The project files (.cbproj) were created in XE4, not upgraded from old 2010 ones. I made new projects and added the old .cpp and .pas files. This was to avoid issues caused by upgrading - on the Embarcadero forums it's often recommended to create projects anew when upgrading IDE versions. Until this occurred, I had indeed encountered fewer issues than in 2010.
  • There are many mentions of Delphi XE2+ EXEs being noticeably larger than those produced by old versions of Delphi. (1, 2, 3, 4, 5, 6.) While the C++ linker is different to that used by Delphi, it is possible the causes are similar.
    The cause there appears to mostly be RTTI used by the Delphi RTL code, which in a Delphi project can be removed by specifying {$WEAKLINKRTTI ON}. The XE4 documentation does not mention an equivalent C++ linker pragma. There is #pragma explicit_rtti (the C++ analog of {$RTTI}) and __declspec(delphirtti) (the C++ analog of {$M}/{$TYPEINFO}).
  • The project is linked using runtime packages and the dynamic RTL. It is a 32-bit VCL forms application. I have XE4 Update 1 installed on Windows 7.
  • Edit: David Heffernan asks in a comment below about the .map file sizes of each project.
    The release .map size is 17MB, and .tds size is 80MB.
    Debug has now stopped linking, with the linker reporting it is out of memory (an old, old bug that should have been fixed years ago.) There are no .map or .tds files generated and so I can't give a comparison size accurately. From memory the .tds was about 100MB, and unfortunately I don't recall the .map size. If I get the project linking I will update the question.
  • Edit again: I found the answer (sortof) - turning 'Expand inline functions' OFF reduces the EXE size to the expected value. This is puzzling itself though - see my answer below. Note that the debug build already had this turned off and still won't link, giving an out of memory error.
    I haven't marked my answer as correct yet, in case someone can provide some insight into exactly what is going on, which would be a much better answer than just 'turn this option off'.
like image 566
David Avatar asked Sep 13 '13 06:09

David


1 Answers

Solved (sortof.)

The Release build had "Expand inline functions" turned on. Turning this off reduced the EXE size from 55MB to 17MB.

Project options showing the 'Expand inline functions' option in the C++ Compiler - Debugging section

This is an astounding difference and I don't know why the difference is so big. I find it unlikely we have 38MB worth of inlined functions, even counting templates and headers, let alone ones using the inline keyword. If there is a way to examine the linker steps, output, or obj files to see what is being expanded, please comment - I'd find this really valuable.

like image 111
David Avatar answered Nov 01 '22 10:11

David