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

问题描述 投票:17回答:4

我正在努力让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}

因此,虽然继续复制并粘贴用于Delphi 2006的ifdef并创建一个Delphi XE4块也很容易......但这似乎是一个不优雅的解决方案。这绝对不是未来的证明......你现在必须更新这个文件的每个新版本,因此Delphi 4中没有的一些代码不会让别人的15岁以上的遗留代码爆炸。

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

delphi conditional-compilation
4个回答
14
投票

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

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

对最新的编译器进行编码总是一个好主意,只使用条件部分来兼容旧版本。所以不要写{$IF CompilerVersion >= 26.0}而是以使用{$IF CompilerVersion < 26.0}的方式编写代码。因此,将来删除对旧版本编译器的支持要容易得多。


15
投票

如果我是一个组件供应商(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的答案,了解一种技术,您可以构建一个支持每个版本的.inc文件,并且只使用旧版本的旧版delphi版本。


6
投票

为了以后能够找到这个问题的任何人的利益,我认为可能值得记录我的最终解决方案,因为它结合了所有答案和评论中的一点点来使它工作,并且它花了更多时间找到我示例,以真正了解如何使用上面的一些建议。

为了处理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文档就会给出一个nice example of this

结合Warren建议使用大于或等于编译器版本的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有一个helpful whole chart,包含所有版本的Delphi及其命名常量,以及惯用的Package Name。在那个和这个stack overflow answer之间,我能够填写所有编译器版本常量。

一旦我在那里获得了这个块,我根本不需要在我的问题中使用Delphi 2005/2006块,而XE4很乐意编译。

我喜欢Uwe建议编码版本X及以下版本,而不是Y及以上版本,尽管我最终没有立即使用该建议,因为重写IFs和IFDEF就像翻录它一样多。首先支持Delphi 3 ;-)。


0
投票

答案比我想象的要简单。来自documentation

例如,要确定用于编译代码的编译器和运行时库的版本,可以将{$ IF}与CompilerVersion,RTLVersion和其他常量一起使用。

以下是从6到10.3(Rio)检测Delphi版本的完整代码:

{$IFNDEF FPC}
  {$IF CompilerVersion >= 33.0}
    {$DEFINE DELPHI_10_3_RIO_UP}
  {$IFEND}
  {$IF CompilerVersion >= 32.0}
    {$DEFINE DELPHI_10_2_TOKYO_UP}
  {$IFEND}
  {$IF CompilerVersion >= 31.0}
    {$DEFINE DELPHI_10_1_BERLIN_UP}
  {$IFEND}
  {$IF CompilerVersion >= 30.0}
    {$DEFINE DELPHI_10_SEATTLE_UP}
  {$IFEND}
  {$IF CompilerVersion >= 29.0}
    {$DEFINE DELPHI_XE8_UP}
  {$IFEND}
  {$IF CompilerVersion >= 28.0}
    {$DEFINE DELPHI_XE7_UP}
  {$IFEND}
  {$IF CompilerVersion >= 27.0}
    {$DEFINE DELPHI_XE6_UP}
  {$IFEND}
  {$IF CompilerVersion >= 26.0}
    {$DEFINE DELPHI_XE5_UP}
  {$IFEND}
  {$IF CompilerVersion >= 25.0}
    {$DEFINE DELPHI_XE4_UP}
  {$IFEND}
  {$IF CompilerVersion >= 24.0}
    {$DEFINE DELPHI_XE3_UP}
  {$IFEND}
  {$IF CompilerVersion >= 23.0}
    {$DEFINE DELPHI_XE2_UP}
  {$IFEND}
  {$IF CompilerVersion >= 22.0}
    {$DEFINE DELPHI_XE_UP}
  {$IFEND}
  {$IF CompilerVersion >= 21.0}
    {$DEFINE DELPHI_2010_UP}
  {$IFEND}
  {$IF CompilerVersion >= 20.0}
    {$DEFINE DELPHI_2009_UP}
  {$IFEND}
  {$IF CompilerVersion >= 19.0}
    {$DEFINE DELPHI_2007_FOR_NET_UP}
  {$IFEND}
  {$IF CompilerVersion >= 18.5}
    {$DEFINE DELPHI_2007_UP}
  {$IFEND}
  {$IF CompilerVersion >= 18.0}
    {$DEFINE DELPHI_2006_UP}
  {$IFEND}
  {$IF CompilerVersion >= 17.0}
    {$DEFINE DELPHI_2005_UP}
  {$IFEND}
  {$IF CompilerVersion >= 16.0}
    {$DEFINE DELPHI_8_FOR_NET_UP}
  {$IFEND}
  {$IF CompilerVersion >= 15.0}
    {$DEFINE DELPHI_7_UP}
  {$IFEND}
  {$IF CompilerVersion >= 14.0}
    {$DEFINE DELPHI_6_UP}
  {$IFEND}
{$ENDIF}

您可以找到整个编译器版本列表,例如here

© www.soinside.com 2019 - 2024. All rights reserved.