Backwards compatibility to older Delphi versions is an issue mostly encountered by component and IDE plugin developers. Borland, Codegear and Embarcadero actually did quite a good job in that area. Many ancient projects (at least back to Delphi 6) can simply be loaded into a later IDE and they just compile. The IDE usually makes the necessary changes. That of course does not mean that there aren’t any hiccups 😉
One commonly encountered problem is that some declarations have moved to different or newly introduced units over the time. Two examples of that are
- TAction, moved from ActnList to Actions, later System.Actions and again to Vcl.ActnList and Fmx.ActnList.
- TImageList, moved from Controls to ImageList, later System.ImageList and again to Vcl.Controls and Fmx.ImageList.
(I hope I got these right.)
This has two effects:
- Later IDEs automatically add the new unit names to the uses lists of forms that use these components. Unfortunately it ignores any {$IFDEF}s you might already have in place there, so the generated source code does not compile due to a duplicate in the uses list: “E2004 Identifier redeclared: ‘Actions'”.
- Older IDEs will no longer compile the code because these units are not available there: “F1026: File not found ‘Actions.dcu'”
Unit aliases can solve this problem. You add an entry “NewUnit=OldUnit” to the unit aliases list in the project options, in this case that would be:
Actions=ActnList;ImageList=Controls
You then simply add the new unit names to the uses list. This solves both issues: The IDE will find the unit it expects and will no longer try to add it. And older compilers will know that the new unit just maps to another one they can find.
If it’s just about backwards compatibility, an entry “NewUnit=System” would also do the trick.
btw: You can safely remove the pre defined aliases for the units Windows and BDE. They date back to ancient times (Delphi 3 in 1997?) when multiple units for each of these were merged into a single one.
btw: Apparently it is not possible to define a unit alias that starts with an underscore:
_Actions=ActnList
will result in the compiler error: “F1030: Invalid compiler directive: ‘-A_Actions=ActnList'” (at least in Delphi 2007). It’s allowed to end in an underscore though.
Edit: I already blogged about unit aliases and what they are good for in 2016 in Backwards compatibility of uses lists. So this is just some additional explanation and also gives me the list should I need it again.