我正在努力让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 。
IIRC,Delphi 6引入了条件表达式,这实际上是TLama建议的。为了使您的代码能够使用下面的Delphi版本,您必须检查{$IFDEF CONDITIONALEXPRESSIONS }
。如果没有定义,则必须使用旧的VERxxx
方案来区分Delphi版本。
对于Delphi 6及更高版本,您可以使用内置常量CompilerVersion
和RTLVersion
。您使用以下哪些取决于您的代码。每当您为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的答案,了解一种技术,您可以构建一个支持每个版本的.inc文件,并且只使用旧版本的旧版delphi版本。
为了以后能够找到这个问题的任何人的利益,我认为可能值得记录我的最终解决方案,因为它结合了所有答案和评论中的一点点来使它工作,并且它花了更多时间找到我示例,以真正了解如何使用上面的一些建议。
为了处理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 ;-)。
答案比我想象的要简单。来自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。