This year (2020) Delphi celebrates its 25th anniversary. In those 25 years an enormous amount of code has been written. Many of these applications are still in full use by companies and individuals. This shows the power of Delphi; code written decades ago still works, even in the latest Delphi versions.
Still, there are some remarks to be made about this praise. Unfortunately we see that there are also many applications that are still being developed in old Delphi versions. That is a pity, because the new versions of Delphi really have a lot of advantages. Not only is the IDE much more pleasant to use, the new language enhancements are a real improvement.
There are a number of recurring problems when converting older Delphi applications to the latest Delphi version. For example, as of Delphi 2009 you have to take Unicode into account. In addition, there may be components that are no longer being developed, or that have been significantly modified. This means that there are still companies working with Delphi 5, Delphi 7 or some other old versions. Now, converting your source code is not always easy. At GDK Software we have had many projects and customers who came to us with older Delphi software. Because we often come across the same issues, we have developed a tool that makes conversion much easier; the GDK Compiler Helper. In this post I will briefly explain how the GDK Compiler Helper assists us with the conversion projects, and how GDK Software can also help you with the upgrade of your Delphi project.
GDK Compiler Helper
The GDK Compiler Helper uses the Delphi compiler to automatically compile programs, search for errors and modify code to fix these errors. Because all changes are carried out via actions, you can just grab the latest codebase and restart the conversion every time. During the development of the GDK Compiler Helper we have always had in mind to automate the conversion as much as possible.
I will start with a brief introduction to the mechanics of the GDK Compiler Helper. After that I will give some examples of the different actions the tool can perform.
We perform a number of steps automatically before starting the compilation process. First we do a pre-compile action on all source code. This consists of the following actions:
- Convert all form files (.dfm files) to text files
- Perform all pre-process actions that are defined
To start with the first point; with Delphi it is possible to save form files as binary files. Since it is possible to replace components with the compiler helper, the form files must be saved as readable text files.
Then we perform all pre-process actions. Suppose we know that in every pascal file certain modifications have to be made, we can specify these in the action list. The compiler helper will first perform these actions on all source code, before starting the actual compilation.
Then we use the Delphi compiler to compile the project and fix errors.
For the purpose of fixing errors, warnings and hints, we have created a database of actions, which the compiler helper uses to automatically perform code changes and recompiles the source code. An action can consist of:
- Add a unit to the uses
- Remove or rename units
- Modify the code by using a simple replace
- Modify the code using Regular Expressions
- Add a prefix to an identifier or variable
- Change the type of a variable
- Replace a (design time) component
- Replace all code by running a replace or Regular Expressions over the pascal file.
Examples of actions
Because we have performed many conversions at GDK software, we have compiled quite an extensive list of these actions. Through the GDK Compiler Helper we can easily add and edit these actions:
Some examples of compiler errors and the corresponding actions are:
error E2003: Undeclared identifier: 'CurrencyString'
The solution is the action
AddPrefixToIdentifier and the prefix or solution is
FormatSetting.. Here the GDK Compiler Helper automatically updates the code to
FormatSettings.CurrencyString. Likewise for the following errors:
error E2003: Undeclared identifier: 'CurrencyFormat'
error E2003: Undeclared identifier: 'CurrencyDecimals'
error E2003: Undeclared identifier: 'DateSeparator'
error E2003: Undeclared identifier: 'TimeSeparator'
[...and so on]
error E2003: Undeclared identifier: 'VarArrayOf'
In this case a unit must be added to the uses class. This is done by using the action
AddUnitToInterface where the unit
An example of a more complex action is the solution to the following problem:
error E1050: WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit.
In this example, we have identified the Delphi warnings to show as errors. The solution to this problem is the
ReplaceByRegEx action. For a replace action (both the regular action and the Regular Expressions action) we need to specify two parameters; the search string, and the result. In this particular case, the search string was a rather complex Regular Expressions function
and the result
The Compiler Helper will apply this solution to the specific line of code, after which the compilation process will continue with the rest of the source code.
While working on a conversion, you obviously want to add new actions as easily as possible. Although the GDK Compiler Helper can solve quite a lot of things automatically, there are always specific problems that need to be solved for a project. That’s why you can easily add your own solutions and actions.
As an illustration I will show an example of a part of the conversion of the (open source) MPEG Audio Collection Library. One of the Delphi projects gives the following error message:
error E2003: Undeclared identifier: 'ReadLn'
The corresponding code line is
Str := TCP.ReadLn;
By analyzing the source code I know that the ReadLn function of the Indy Libraries is now in unit
TCP.IOHandler instead of in the unit
TCP. So we need the action
ReplaceIdentifier and replace TCP. with TCP.IOHandler. Adding this action is now very easy:
The main advantage of modifying your source code in this way is that it is transferrable. If this specific code occurs again somewhere else, the GDK Compiler Helper will automatically apply this solution there and continue compiling.
As you have seen it is incredibly easy to update existing Delphi projects to the latest Delphi version with the GDK Compiler Helper. You can also continue the existing development for the old version of the software during the conversion project. Because all changes are stored in actions you can just grab the latest codebase and restart the conversion every time.
How we can help
At GDK Software we want to share our knowledge with other developers, and we want to help companies to get and keep their Delphi software up to date. Therefore we have interesting options to use the GDK Compiler Helper for your software project as well.
Are you interested in a personal demo of the GDK Compiler Helper, or are you looking for help converting a Delphi project? Please contact me via firstname.lastname@example.org, or via our website GDK Software.
Thanks for reading!