如何在Delphi中定义版本“和up”ifdefs?

我正在努力让Log4D在Delphi XE4中工作,并且因为它无法在uses子句中找到Contnrs而出现一些编译错误,除非我将它移到定义的ifdef之外。

{$IFDEF DELPHI5_UP}
  Contnrs,
{$ENDIF}

有一点调查发现,ifdef是在一个包含文件Defines.inc中定义的,该文件为delphi的每个“受支持”版本提供了一个块,它停止了几个版本:

例如:

{$IFDEF VER170}  { Delphi 2005 }
{$DEFINE DELPHI9}
{$DEFINE DELPHI4_UP}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$ENDIF}

{$IFDEF VER180}  { Delphi 2006 }
{$DEFINE DELPHI10}
{$DEFINE DELPHI4_UP}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}

所以虽然这将很容易,继续前进,并复制和粘贴ifdef为Delphi 2006,并创建一个Delphi XE4块...这似乎是一个不雅的解决方案。 这绝对不是未来的证明......现在每一个新版本都要更新这个文件,所以Delphi 4中没有的代码不会让别人的15年以上的旧代码爆炸。

所以我想知道是否有更好的方法来进行条件编译,以便在编译该行时确实检查您是否具有“Delphi 5或更高版本”,而不是需要更新每个新版本的delphi的格式。


IIRC,Delphi 6引入了条件表达式,这实际上是TLama建议的。 为了使你的代码在Delphi版本下工作,你必须检查{$IFDEF CONDITIONALEXPRESSIONS } 。 如果未定义,则必须使用旧的VERxxx方案来区分Delphi版本。

对于Delphi 6及更高版本,您可以使用内置常量CompilerVersionRTLVersion 。 你使用哪一种取决于你的代码。 每当您对CompilerVersion使用新的编译器功能测试时。 用于与RTLVersion的RTL或VCL测试相关的任何内容。

对最新的编译器进行编码并且仅使用条件部分来兼容旧版本是一个好主意。 因此,不要编写{$IF CompilerVersion >= 26.0} ,而应使用{$IF CompilerVersion < 26.0}来编写代码。 因此,将来更容易放弃对旧版编译器的支持。


如果我是一个组件供应商(TMS,DevEx),我可能会感到不得不坚持每个delphi版本都支持的冗长冗长的语法。 这就是为什么大部分组件代码库都有这么大的混乱。

然而,对于我自己的内部组件,我不更新每个版本,因为我的ver.inc文件看起来像这样,并且我不支持所有不支持这种新语法的Delphi版本:

{ver.inc}

{ MYSOFT VERSION DEFINES }


{$IF CompilerVersion >= 22.0}
{$DEFINE RTL220_UP}
{$DEFINE XE_UP}
{$IFEND}

{$IF CompilerVersion >= 23.0}
{$DEFINE RTL230_UP}
{$DEFINE XE2_UP}
{$IFEND}

{$IF CompilerVersion >= 24.0}
{$DEFINE RTL240_UP}
{$DEFINE XE3_UP}
{$IFEND}

{$IF CompilerVersion >= 25.0}
{$DEFINE RTL250_UP}
{$DEFINE XE4_UP}

{$IFEND}

{$IF CompilerVersion >= 26.0}
{$DEFINE RTL250_UP}
{$DEFINE XE5_UP}
{$IFEND}

{$DEFINE OTHER_THING}

当新的delphi版本发布时,上面代码中没有任何内容会被破坏。 请注意,我不需要使用我的代码库支持Delphi 5到2010。 实际上,我只支持XE2以上。

上述表格的稍长版本可用于支持Delphi 6及更高版本的每个版本,且无需任何重复块,并且每次发布新的delphi版本时都不会中断。

另外,请参阅Uwe的技术答案,您可以在其中创建一个支持EVERY版本的.inc文件,并且只使用旧版本的旧版本。


为了将来有人发现这个问题,我认为这可能是值得记录我的最终解决方案的,因为它将所有答案和评论中的一小部分结合在一起,使其发挥作用,并且找到了我更多例子来真正理解如何使用上面的一些建议。

为了处理Delphi 6之前不支持{$IF} ,我将它们保持原样。 至多你会有5个,但在我的情况下,它只有2个:

{$IFDEF VER120}  { Delphi 4 }
  {$DEFINE DELPHI4}
  {$DEFINE DELPHI4_UP}
{$ENDIF}

{$IFDEF VER130}  { Delphi 5 }
  {$DEFINE DELPHI4_UP}
  {$DEFINE DELPHI5_UP}
{$ENDIF}

然后对于支持{$ IF}(Delphi 6+)的版本,我将它们包装在Uwe建议的{$IFDEF CONDITIONALEXPRESSIONS }块中。 一旦我知道了正确的搜索条件,Embarcadero文档就证明了这一点。

结合沃伦关于在大于或等于编译器版本的情况下使用IF块的建议,大大简化了事情:

{$IFDEF CONDITIONALEXPRESSIONS} { Delphi 6+ }

  {$IF CompilerVersion >= 14.0} { Delphi 6+ }
    {$DEFINE DELPHI4_UP}
    {$DEFINE DELPHI5_UP}
    {$DEFINE DELPHI6_UP}
  {$IFEND}

  {$IF CompilerVersion >= 15.0} { Delphi 7+ }
    {$DEFINE DELPHI7_UP}
  {$IFEND}

{$ENDIF}

Embarcadero有一个有用的整个图表,包括Delphi的所有版本和它们的命名常量,以及习惯的Package Name。 在这个和这个堆栈溢出答案之间,我能够填写所有编译器版本常量。

一旦我在那里获得了这个块,我甚至不需要Delphi 2005/2006块来解决我的问题,而XE4很乐意编译。

尽管我没有立即使用这个建议,但我仍然喜欢Uwe建议的编码版本X和以下版本,而不是Y和以上版本,因为重做IF和IFDEF可能会导致翻版首先支持Delphi 3 ;-)。

链接地址: http://www.djcxy.com/p/67675.html

上一篇: How to define version "and up" ifdefs in Delphi?

下一篇: Delphi: Generics, Interfaces