Skip to main content
Thoughts from David Cornelius

Category

Delphi's project options allows you to build a project with or without linking to runtime packages. A runtime package is a special dynamic-link library in the proprietary Delphi (or C++Builder) format that allows an executable to be split into various modules of functionality; these module files have a .BPL extension (for Borland Package Library). In the early days, this was useful to allow large applications to run on computers with limited memory because each module loads into its own memory space (these days, memory limitations are rare unless you're still deploying memory-hungry 32-bit applications). The main advantage today is realized if you have multiple executables that share some common functionality, like reporting or GUI controls or database access. The .EXEs can be smaller because instead of linking the reporting or GUI controls or database access code into each one of the .EXEs, you can ship that functionality in .BPLs and the .EXEs can be much smaller because they load that shared common code at runtime.

To change this option, pull up your Project Options and find the "Link with runtime packages" option. If that option is not checked, you're building a monolithic executable--all the library code is in one big .EXE. But if you check that box and list the runtime packages for your applicaiton, your .EXE is smaller and you must ship the specified package files along with it. To be automatically found by the .EXE, the .BPLs must be either in the same folder as the .EXE or on the system PATH.

What I didn't know is that you don't have to list all the runtime packages your application uses!

I've known about this feature for many years and have used it at times for specific scenarios, or when a working with a plug-in system that used the .BPL format. What I didn't know, however, is that you don't have to list all the runtime packages for that option--and what packages you DON'T list, get linked into the .EXE. In fact, if you don't list ANY runtime packages, Delphi builds the application as if you had not checked the "Link with runtime packages" option at all!

This means that you can determine how many of the packages to link in and which ones to leave out as extra .BPL files. My assumption has always been that it was all or nothing--either all packages were linked into one giant .EXE or all packages used by the application had to be listed and deployed for it to work. This is not so!

By default, the "Link with runtime packages" option is unchecked for new application projects, allowing you to quickly create a stand-alone program. When you first check that option and enable the "Runtime packages" line, all the packages for all components you have installed in Delphi, whether from Embarcadero or open source or commercial products, and both VCL and Firemonkey, are all listed. You obviously don't need all these packages and cannot even build a project with everyone of them listed as they are not all available for all platforms; for example VCL and Firemonkey are incompatible in the same project and the BDE doesn't work on any platform other than Win32.

If you're going this route with runtime packages and are deciding which ones to include, it may be prudent to stop periodically and build your project to see how big the .EXE size is. Depending on how many packages and .EXEs you have to ship, there will be a "sweet spot" that makes sense for you. A team I'm working with deploys different sets of several dozen .EXEs to hundreds of customers and while there could be an argument to save hard disk space, it's so cheap these days, it's hardly worth the time. What's more important for us is if we want to to send out a fix to a reporting library or upgrade the security of one of the internet components to support a new protocol or change a style of a GUI control. By keeping some of those types of .BPLs separate, we can update just a few files to affect all programs rather than recompile and redistribute hundreds of applications.

After learning about this flexibility in listing runtime packages, I wanted to test it out and see some real numbers. So, I wrote a simple Win32 VCL application in Delphi 10.4 and placed a label, a button, and two third-party components on the main form, 1) a ReportBuilder component, and 2) a non-visual layout saver from a small library I wrote. I built this four different ways, noting the size of the .EXE and the list of packages to deploy for each scenario:

OPTION: NOT linked with runtime packages
EXE Size: 26,690 KB
Deploy: single .EXE

OPTION: Linked with runtime packages: only ccLib_R
EXE Size: 14,581 KB
Deploy: .EXE plus...

  • rtl270.bpl
  • vcl270.bpl
  • dbrtl270.bpl
  • cclib_r270.bpl

OPTION: Linked with runtime packages, only dclRB2227 (ReportBuilder)
EXE Size: 4,224 KB
Deploy: .EXE plus...

  • rtl270.bpl
  • vcl270.bpl
  • vclx270.bpl
  • vclWinX270.bpl
  • vclimg270.bpl
  • vclie270.bpl
  • vcledge270.bpl
  • bindengine270.bpl
  • rbRTL2227.bpl
  • rbRCL2227.bpl

OPTION: Linked with runtime packages, both dclRB227 and ccLib_R
EXE Size: 4,210 KB
Deploy: .EXE plus...

  • rtl270.bpl
  • vcl270.bpl
  • vclx270.bpl
  • vclWinX270.bpl
  • vclimg270.bpl
  • vclie270.bpl
  • vcledge270.bpl
  • bindengine270.bpl
  • rbRTL2227.bpl
  • rbRCL2227.bpl
  • ccLib_R.bpl

Several things I noticed in this test: 1) removing my small library from the stand-alone .EXE dropped its size by quite a bit but only because it also separated out the RTL and VCL packages that had been previously linked in; 2) simply listing a single ReportBuilder package required eight additional .BPLs to also be shipped; 3) the real size of the "ccLib" package was realized in the last test as it only reduced the .EXE size by 14 KB from the previous test.

A final consideration when selecting your package list is the hassle to package and deploy the various .BPL files; is it worth the extra management required to make sure all the .BPLs are deployed in order to save a few MB? The questions you have to answer will be different for your software and customer environment. But with modern build tools and automation, a lot of the details can be tucked away, never seen or dealt with after the configuration is tested so that is probably not a big deal.

Well, if you didn't know this trick about varying the selected packages to include before, you now have a little extra flexibility for how you build your Delphi projects.

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
Please enter the characters shown; no spaces but it is case-sensitive.
Image CAPTCHA
Enter the characters shown in the image.