Version dependent compiles - $ENDIF and $IFEND - delphi

I seem to be in a catch 22 situation. I want to add compiler version dependant code. OK - that is pretty standard. But the syntax of the $IF statements is different between versions.
Here is what I am trying to achieve
{$IF CompilerVersion = 28}
if (fPendingObject = pObject) and (Addr(fPendingActionEvent) = Addr(pPendingActionEvent) ) then
{$ELSE}
if (fPendingObject = pObject) and (#fPendingActionEvent = #pPendingActionEvent ) then
{$ENDIF}
This compiles in Delphi XE7, but not in Seattle or Berlin. Those compilers require the syntax
{$IF CompilerVersion = 28}
if (fPendingObject = pObject) and (Addr(fPendingActionEvent) = Addr(pPendingActionEvent) ) then
{$ELSE}
if (fPendingObject = pObject) and (#fPendingActionEvent = #pPendingActionEvent ) then
{$IFEND}
($IFEND instead of $ENDIF). But XE7 won't accept that syntax.
There obviously must be a trick, and indeed the Delphi 2009 documentation says so, but my poor brain can't work out the trick. Can someone help?

There is a compiler option that allows the use of the older {$IFEND} directive:
Project
Options
Delphi Options
Compiling
Require $IF to be terminated by $IFEND: [x] true
Then there is the {$LEGACYIFEND ON|OFF} directive, which does the same, locally. Setting it on will make XE7 accept {$IFEND}, like in the older versions. I often use something like:
// For Delphi XE3 and up:
{$IF CompilerVersion >= 24.0 }
{$LEGACYIFEND ON}
{$IFEND}
Obviously, this option is on by default in your Seattle or Berlin projects, but not in XE7. You can turn it off or on, depending on your preferences.

Related

Is there a compiler define that separates Delphi 11.0 from 11.1?

There are a few corrected issues in the VCL which had previous workarounds. Is there some method to identify that Delphi 11.1 is in fact installed and not 11.0 so the fix can be used rather than the workaround? The compiler defines for RTLVersion and CompilerVersion have not changed and are still 35.0. The static compiler define is also still VER350.
There is RTLVersion111 constant which you can use to determine whether you are dealing with 11.1
const
RTLVersion111 = True;
{$IF RTLVersion111}
Writeln('DEFINED RTL 11.1');
{$ELSE}
Writeln('NOT DEFINED RTL 11.1');
{$IFEND}

Compiler directive is not set in Delphi 10.2

I have the following unit implementation in my delphi probject.
uses
{$IFDEF Ver270} JSON, {$ELSE} DBXJSON, {$ENDIF}
In Delphi XE4 DBXJSON will be implemented - that's fine.
In Delphi XE6 JSON will be implemented - that's fine too.
But in Delphi 10.2, DBXJSON will be implemented - not JSON. Why? Is this a bug in Delphi 10.2?
This is not a bug, it is by design. Each version has exactly one VERXXX definition. VER270 is defined in XE6 and XE6 only. For version 10.2 VER320 is defined.
In your scenario it is much simpler to use code like this:
uses
{$IF RTLVersion >= 27} JSON, {$ELSE} DBXJSON, {$IFEND}
Another option is to use a standard include file like jedi.inc. This takes the pain out of such conditional statements. If you use jedi.inc then you can code it like this:
uses
{$IFDEF DELPHIXE6_UP} JSON, {$ELSE} DBXJSON, {$ENDIF}

Delphi CompilerVersion directive issues

I have a library code file which is shared between Delphi 5 and DelphiXE2. I am attempting to add anonymous method functionality to the code file, but only for DelphiXE2 projects (since Delphi 5 doesn't support anonymous methods). It seemed I should be able to use the CompilerVersion (Note: I don't want to limit it to DelphiXE2, just in case we ever upgrade).
{$IF CompilerVersion >= 23}
{$DEFINE AnonymousAvail}
{$IFEND}
This worked nicely in XE2, but it turns out, Delphi 5 doesn't support the $IF directive. I decided to wrap it in an $IFDEF. This worked nicely in Delphi 5, but XE2 also doesn't seem to have CompilerVersion defined, so AnonymousAvail is not defined.
{$IFDEF CompilerVersion}
{$IF CompilerVersion >= 23}
{$DEFINE AnonymousAvail}
{$IFEND}
{$ENDIF}
Any help would be appreciated.
Note: I cannot move anonymous method code to a different code file.
Do what the documentation says:
{$IFDEF ConditionalExpressions}
{$IF CompilerVersion >= 23.0}
{$DEFINE AnonymousAvailable}
{$IFEND}
{$ENDIF}
Be sure that the outer condition is as shown (and closed with ENDIF) and you can use CompilerVersion and other constants and expressions inside.
You can also use
{$IF defined(BLAH)}
or, one of my favourites:
{$IF declared(AnsiString)}
etc...
FWIW, I noticed that the example in the link comes, almost verbatim, from my Console.pas unit.

From which version "vclunit.pas" changed to "Vcl.vclunit.pas"?

I made a component in Delphi 2007 and now I want to make it work with new versions of Delphi so I must change the uses from
uses Controls;
to
uses {$if CompilerVersion > 21}Vcl.Controls{$else}Controls{$ifend};.
But I don't know the compiler version I must write. Anyone knows it?
Unit scope names were introduced in XE2. And XE2 is compiler version 23. So the conditional is:
{$if CompilerVersion >= 23}

Can I generate a custom compiler error? If so, how?

Here is what I want to do. I have a project that must be compiled in some version of Delphi or later. I would like to use a conditional compiler directive to test the Delphi version, and then cause a custom compiler error to be generated with a custom message. Being able to generate a custom compiler warning or hint would also be adaquate if an error is not possible.
Sure, I could put some un-compilable giberish in the conditional code segment, and that's fine. But my question is "Can I generate, conditionally, a custom compiler error?"
Thank you Johan and Serg.
Here is the solution, and more details about the issue. I have an application that was originally built in Delphi 2007. It includes Internet Direct components to attach to a Web service. These use SSL. I recently upgraded my SSL libraries to a later version, and these don't play so well with the Delphi 2007 Indy components. I have now added the following compiler directives to ensure that this application will no longer be compiled with Delphi 2007 or earlier:
{$IF CompilerVersion <= 19.0} // Delphi 2007 = 19.0
{$MESSAGE Error 'This project must be compiled in Delphi 2009 or later'}
{$IFEND}
You can use:
{$Message HINT|WARN|ERROR|FATAL 'text string' }
{$MESSAGE 'Boo!'} emits a hint
{$Message Hint 'Feed the cats'} emits a hint
{$messaGe Warn 'Looks like rain.'} emits a warning
{$Message Error 'Not implemented'} emits an error, continues compiling
{$Message Fatal 'Bang. Yer dead.'} emits an error, terminates compiler
See: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsmessagedirective_xml.html
This works in Delphi 6 and later.
Checking the Delphi version has become easy since CONDITIONALEXPRESSIONS directive was introduced in Delphi 6:
program requires2010;
{$APPTYPE CONSOLE}
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion >= 21.0} // 21.0 is Delphi 2010
{$DEFINE DELPHI2010}
{$IFEND}
{$ENDIF}
begin
{$IFNDEF DELPHI2010}
{$MESSAGE Fatal 'Wrong Delphi Version'}
{$ENDIF}
Writeln('Continued');
Readln;
end.

Resources