F2051:单位%s使用不同版本的%s编译

时间:2014-08-28 17:49:21

标签: delphi delphi-xe6

我们一直在使用Delphi XE6修复VCL中的错误。到目前为止,该文件夹包含:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas

我们将文件夹添加到图书馆搜索路径:

enter image description here

在此过程中,我们了解到我们必须将修复仅限于implementation部分 。否则interface部分中符号的哈希签名会发生变化。这会导致链接器意识到DCU中的符号与它们期望的版本不同。

Barry Kelly对此行为有一个很好的解释:

  

重要的概念是符号版本。保存DCU时,Delphi会根据符号的接口声明计算散列值,并将其与符号相关联。使用该符号的其他单位也存储符号版本。这样,与大多数C链接器不同,避免了由陈旧符号引起的链接时冲突。

     

这样做的结果是,您应该能够将Classes.pas添加到您的项目中,并将其实现部分修改为您的内容,并且仍然可以静态链接其他RTL和VCL以及第三方库,甚至是仅以对象格式提供的库。

     

要小心的事情:

     
      
  • 内联例程;内联例程的主体是符号版本的一部分
  •   
  • 泛型;泛型类型和方法的实现方是各自符号版本的一部分
  •   

因此,我们努力将错误修正限制在实现部分(例如,引入新的cracker类,而不是覆盖面向公众的类中的方法)。

然后

然后我去Vcl.Themes.pas进行修复。我开始简单,复制文件并将其放在fixes文件夹中:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
|----- Vcl.Themes.pas

即使我还没有(还)修改过Vcl.Themes.pas,编译器就会对它进行扼流:

  

[dcc32致命错误] Vcl.Themes.pas(2074):F2051单元Vcl.Forms是用不同版本的Vcl编译的.Themes.TMouseTrackControlStyleHook

为什么

重要的问题是:

  

为什么会这样?

编译器无法识别完全相同的文件是完全相同的文件是怎么回事? XE6附带的VCL源是否可能不合适,并且与DCU中的船舶不匹配?它与库搜索顺序有关吗?它是否与内联,泛型,迭代器,平台,调试dcus,64位编译器,ifdef,代码完成,协同作用等有关?

还有其他隐含的问题与尝试回答为什么

  

为什么它适用于其他两个文件,但不适用于此文件?   当我甚至没有更改文件时为什么会失败?

你有什么尝试?

  • 尝试在搜索路径中移动VCL Source Fixes更高和更低
  • 尝试启用使用调试dcus
  • 尝试切换到64位平台
  • 尝试删除项目文件夹中的所有dcu个文件(虽然没有删除Delphi XE6附带的D:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu
  • 关闭XE6并重新运行
  • 去Wendy吃午饭

当然我想解决它。但不仅仅是想解决这个问题,我想了解它失败的原因。编译器没有使用魔法,伏都教或类似Q的能力。它是一个确定性的机器,并且根据一组固定的(未记录的)规则进行操作。

为什么会这样?

另见

1 个答案:

答案 0 :(得分:7)

您需要编译器选项以匹配Embarcadero编译单元时使用的选项。这就是为什么你的实现部分只有在它看起来应该成功时才会失败的原因。

启动默认项目并使用 CTRL + O + O 生成这些选项。我得到了

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

当我在XE6中这样做时。

把它放在你单位副本的顶部,你应该好好去。根据您的主机项目选项,您可以放弃这些的缩减子集。在我的代码中,我发现:

{$R-,T-,H+,X+}

就足够了。