2

I am updating our projects from XE7 to XE8. For the time being they will still need to work with XE7, so a few conditionals are required. For example, ImageList has changed units, so Vcl.ImgList is Syste.ImageList in XE8. To make it work on both Delphi versions the uses clause looks something like this:

uses
  System.SysUtils, System.Classes, Vcl.Controls
  {$IF CompilerVersion >= 29.0}
  ,System.ImageList
  {$else}
  ,Vcl.ImgList
  {$endif}

  ,cxGraphics;

Sometimes this works fine. However, quite often Delphi automatically re-adds the System.Imagelist unit even though it is already there, albeit in a conditional e.g.

uses
  System.SysUtils, System.Classes, Vcl.Controls
  {$IF CompilerVersion >= 29.0}
  ,System.ImageList
  {$else}
  ,Vcl.ImgList
  {$endif}

  ,cxGraphics, System.ImageList;

When this is compiled, XE8 complains.

[dcc32 Error] dmImagesU.pas(13): E2004 Identifier redeclared: 'System.ImageList'

a) Why does Delphi add the unit? b) Anybody know a workaround?

norgepaul
  • 6,013
  • 4
  • 43
  • 76
  • You can try to use {$IFDEF VER290} instead compiler version constant. Maybe it will help? – Darthman Aug 27 '15 at 09:26
  • I deleted my answer because I found a dupe that has much more detailed coverage. What I wrote in my deleted answer here is to use a unit alias, discussed in depth at the dupe. I commend the unit alias approach to you. – David Heffernan Aug 27 '15 at 09:39
  • I'm not sure it's quite that simple David. This isn't a 1:1 replacement/renaming of a unit. Both units exist in XE8 and, interestingly, when you create a brand new project in XE8 adding a TImageList component to a form results in **both** units being added to the *uses* clause, not just the *System.ImageList* unit. So it seems that XE8 needs, or at least 'recommends' the Vcl.ImgList unit (for types/constants?) **and** the System.ImageList unit for the class itself. Another fine mess Embarcadero have gotten everyone into. – Deltics Aug 27 '15 at 09:56
  • I think there is 2 modules because of FM components. Core in Syste.Imagelist and all VCL stuff in VCL.ImgList. – Darthman Aug 27 '15 at 10:04
  • @Deltics The code in the question is either or isn't it? I was working from that. Anyway, if you want to use either 1 or 2 units depending on version, you can do so with an alias in just the same way. You just use both units, and conditionally alias one of them to `System`. And if you want to use either or, then you do it by using a single unit, and aliasing in one of the projects. It really is that simple. – David Heffernan Aug 27 '15 at 10:39
  • Yes, but unit aliases are project settings, which makes them inconvenient if your project has to be maintained in different IDE versions (as is explicitly stated in both this and the other question). Placeholder units on the other hand can be conditionally used in explicit paths in the DPR source, avoiding the need for project specific settings or IDE specific option sets (a refinement to my answer in that other question which I overlooked at the time, although it is vulnerable to the IDE altering the DPR uses list). Hey ho. – Deltics Aug 27 '15 at 10:57
  • @Deltics You can do it that way if you want. But I strongly rebutt your statement that unit aliases won't solve this issue. They can solve either 2 -> 1 or either/or variants. – David Heffernan Aug 27 '15 at 11:06
  • @David - huh ? Where is this "statement" you claim to have rebutted ? By all means have a different opinion, but I don't see why you seem to feel the need to bolster it by claiming that it somehow has rebutted something that never even existed. Very strange. – Deltics Aug 27 '15 at 22:12
  • @Deltics You said it's not quite that simple. I think it is. – David Heffernan Aug 27 '15 at 22:13

1 Answers1

5

The "parser" that is responsible for adding units to the uses in this case is not considering compiler directives properly (that issue already occured with the introduction of System.Actions.pas).

I usually create a dummy unit for older Delphi versions so I don't have to put any directives into the uses.

So in your case just create an empty System.ImageList.pas and put that somewhere <= XE7 finds it.

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102