Warning: This site is under construction, most links will be broken.

Shrinking large Delphi 2010 executables - removing RTTI properly

Last modified on Mon, 15th Feb 2010 at 22:36 GMT by zipplet

If you have ported a project previously compiled with an older version of delphi to delphi 2010, I'm sure you will have noticed the large gain in output executable size. Embarcadero correctly state that the size gain is generally not harmful to speed of execution, and a modern computer with huge hard disk drives makes it seem irrelevant. However it can look plain ugly and for some applications (installation programs etc) it does begin to matter.

This gain in size is partly due to the larger more powerful VCL now with full unicode support but a lot of it comes from RTTI (Runtime Type Information). RTTI is useful in some cases but especially with older projects you will not need it. So how do we get rid of it?

If you scour the help files, you will find that you can disable RTTI per unit with a compiler directive, and a second compiler directive helps to stop some extra generation of RTTI information for any used units. This does not really get rid of the problem as the VCL/RTL is compiled with RTTI too, plus adding the directive to every unit file is a pain.

To give an example, EXE sizes of a project of a rather large program of mine compiled in various ways - all release builds without debug information:

From the size reduction it's definately worth it for projects where size matters.

1. Compiler directives in your project

First, put the following directives in your DPR just before the uses command:

{ Reduce EXE size by disabling as much of RTTI as possible (delphi 2009/2010) }
{$IF CompilerVersion >= 21.0}

Right click the build configuration you are using and choose Build to force a recompile of all units. You should notice a decrease in executable size.

2. Rebuild the VCL/RTL without RTTI

Next we will build alternate versions of the most important VCL and RTL units without RTTI. Create a new forms project and save it somewhere, for sake of discussion c:\nortti. Make a subdirectory, call it c:\nortti\delphi2010.

In the DPR, add every VCL/RTL unit you want to use into the uses definition. I placed all of mine into an include file and included that in the DPR. Edit the project options (Right click the base build configuration, edit) and change "Unit output directory" to c:\nortti\delphi2010. Build the release version of this project. If any errors occur remove the offending units. If you want the JPEG units rebuilt you will need to copy the OBJ files from source\Win32\vcl\Imaging\JPGImage\obj into your project directory as it does not seem to check the search path properly. Eventually it will compile. Close the project.

A tip: a nice way to generate the initial unit list is with a simple batch file like this:

@echo off
del unitlist.inc
dir /b "C:\Program Files\Embarcadero\RAD Studio\7.0\source\Win32\vcl\*.pas" >> unitlist.inc
dir /b "C:\Program Files\Embarcadero\RAD Studio\7.0\source\Win32\rtl\win\*.pas" >> unitlist.inc
dir /b "C:\Program Files\Embarcadero\RAD Studio\7.0\source\Win32\rtl\common\*.pas" >> unitlist.inc

rem Manually add some system units (we cannot add the entire dir or problems crop up)
echo SysUtils.pas >> unitlist.inc
echo Types.pas >> unitlist.inc
echo Variants.pas >> unitlist.inc
echo VarUtils.pas >> unitlist.inc

Then open the inc file, search+replace '.pas' with ','.

/!\ QUICK FIX /!\ Download my rttidisable project and modify it to your needs. Remember to create a unit output directory and set it properly in RAD studio.

3. Using the replacement units in your project

Open RAD studio. You must edit the master (global) unit search path in RAD studio. The reason is that the compiler always looks there first for units, so it will prefer the prebuilt units to your units if you do not do this.

Open the Tools -> Options menu, navigate to Environment Options -> Delphi Options -> Library - Win32. Add the full path to your new units to the beginning of the Library path.

This change will affect all projects you open in RAD studio from now. However, if any projects use VCL/RTL units we have not rebuilt they will still work and use the prebuilt units.

Do not forget to also use the compiler directives at the beginning of your DPR!

4. Use UPX for a further size reduction

If it really matters for your project, you can use UPX to compress your executable further. Use the following command line for the smallest possible size:

upx --best --ultra-brute <filename.exe>

This takes quite a long time as it tries many different compression methods and picks the best - 72 for my version of UPX.

To add to the example earlier - my 1091KB executable (with the RTTI fixes) shrinks down to 382KB!
Before someone asks the inevitable: no UPX will not do anything nasty to your executable or prevent resource loading from working properly. The only penalty is a slight increase in loading time on very slow (say, pentium 1) computers. Your delphi 2010 executable will not work on anything less than Windows 2000 anyway, so why worry?

If you have any more tips for reducing executable size, please get in contact with me.