【问题标题】:How to define version "and up" ifdefs in Delphi?如何在 Delphi 中定义版本“及更高版本”ifdefs?
【发布时间】:2014-07-05 10:15:03
【问题描述】:

我正在努力让 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 的格式出来了。

【问题讨论】:

  • 我这样做,但我在一个 .inc 文件中这样做。 ${IF CompilerVersion >= 17} {$DEFINE DELPHI_2005_UP} {$ENDIF} 打字少得多。而且我更喜欢通过我的实际代码输入{$IFDEF DELPHI_2005_UP}This{$else}That{$endif}
  • {$IF} 是在 Delphi 6 中引入的。如果您需要在 Delphi 5 或更早版本中编译,则必须将 {$IF} 语句包装在 {$IFDEF CONDITIONALEXPRESSIONS} 块中。

标签: delphi conditional-compilation


【解决方案1】:

IIRC,Delphi 6 引入了条件表达式,这实际上是 TLama 所建议的。要使您的代码与低于该版本的 Delphi 版本一起使用,您必须检查 {$IFDEF CONDITIONALEXPRESSIONS }。如果未定义,则必须使用旧的VERxxx 方案来区分 Delphi 版本。

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

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

【讨论】:

  • 我喜欢避免使用完整长度的 {$if CompilerVersion
【解决方案2】:

如果我是组件供应商(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 版本使用旧形式。

【讨论】:

  • 一些供应商仍然支持 Delphi 5,其中 {$IF} 尚不可用。
  • 是的,我没有,因为我不是组件供应商,只是一个 Delphi 用户。
【解决方案3】:

为了让将来找到这个问题的人受益,我认为可能值得记录我的最终解决方案,因为它需要结合所有答案和 cmets 中的一点点才能使其工作,并且需要找到我再举几个例子来真正理解如何使用上面的一些建议。

为了处理 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 及其命名常量,以及惯用的包名称。在此和stack overflow answer 之间,我能够填写所有编译器版本常量。

一旦我得到这个块,我什至根本不需要我的问题中的 Delphi 2005/2006 块,XE4 很高兴地编译了。

我喜欢 Uwe 的建议,即尽可能为版本 X 及更低版本而不是 Y 及更高版本编码,即使我最终没有立即使用该建议,因为重新编写 IF 和 IFDEF 会很麻烦首先是取消对 Delphi 3 的支持;-)。

【讨论】:

    【解决方案4】:

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

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

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

    {$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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 2021-11-17
      • 2019-11-20
      • 2022-01-02
      • 2023-03-27
      • 1970-01-01
      • 2015-03-04
      相关资源
      最近更新 更多