Building stand-alone EXEs
by Kent Reisdorph
A stand-alone EXE is one that doesn’t require external DLLs or packages in order to run. Probably most of you know how to configure a project to build a stand-alone EXE. However, you may not know exactly what happens when you set the project options this way. Further, you may have encountered situations where it was not possible to create an application that is not dependent on external files. Finally, you may have wondered how you can configure C++Builder to create a stand-alone EXE by default. All of these topics will be explained in this article.
Static vs. dynamic linking
A project can be built in one of two ways: using static linking or dynamic linking. When dynamic linking is used (the default for C++Builder projects), the executable uses code from the C++Builder DLLs and runtime packages. This makes the executable very small. However, the small size is misleading because you must ship the required DLLs and runtime packages with your application. A simple do-nothing application, for example, compiles to about 23 KB. However, the application requires the runtime library (RTL) DLL and at least one VCL package. The combined size of the required files is roughly 3 MB at a minimum. In reality, the initial executable size of 23 KB is meaningless. Windows will display an error message if a required DLL or package cannot be located when the application starts. Once that happens, the game is up. Your application cannot run without the required files.
When static linking is used, the linker will pull the code needed to run the application from the RTL and package library files. The code is then linked directly into the application. This results in a larger executable size, but eliminates the requirement of shipping the DLLs and runtime packages. When built using static linking, a do-nothing C++Builder application compiles to about 350 KB. Although the initial size of the executable is larger, the runtime library DLL and runtime packages are not needed. The end result is that the entire distribution is much smaller.
In most cases you will want to use static linking. Use dynamic linking if you have a large application suite that contains many applications and/or DLLs. All of the EXEs and DLLs will share the code in the DLLs and runtime packages. Because of this, the overall size of the entire suite may very well be smaller than when static linking is used.
Creating a stand-alone EXE
Creating a stand-alone EXE requires modifying the project options to use static linking. There are two project options you must modify to accomplish this. Those options are explained in the following sections. After you have changed the project options and rebuild the project, the EXE will not require external files in order to execute.
The dynamic RTL
The first setting you must modify is the project’s use of the C++ runtime library DLL. This DLL contains the code for the C++ library. All C++ applications need the RTL code in order to operate.
By default, a new C++Builder project is configured to use the RTL DLL. The RTL DLL for C++Builder 5 is named CC3250MT.DLL. For other versions of C++Builder, it has a slightly different name. For C++Builder 4, for example, the DLL is named CP3245MT.DLL.
To eliminate the need for the runtime library DLL, open the Project Options dialog, click on the Linker tab, and uncheck the “Use dynamic RTL” option.
The second setting you must modify is the setting that controls how packages are used by the application. The default project settings require the use of runtime packages.
All VCL components (including those written by third parties) must reside in a package. Packages are nearly identical to DLLs in the way they are used by an application (the technical differences are not pertinent here). When you build an application using runtime packages, the application must be able to load the runtime package when it starts. When the use of runtime packages is turned off, the code for all components used in the project is linked into the executable.
To turn off the use of runtime packages, select the Packages page on the Project Options dialog and uncheck the “Build with runtime packages” option.
Exceptions to the rule
There are a few situations where you cannot build a stand-alone application. The first is the case of database applications. All C++Builder applications that use the VCL database components require the use of the Borland Database Engine (BDE). The BDE is a set of drivers and DLLs. The BDE cannot be statically linked to your application. You can still build your application using static linking (thereby eliminating the need for the dynamic RTL and runtime packages), but you will still need to ship the BDE with your application.
The second case where you cannot build a stand-alone application is when the application uses ActiveX controls. By their very definition, the code for ActiveX controls cannot be linked into an application. If your application uses ActiveX controls, you must ship the corresponding DLL or OCX file with your application. This applies to COM objects as well as ActiveX controls.
The third case is when an application uses third party libraries that are contained in DLLs. If the third party vendor supplies a static library, then you may use static linking. If only a DLL is supplied, though, you must ship that DLL with your application.
There are probably other situations where you cannot create a stand-alone EXE but these are the most common.
Setting default project options
For whatever reason, a default C++Builder project uses the dynamic RTL and runtime packages. I would venture that 95% of C++Builder users don’t build their projects with these setting. Fortunately, you can easily change the default settings for new projects. There are two ways to go about this.
The first way is to open the Project Options dialog and change the project options as explained earlier. Check the Default check box at the bottom of the dialog before you close the dialog. When you click the OK button, the default project file will be modified. Any new projects will use the project options you just set.
The second way is nearly identical to the first. In this case, though, you begin with no project open in the IDE. When you open the Project Options dialog with no project open, any changes made to the project options will automatically become the new defaults when you click the OK button.
You now know what you must do to build using either static or dynamic linking. Understanding not only how to accomplish this, but why you might use either option is important to any C++Builder developer.