20

Using Delphi (or in general any tools, if exist of course), is it possible to reduce size of an exe file, removing all code that not is used but that is present there?
(for example, a function or procedure that is present but is never called).
I remember that with Pascal, using unit (without objects) the compiler includes only procedures and functions that are really used and will strip out non-used routines in a unit from the final exe.

With Object-pascal, I remember that in Delphi 1 all members of a object are included in the exe;
Has something has changed since than till Delphi-XE2?

Johan
  • 74,508
  • 24
  • 191
  • 319
Marcello Impastato
  • 2,263
  • 5
  • 30
  • 52
  • In C/C++ with MSVC you can set the `/OPT:REF` option when linking, which removes all codes and datas that are not used. – user26742873 Sep 04 '20 at 07:34

6 Answers6

21

If you aren't using RTTI you can add this to the top of your .dpr file (immediately after program) to remove the extra RTTI information:

{$IFOPT D-}{$WEAKLINKRTTI ON}{$ENDIF}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}

If you want to strip it out of all the RTL/VCL units then you'd need to include those in your project file too so that the settings above could take effect. I don't think I would recommend doing that since I don't believe the reduction in executable size is worth the complications of compiling your own RTL/VCL.

You can also add the following, again somewhere in your .dpr file:

{$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}

This will strip the relocation information which is not needed in a .exe. Don't add this to a DLL or package!

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 4
    The new Livebinding feature will not work if you turn off the RTTI. – Robert Love Sep 13 '11 at 14:14
  • 1
    @Robert Yes, I guess quite a few things will fail without RTTI. But I bet the vast majority of extant code will be fine. – David Heffernan Sep 13 '11 at 14:17
  • How much will this actually reduce the size (percentage wise)? – Johan Nov 18 '11 at 15:30
  • @Johan 30% reduction in size for my executable. But this figure varies between different projects. – David Heffernan Nov 18 '11 at 15:35
  • +1, Excellent tip :) I couldn't compile the directive {$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED} though. To correct it, make sure Windows is included in uses clause. –  Jan 31 '12 at 15:13
  • @Blobby or just redeclare the – David Heffernan Jan 31 '12 at 15:49
  • Be careful stripping relocation entries from exes. Though rare, there are situations where an .exe may not be able to load at its preferred base address. – dthorpe Nov 06 '12 at 18:08
  • @dthorpe Can you give an example? I've never heard of such a thing. – David Heffernan Nov 06 '12 at 18:11
  • @dthorpe The system DLLs will be relocated. And what's global heap? No such thing so far as I know. Are you thinking of 16 bit? – David Heffernan Nov 06 '12 at 18:43
  • @dthorpe The exe comes in first. It always gets loaded at its preferred base address. Then come the DLLs. Now they way be relocated. Even system DLLs like comctl32 can be relocated. System DLLs are no more special than other DLLs. Sharing of code segments between processes happens for all DLLs. Which API for global heap? – David Heffernan Nov 06 '12 at 18:54
  • 2
    Wish you were there when I was implementing $SetPEFlags. Your confidence would have made my work much simpler. And I would have a handy scapegoat if/when fate didn't agree with our decision. ;> – dthorpe Nov 06 '12 at 18:58
  • global heap: GlobalAlloc() http://msdn.microsoft.com/en-us/library/windows/desktop/aa366574(v=vs.85).aspx – dthorpe Nov 06 '12 at 19:00
  • @dthorpe It's global in name only on Win32. Name left over from Win16. – David Heffernan Nov 06 '12 at 19:01
  • It still allocates memory from the process virtual address space. And as such, global memory allocations can block placement of code at preferred base addresses. Usually DLLs. – dthorpe Nov 06 '12 at 19:02
  • @dthorpe Sure, but the exe is loaded before any code has a chance to call GlobalAlloc. Process virtual address really is isolated. – David Heffernan Nov 06 '12 at 19:09
  • 2
    From MSDN: "While this may save space in the executable file, it may cause the executable not to work on other Win32-based implementations. For example, say you built an EXE for Windows NT and based the EXE at 0x10000. If you told the linker to strip the relocations, the EXE wouldn't run under Windows 95, where the address 0x10000 is already in use." http://msdn.microsoft.com/en-us/library/ms809762.aspx – dthorpe Nov 06 '12 at 19:13
  • @dthorpe I only build for XP and later, NT only. – David Heffernan Nov 06 '12 at 19:16
  • 2
    When you advise folks to turn off relocations, you should advise them of the limitations. Nothing is free. – dthorpe Nov 06 '12 at 19:19
  • @dthorpe I thought I had done that. When I said only to do it on an EXE. So far as I know, in the modern world, reloc stripping is no probs for executable files. – David Heffernan Nov 06 '12 at 19:24
  • @dthorpe As a parting line, I'd say that I've been stripping for years without any trouble!! – David Heffernan Nov 06 '12 at 19:28
  • @dthorpe Having said all of that in defence of stripping, I'm hardly sure it's worth it. If the EXE doesn't need rebasing then the relocs will never even be read off the disk. Stripping might reduce the size of your exe for distribution/download, but it's only around 5% for my executable. Is it ever worth it? I doubt it. – David Heffernan Nov 06 '12 at 19:51
  • @dthorpe Take a look at MSDN docs for the `/FIXED` option of `LINK`: http://msdn.microsoft.com/en-us/library/w368ysh2.aspx specifically this bit: "By default, /FIXED:NO is the default when building a DLL, and /FIXED is the default for any other project type." – David Heffernan Nov 06 '12 at 19:54
  • I am not going to use this flag in my program because of the problems it will bring up, BUT just out of curiosity: how much one will expect to reduce the size if this flag is used? :) – Gabriel Mar 29 '22 at 08:42
  • @ServerOverflow Varies for program to program. Try it with your program. – David Heffernan Mar 29 '22 at 08:47
  • Hm... strange. I added the two lines to my DPR project (Delphi 10.4). The exe size is the same. – Gabriel Mar 29 '22 at 08:59
  • Hm... Interesting. I moved the two lines IMMEDIATELY after the "Program" line at the top of DPR. Now the IDE/compiler froze in the middle of the compilation. Looks like I have found a compiler bug! – Gabriel Mar 29 '22 at 09:03
  • More weird things: I right-click the Delphi button is taskbar and clicked "Close". Now a dlg box ask me if I want to cancel the background compilation AND as long as that dlg is open, the compilation continues.... – Gabriel Mar 29 '22 at 09:06
8

reduce the application EXE size - excellent article

(Taken from the link above)

Generally, EXE files created with Delphi are larger than EXE files created with another programming language. The reason is the VCL. (Sure, VCL has many advantages...)

There are several ways to reduce a EXE's size:

01) Use a EXE-Packer (UPX, ASPack,...)-UPX

02) Use KOL.

03) Write your application without VCL

04) Use the ACL (API Controls Library)

05) Use StripReloc.

06) Deactivate remote debugging information and TD32.

07) You might want to put code in a dll.

08) Don't put the same images several times on a form. Load them at runtime.

09) Use compressed images (JPG and not BMP)

10) Store less properties in DFM files

PresleyDias
  • 3,657
  • 6
  • 36
  • 62
RBA
  • 12,337
  • 16
  • 79
  • 126
4

If your aim is to reduce the size of your executable, you can use a tool which compress it and allow to execute it as it was not compress.. (=not a zip)

For instance, you can check UPX which works nicely with delphi programs.

Whiler
  • 7,998
  • 4
  • 32
  • 56
  • 15
    Before using UPX you should read [this article from Jordan Russel](http://www.jrsoftware.org/striprlc.php#execomp) to be aware of the downsides. – Uwe Raabe Sep 13 '11 at 09:56
3

Delphi has a smart linking option that is ON by default if I remember correctly. It does exactly what you describe. Only used functions and data are linked to your exe. If you need further size compression you can try one of the many "exe compressor" programs out there.

cyco130
  • 4,654
  • 25
  • 34
0

Yet another option: Use WinRar to create a Setup file (yes, WinRar can do that). WinRar can automatically execute an EXE file once the unpacking is done.

WinRar has a superior compression ratio. One of the reasons is that it will merge all your files as a single file and then will start the compression, while ZIP (and other similar not-so-sophisticated compressors) will compress each file individually and merge them in a large file after the compression.

This give RAR's algorithm a better chance to find duplicate data among your files.

Plus, WinRar is less complicated than other installers (minus: it does not offer an uninstaller also, but that it is easy to fix with your own program).

Disclaimer: I am not affiliated with WinRAR.

Gabriel
  • 20,797
  • 27
  • 159
  • 293
0

Just to supplement what other's have written...

The smart linker will eliminate unused routines except under the following conditions:

  • The unit has an initialization section - unfortunately many of the largest units in the RTL/VCL (Classes, SysUtils, Windows, Forms... to name a few) have initialization sections so if they are in your uses clause you get the whole enchilada linked into your code. Much of the code in the RTL/VCL could be refactored to reduce or eliminate this but it would break backward compatibility.

  • The routine is part of a class and is marked as virtual or dynamic - If you instantiate and object in your code that has virtual or dynamic methods, those methods are linked into your executable whether you call them or not.

Additional steps to can take to reduce exe file size:

  • Take advantage of form inheritance - If you have many similar forms, create a base form for them to inherit from. These child forms will only store properties that differ from the base form in their dfms. This can drastically reduce the size of your executable by eliminating redundant information in your dfms.

  • Store any large graphics in external files and load them on demand - Splash screens, "skins", icon sets, etc. can really bloat the size of an exe. Delphi doesn't always store these files in the most efficient format when they're embedded in the exe.

  • You can shave 10% - 30% off an exe's size by stripping certain unused data from the exe after its been compiled. There are third party tools that can do this but you can eliminate some of the cruft by setting appropriate PE header flags. Make sure you understand the implications of each flag before using it as some flags could make your exe unusable.

  • Copy portions of the RTL/VLC into your own units - instead of including Classes or SysUtils in your uses clause, create an new unit and copy just the classes and functions you need into the unit. Then use it instead.

  • Break code up into loadable modules - If you have multiple exes that reuse the same units you can make them smaller by using dlls or bpls rather than statically linking everything into the exes. A dll/bpl will only be loaded into memory once no matter how many exes need it.

Kenneth Cochran
  • 11,954
  • 3
  • 52
  • 117
  • 2
    Correction: A unit having an initialization section does not inherently cause everything in that unit to be linked into the executable. The initialization section is treated internally just like any other function: only the types that it refers to will be linked into the executable. Some VCL unit intialization sections do drag in a lot of material because they touch critical core classes that have RTTI baggage or hefty virtual method tables. If your unit initialization section touches none of your classes, it won't bulk up your exe. – dthorpe Nov 06 '12 at 18:14
  • 2
    Using dlls or packages will shrink the .exe file size significantly, but the tradeoff is that the dll/bpl file size that you have to distribute with your exe is many times larger than what the exe would have been if statically linked with the dcus. Switching to BPL packages provides a net file size savings only if you have multiple applications sharing the same packages. – dthorpe Nov 06 '12 at 18:17