Everytime a new Delphi version arrives, a library vendor releases a new version or you are going to change to a newer version of some open source library it is quite likely you are getting into some hassles while integrating these changes or new version into your preferred Delphi IDE(s). Although there are vendors that actually do a good job here there are cases when there is some room for improvement. Here I am going to list some things that bothered me in the past and ways to make it easier for the developer to adapt those libraries to a newer Delphi version (without waiting for the vendor).

Disclaimer: These guide lines are resembling my personal preferences that match my own needs. Your personal needs may be better suited in other ways.

Package Naming

The Package Names and unit names must be distinct, so don’t use a generic name like DbComponents. It is quite likely that another one has the same bright idea. If possible, use a specific prefix for the package as well as for the unit names. Ideally all units of this library should be grouped together when listed alphabetically.

The Delphi version is not part of the package name nor is the package version. Use the LIBSUFFIX for the Delphi version and stick with the Delphi convention for libraries (XE=150, XE2=160, … XE8=220). In case of a new version of Delphi, you only copy the exsting packages and adjust the LIBSUFFIX. Make sure to set the LIBSUFFIX in the base configuration so it can be inherited.

Two packages of different versions cannot be loaded simultanously anyway, so leave the package version to its version info. If you put the package version into the package name, people will have to adjust these names on different places (projects, setups) to make use of the new version.

Folder structure

The units together with the DFMs are located in the source subfolder, while the packages reside in the packages subfolder. The packages folder again contains one subfolder for each supported Delphi version. The package naming is consistent between all Delphi version.

The unit output is set for all packages to avoid dcu files in the source folder. The target folders for each target and build configuration is a subfolder of the package folder. This can easily be achieved with $(Platform)\$(Config) in the base configuration settings.

The target folders for bpl and dcp are empty so the files automatically go to the right place where they can be found by the IDE.

Switching between different versions of one library inside the IDE is a little bit tricky and may be part of another blog post in the future.

Miscellanous

Provide a project group ordered by dependency and relevance to open all packages at once. Set all packages to Release configuration and Win32 target on delivery. So for the developer to install the packages it is just:

open the project group

compile all

install each design time package

close all

If you want to provide an easy way to compile for different targets and build configurations use a Build Group. That will change the above step compile all to compile build group.

At least for designtime packages give a decent Description! Best put it into the base configuration (see LIBSUFFIX above). Otherwise the IDE will only show the file path of the package in the list of designtime packages.

Avoid packages declared as design and runtime! Use either designtime or runtime. I am still waiting for a case where such a combination is really necessary.

Keep the requires clause as small as possible. There is no need to repeat the required list from a runtime package inside a designtime package that already requires that runtime package.

Discussion

It is most likely that readers will have different opinions on some points mentioned in this article. Feel free to express yourself in the comments.