About Packages – Thougts after a Delphi Migration Workshop in Denmark

I had a nice day at PC-Ware in Denmark yesterday. The seminar was full and it was fun to talk through all new stuff in Delphi from a Win32 developer’s perspective. One of the topics of the seminar was to give attendees a good strategy to
migrate a project from one Delphi version to another.

One of the participants in the Migrate workshop completed his upgrade of a large Delphi 7 project in less than one hour with only one minor problem when upgrading component packages.

Recompiling your home written and 3rd party components is a problem I see many users struggle with when migrating.

I always strongly encourage developers to make sure they have all source code for their 3rd party components to guarantee that they will be able to upgrade to new Delphi versions in the future.

Gift wrap

Components are classes in ordinary units compiled into a package. A package is actually an ordinary dll with the extension changed to bpl. A package can be either a design-time package or a run-time package. Design-time packages are loaded by Delphi to get the components onto the Tools Palette and into the Form Designer in the IDE. It is important to understand that Delphi only can load packages compiled with the same Delphi version.

A package has usually dependencies to other run-time packages. This is listed in the requires-clause in the Delphi package project file. Select view source on the dpk-file to see them.

Complex Search

The ordinary Windows API’s LoadLibrary is used to load packages into memory. This means that dependent packages must be in a location where LoadLibrary
looks for them. It is a complex search that depends on operating system version. Basically it looks in the directory from which the application was loaded, the system and windows folder, current directory and in all folders in the process environment variable PATH. As you can guess it can easily get hold of the wrong version of the file if you are not careful.

To minimize the risk of loading a package compiled by another Delphi version it is recommended to add a number after the package name that corresponds with the version number of Delphi. For Delphi 7 that would be 70 and for Delphi 2006 the number is 100.

Simple to upgrade

To make it easier for you to upgrade a package this number is added automatically to the package name of all packages listed in the requires-clause. So, the only thing you need to do to upgrade a package is to save it with a new number corresponding to the new Delphi version, build it and install it.

This functionality was added after Delphi 5 so if you upgrade a Delphi 5 it is probably easier to empty the requires-clause and let the Delphi IDE help you to
rebuild it by recompiling several times.

Migrate in minutes

So to make a simple to upgrade your component packages follow this check list:

  • Open each DPK-file and save them with a new version number matching the Delphi version.
  • Add all DPK-files to a project group by right clicking on the Project Group in the Project Manager and clicking add existing project. If several packages depend on each other order them with build sooner and build later.
  • Verify that your package output directory (set in Tools|Options) is in your Path variable. Otherwise LoadLibrary will not be able to find dependent packages. It is also possible to
    make a local override for environmental variables in Delphi’s Options dialog.
  • Build all packages.
  • If you have IFDEF in the source code and it does not compile, try to add conditional defines for earlier Delphi Compilers in Project Options until it compiles. (VER150 – Delphi 7; VER140 – Delphi 6; VER130 – Delphi 5). NOTE! Remember that version number of Delphi used in package names and the version number of Delphi compiler used in IFDEF is different!
  • If you get an error because unit DsgnIntf is missing, replace it with DesignIntf and DesignEditors.
  • If you are using units like DesignIntf and other units from the ToolsAPI folder and it does not compile try to add DesignIDE to your requires-clause of your package.
  • Finally, right click on all packages from top to bottom and select install on each of them. Run-time packages will fail to install but it is harmless.