Make smaller Delphi executables [duplicate] - delphi

Very recently I have come back to Delphi after a long pause and written a rather straightforward utility app my client requested to support an older release...
I know these days the size does not matter much, but it struck me as odd that the one-unit application, when compiled, amounted to 1'084'416 b executable. The one and only .pas unit I wrote is some 20.8k large, mostly because of the richness of the gui.
The uses clause is as follows:
uses
Windows, Messages, SysUtils, Variants, Classes, Controls, Forms, strutils,
Dialogs, ADODB, DB, DBGrids, ExtCtrls, DBCtrls, StdCtrls, Grids, Menus,
Buttons;
I wonder if there's any way I could reduce the size of the application to 300-400k or less?

Did you do a debug or release build? (Make it release for smaller size, make sure optimization is on, debug information turned off)
Did you turn off RTII (delphi 2010 and up) if not needed? (Smaller EXE sizes.)
Number of units in your uses clause of your main unit, is not a good way to guess EXE size. Think of it this way: The VCL itself is one large amount of code, the Database Layer another, and the stuff you write is probably a very small percentage of the EXE size.
To understand your executable size, try the JCL Project Analyzer, or read the MAP file that is produced when you turn on the Map option. This will tell you exactly what is inside your executable file.
It would be silly for various reasons, but you could get a smaller executable by using Delphi 7, for example. In the end when I make an application and I want to make it smaller, I look at how much time it would take, and how much effort to rebuild everything (such as with a vcl alternative) and I then say to myself, forget about it.

You can try using KOL (Key Objects Library is a set of objects to develop power (but small) 32 bit Windows GUI applications using Delphi but without VCL). KOL allows to create very compact Windows32 GUI applications (starting from ~11K without compression - if suggested system units replacement used). The most of code is converted to built-in assembler.
Another option is use a exe compressor like UPX.

MapFileStats (DelphiTools.info) is a good (free) tool that allows you to see how much space every unit occupies in your executable. My own tool DelphiUnitSizes is an alternative that in addition to unit sizes also display the size of each function or class.
Delphi 2010 made the default executable about 30% larger, probably because of RTTI included in the RTL/VCL units, so you can use an older version of Delphi for smaller exe-size.
As others have mentioned UPX is a great tool too, the false positives by virusscanners are not that frequent in my experience.
The size of Delphi-executables can be very much trimmed down using custom System-units and UPX-compression. I can generate exe-files that are less that 64kb in size with my Delphi-based game-generator ZGameEditor, even with Delphi Berlin.

How big is your DFM? It is included as a resource in your EXE. Depending on how complex your GUI is, you might find that creating the GUI at runtime in code could reduce the EXE size.

You may also considere to add the following line to the top of the project file:
{$SetPEFlags 1}
Explanation here : http://hallvards.blogspot.fr/2006/09/hack12-create-smaller-exe-files.html

Yes, but then you'd need to supply the other code units as additional files. Just as .net required the assembly, and you have VB runtimes etc., this is just the Delphi runtime - but it's embedded in the exe.
Another option is to compress the executable, there are tools for that around.

You say you're coming back to Delphi. If you still have an old version available, use that - every new version adds extra features and if you don't need them them your exes will be smaller without them.
Make sure you're only including units you actually use.
But whatever you do I very much doubt you'll get down to 300k. If memory serves, even a 'hello world' application in Delphi 2 would be larger than that.

Do you have any resource files or pictures that are linked into the project?
I think the ADODB also includes quite some overhead. If your app really uses a database then a mere 1MB isn't too bad for file size? Don't forget that your app is just this exe - no need for extra dll's etc.

Related

Can I create a Unit for common utility routines in Delphi in a way that unused class routines won't contribute to the Release Build size?

We are using Delphi 10.4.2 Sydney. I would like to create a single unit (or possibly multiple units) that houses all the utility functions we use in our various software products. The idea is we would just include this unit in every project we start and then we can rely on it being there and use these functions freely in all our code. These would probably be mostly class routines and such.
I'm concerned though that some of our projects might only use a single routine in this large unit. The size of our apps is important and we want to keep that size to a minimum. I am not familiar with how Delphi's compiler works or how much space adding a superfluous unit might add or any other issues with this.
Is there perhaps a way to create a Unit where only the functions we actually use will contribute to the final build's size? Is this even something to worry about? How are common utilities library usually handled in Delphi?
The Delphi Linker is supposedly smart enough to detect unused functions and will not include the code for them in the executable it generates. This also applies to class methods. (*1)
So, go ahead and create these units.
You can easily check whether code was generated for a method by looking for the blue dots during debugging.
(*1: That feature can be a major pain in the lower back when you want to call such a function from the Evaluate/Modify dialog during debugging.)
Put the units into a separate package project. If you build your exe as a monolithic exe (so packages are linked in) then the compiler should only link in the units that are actually referenced, not the entire package.

How do I remove dead code from an EXE file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reduce exe file
What are some tools that, given an EXE file, remove all unused code and make a new EXE file with code really used by the application? I think that something like that should exist. Just for curiosity; but I think that it can be really good as tools for producing a smaller EXE file without unused code.
P.S.: Delphi produces standalone EXE files that contain code of all object used in an application, but not all elements of this object are really used. This makes big files.
I remember the first version of Pascal that include only code really used and did not insert unused code, and EXE files were smaller.
Current Delphi also excludes unused code. You can easily see this in Delphi. If you compile, you get 'blue dots' in the gutter of your code. Functions that are not used don't have blue dots, meaning they are excluded. If you check the Optimization checkbox in project options, code is rewritten to make more use of registers thus eliminating certain variables.
Nevertheless, Delphi executables grow, especiall when using certain units. I think the smallest .exe you can create in Delphi 7 is about 10Kb. In later versions this will probably be a bit larger.
Important causes of file size is
resources. Large or lots of images consume a lot of space. If you use icons on multiple forms, make sure to put them in a central image list (on a shared datasource). Use one of the available PngImageList implementations for smaller image size against better quality.
rtti. The runtime type information causes class definitions to consume extra space. Thise space is partly due to the meta information about the class, but mainly because all extra code. Any methods that may be called using RTTI could be bound in a kind of 'late binding' fashion. Therefor, the compiler cannot know whether the methods can be eliminated, so it needs to include them in the executable.
registered classes. Similar to 2. If a class is registered, it can be fetched and instantiated using its name as a string. Those classes must be included in the project, even if they are never used, just because the compiler cannot know if they are needed.
It's a fact that RTTI is expanded in recent Delphi versions. I think this also causes the RTTI meta information about classes to consume more space. There's only so much you can do about that.
In general, I think the Delphi compiler still does a lot of optimizing. You shouldn't have to worry about exe file size. If you do, you could try a packer like upx. I've got good esperiences with upx. It cuts down the executables to about a fifth or less of their original size, while retaining all functionality.
If you application is huge, check if you don't have a lot of debug info compiled in.
Try a release build and check if it's any smaller.
What i sometimes do is configure the project to compile all .dcu files into a single folder. That way you quickly see all of the useless units that get compiled into your .exe. It often happens that you include a single unit for a single function, but in turn you get a whole tree of dependent units. You'll just have to search your uses clauses and try to get rid of these dependencies somehow.
I think both gexperts and cnpack contain tools to show dependencies, or to scan for unused units in your project. They can be helpful with this.
After you've removed useless dependencies, you can always compress your compiled exe with upx. There are supposed disadvantages to that (barry kelly wrote about it some time ago), but i've got good experiences with it. It sometimes makes the file 4x as small which can be a big deal.

Reduce exe file

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?
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!
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
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.
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.
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.
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.

will Delphi applications become smaller in future

already delphi win32 exe size is ~850 kb , do they have any roadmap of making exe size bit smaller,(i know that the size is because of vcl unicode RTTI and many more ),delphi compiles the whole unit even only a small function in the unit is needed. so is there any facilities to do so,or third party products are there , (i know kol and mck do the same)
I doubt that exe size is much of a concern for the Delphi team, or even for most of the users as well. As you noticed, unicode and new RTTI increase the size, and while you can turn of new RTTI there really is not much else you can do about it.
In general each new Delphi version produced larger exes, I don't see this trend changing.
As for compiling whole units that isn't correct, unless you compile packages the compiler will not include non used methods and declarations.
If exe size is important you don't have much choice. If you don't need unicode and other new features then using D2007 or D7 or even D2 is an option.
You can use exe packers such as UPX.
If you build a set of applications you can reduce total size by using shared packages.
Also check out these:
What Can I Do To Reduce My Executable's Size (Delphi)?
Delphi EXE compressor?
delphi xe disable RTTI
I'm not sure what kol and mck have to do with your question about .EXE size.
The presumption in your question that a unit is always completely included in your .EXE, even if only a small portion of the unit is actually used, is plain wrong.
Delphi has both a code optimizer and a linker optimizer.
The latter will not include code from a unit in your .EXE if that code is not actually somehow used.
Your more general question 'do they have any roadmap of making exe size bit smaller' can be answered by a simple 'No'.
The current roadmap does not include that.
--jeroen
You certainly shouldn't expect exe size for future 64-bit Delphi versions to be smaller than current 32-bit Delphi exe files.
On the contrary: pointers and pointer-sized types will double in size and other data structures may grow in size due to padding (to meet alignment requirements). All of this gets compiled into the executable, the size of which will therefore grow.
The path looks to be exes will become larger, in the future. Application size became far less important since disk sizes, bandwith and memory footprint rarely are a problem in the Windows world. There's always been a tradeoff between exe size and exe optimization (some optimization techniques can make an exe larger), and a 64 bit executable will probably be somewhat larger. Also improvements to the language may require more data to be stored about the code itself (i.e. RTTI informations). There are techniques to keep an exe size small, but they usually require to bypass most of the Delphi OOP and RAD features and libraries. Unless you have very special needs, rarely the exe size is an issue (although I understand that is some parts of the world bandwidth still matters, and maybe disk space too).
Anyway AFAIK it is not true Delphi linker will import a whole unit. Unused calls will be removed, although not everything you would like to be. The dcu will be compiled as a whole, but only needed code will be moved to the compiled executable. Something may depend on your compilation options. Did you activate the optimization option?
I guess the Free Pascal faq on this goes for Delphi too:
http://wiki.freepascal.org/Size_Matters

What Can I Do To Reduce My Executable's Size (Delphi)?

I release a single executable (.EXE) for a desktop program using Delphi 2009. I have no external DLLs or resources that I need for the program to run.
I use two components: LMD Innovative's ELPack and Sergey Tkachenko's TRichView that are compiled into my executable.
When I build my production version, using the "Release" build configuration, the executable file produced is 13,533 KB.
Prior to using Delphi 2009, I was using Delphi 4. The executable it produced was only 2,671 KB while incorporating the same two components and basically having the same code as my current version.
I do understand that Delphi 2009 is completely Unicode (which is the main reason why I upgraded), and being Unicode can cause up to a doubling of size. But this is about 5 times larger.
Is there a reason why my executable has to remain 5 times larger? Or are there some simple ways to cut down a significant chunk of the executable size?
Please note. Some people are answering with ways to compress the Delphi EXE. That is not what I am trying to do. I am trying to simply see why so much space is being used to remove what might not be necessary. If that is done, compression can still be done afterwards if so desired.
It really doesn't matter how big or small the executable is once it is installed. It is for downloading purposes and to minimize server load and download times that you want to compress it. I prefer to use Inno Setup and compress the program inside the install routine itself. Then when it is installed, it is expanded to full size. That both prevents possible detection as a virus and eliminates the extra startup time needed to uncompress the program in memory. Also I code sign both my executable and my install routine and some compression techniques are incompatible with that.
For more info about compressing, see the StackOverflow question: Delphi EXE compressor?
ldsandon asked me to provide exactly what options I'm using, so here they are:
(source: beholdgenealogy.com)
(source: beholdgenealogy.com)
When moving from Delphi 7 to Delphi 2010., our .exe's grew for example from 16 megs to 35 megs.
I asked a question similar to yours on the Embarcadero forum a few weeks ago. (link) In my OP, I listed a series of links on this subject that you might find helpful.
We tried using UPX to compress our .exe's. Letting it work for hours significantly reduced our .exe, but we probably won't use it in production for these reasons:
We have quite a few .exe's and don't want to wait 1/2-day on each build. (It's possible that we could find a non-brute force set of parameters to UPX that would reduce this...)
Although the size of the .exe is reduced, our shippable was not, because our installer (not surprisingly) is unable squeeze much more compression out of the already compressed file... whereas it was able to reduce the original 16 meg .exe down to 8 megs.
I've read some reports that at some time (rarely, but not never), UPX exe's triggered various anti-virus programs to report the application contained a virus. (I don't recall the date, site, or details of where I saw this, so it's a bit unfair of me to report it here.) But, we are so adverse to taking a risk of that even possibility happening, that UPX is off the table...
The link on the Embarcadero forum also includes a link to another SO thread on this topic.
I continue to be surprised and disappointed at the code bloat we found when moving to Delphi 2010. As Nick notes, 2X for Unicode is quite excessive.
However, the bloat is a relatively minor trade-off when moving to D2010, because, IMO, D2010 is such a terrific upgrade in so many other ways. But, it does mean that we'll probably have to move to shipping 2 CDs rather than one. I'm not looking forward to seeing the reaction to this from our organization...
Without seeing the actual settings that your "Release" build configuration uses explaining this increase in size requires a great deal of speculation.
Beyond some perhaps unlikely factors resulting in a vast increase in the amount of code being "dragged in" even though it isn't used, that magnitude of increase would most easily be explained by the inclusion of debug information.
I would check your compiler and linker settings for:
Debug Information (compiler setting)
TD32 info (linker)
Remote debug info (linker)
Compare these settings in your Delphi 2009 project with the equivalents in Delphi 4.
Factor out the expected 2X increase from Unicode and you end up with a 2.5X increase unaccounted for. This makes sense considering how many versions you've skipped. A lot's been added to the VCL and RTL since Delphi 4, and not all of it is stuff that can be easily smartlinked out, even if you never use it. Depending on how many units you're using, you could be hauling in quite a bit of extra baggage.
Allen Bauer and the compiler team added a new feature into D2010 to help reduce this, but apparently they're treading cautiously and didn't use it in as many places as they could have. Hopefully we'll see more cruft reduction in 2011 and subsequent releases.
I will add my few words.
Linker can remove unused procedures and functions only if it can follow the code hierarchy. The nightmare list for linker listed below:
Message-driven code, the sad news is that this code can't be removed whatsoever, that's why Delphi blank project size continues growing from version to version. Every new windows message (WM_TOUCH for example as long as I know introduced recently) creates procedure call hierarchy that can't be removed (even if you don't have plan to use Touch API at all). This is because every case WM_: fragment is something linker can't decide whether it will be used or not.
Code and data structures accessed from the begin end, initialization, finalization secions of the units. Here you have some control, remove unnecessary calls or object creation. Even if you create objects on demand and only free them in finalization section, make it carefully
Use "upx - compress or expand executable files" # http://upx.sourceforge.net
If you go to tools/configure tools, and set it up like this, you can compress the executable that you're working on easily via a menu item in the IDE.
Another way is to have a look to 'what unit increase the size ?'.
To do this, I use the JCL 'Project Analyser IDE', integrated in the IDE with the JCL/JVCL installation, it show you all the units with their respective size. You can export it in text file.
If you do it with the 2 environnements (D4 & D2009) you will have a lot of pertinent informations.
I've done some tests to see the difference between D2007 and D2010, because we are upgrading to D2010. I've tested a medium sized management GUI application, with about 60 forms (grids with detail forms, frames, etc). We're using TMS components + Remobjects.
D2007:
"normal" compilation: 18.8mb
with debug dcu's: 18.8mb (same size!)
D2010
normal: 23.9
debug dcu's: 48.8mb (!)
So using debug dcu's doubles our exe size...
Test with our business service (no big dfm's):
D2007: 12.3mb
D2010: 17.1mb
So yes, D2010 increases the exe (a bit), but this is not a problem for my customer.
Edit: some information about compiled size:
D2007:
D2010:
So an increase of code size, but a more than doubling of the data!
If you don't want to use an exe compressor then you should give StripReloc a try.
Check format of your dfm-s. They must be in binary format if you want to make your exe smaller.
1) You are generating a detailed map file, and because you've set "used debug dcus" it will also contains symbols for the RTL/VCL units. If it is used by an exception handling systems to generate call stacks and the like, it could be added to the executable. And if not compressed somehow, it could make your .exe size pretty large.
2) Using debug dcus will also make your .exe somewhat larger because usually they are compiled without optimization and debug options set, and they will make also your code slower. They shouldn't be used in a release version.
3) Debug information should add debig info only to the unit and not to the executable, although it is required IIRC to generate the map file.
Since D2010 adds extended RTTI, and RTTI is a notorious factor in increasing exe size, it would be interesting to see how big D2009 binaries are for that application.
If D2009 binaries are significantly smaller, it is not Unicode etc. For my own binaries, I only have a 30% increase or so going from D7 to D2009.
It has been stated earlier that using an executable compresser reduces the size of the exe but not of the install package. However, if you want a good compressor then try ASPack.
#Tom1952: ASPack is pretty fast, just a few seconds to compress a file
Also you can change the Icon. Icon in newest delphi IDE (ie XE3) is Vista/7 compatible and contains all sizes (up to 256x256 as far as I know). So you can reduce exe file size with changing the Icon.
The standard units in you newer delphi may contain more strings and constants such as error strings, that is included even if you disable debug information. Check your uses.
Don't have much of a somution besides not using a specific unit, or removing unneeded data from it.
(My experiences are with Delphi 5)
For Delphi 10.3 Rio with default setiings:
Step 1: Switch from Debug to Release in "Projects" window. This reduced my exe file from 22 MB to 5 MB !
Step 2: Use an exe compresor like ASPack. It further reduced my exe file to 1.3 MB. Unbelievable, isn't it ? :)
Uncheck debug information in project options.
If embarcadero can't provide any solution or explanation!!! I think the solution is simple: don't stuck only with Delphi there is a lot of programming languages, every one is limited only by programmer imagination.

Resources