【问题标题】:F2051 Unit was compiled with a different version (again)F2051 单元用不同的版本编译(再次)
【发布时间】:2020-11-20 05:49:34
【问题描述】:

警告:长读。这个问题引用了许多关于 F2051 的其他问题)

我们的源代码树中有一个名为 PatchLibs 的文件夹,我们在其中放置了第三方源代码的修改文件。
这是在项目搜索路径中:..\Skin;..\PatchLibs

我将文件 dxBar.pas 从 DevExpress 控件复制到 Patchlibs 并在实现部分修改了一些代码

现在,在构建时(删除所有本地 .dcu 文件并进行“清理”),我得到了臭名昭著的:

[dcc32 Fatal Error] F2051 Unit cxBarEditItem was compiled with a different version of dxBar.TdxBarItemControl.GetItem

它不是指一行代码。我在开始编译时收到消息。

配置:

  • 在新 VM 中安装新的 Delphi 和 DevExpress 版本;复制了程序源代码树。

  • C:\DelphiLibs\DevExpress\VCL\Library\RS27 在 32 位库路径中

  • 该文件夹包含所有 DevExpress dcu,特别是 cxBarEditItem.dcudxBar.dcu
    $(DXVCL)\Library\RS27\Win64 库路径也是如此,但这是一个 Win32 应用程序)

  • 在任何地方都没有出现其他cxBarEditItem.dcudcBar.pascxBarEditItem.pasc:\DelphiLibs\DevExpress\VCL\ExpressBars\Sources\
    (我什至扫描了磁盘上的所有 cx*.* 和 dx*.* 文件)。

  • 该源文件夹也存在于浏览路径中 ($(DXVCL)\ExpressBars\Sources)

  • 这些只是单位(没有对应的.dfm 文件)

  • Patchlibs 中还有其他修改过的 DevExpress 文件,我对此没有任何意见; 并且还有一些我遇到了同样的问题(不仅仅是dxBar)。

  • 项目设置为将 .dcu 文件放在其 .pas 源旁边(单元输出目录为空白)

  • 没有 DevExpress 文件是项目的一部分

  • 项目中的其他源文件发生了变化

如果我将cxBarEditItem.pas 的副本提取到 Patchlibs 中,错误只会传播到另一个单元(重复)。

尽管阅读了很多答案(值得注意的 SO 问题:Why are my units "compiled with a different version" of my own files?我只是不明白为什么会出现错误以及这次如何修复它
cxBarEditItem.pas 在其接口 Uses 部分中有 dxBar,而 cxBarEditItem 在我的 Uses 子句中,但是为什么要重新编译呢?

我当然可以开始将 DevExpress 源代码目录添加到搜索路径中,但是其中有很多,这也会导致 .dcu 文件在其中。
我不想这样做,因为它掩盖了实际问题,这在以前的 Delphi/DevExpress 设置中不是必需的

早期 Delphi 10.3 中的 32 位库路径:

c:\DelphiLibs\CompanyName
c:\DelphiLibs\CompanyName\TTLib
c:\DelphiLibs\CompanyName\DataFox
C:\DelphiLibs\RBuilder\Source
$(BDSLIB)\$(Platform)\release
$(BDSUSERDIR)\Imports
$(BDS)\Imports
$(BDSCOMMONDIR)\Dcp
$(BDS)\include
c:\delphilibs\multilizer\localizationcomponentsxex_x86\packages\full\bplxe\20.0
C:\DelphiLibs\Multilizer\LocalizationComponentsXEx_x86
c:\delphilibs\pascal script\dcu\d25\win32
C:\DelphiLibs\Pascal Script\Source
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Dcu\D26\Win32
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\DataSnap
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\ZLib
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\Synapse
$(Everwood)\Bin
C:\DelphiLibs\Scalabium\SMExport\Sources
C:\DelphiLibs\Scalabium\SMImport\Sources
C:\DelphiLibs\Cooltray
C:\DelphiLibs\PlusMemo\
C:\Delphilibs\RBuilder\Lib\Win32
C:\DelphiLibs\PlusMemo
C:\DelphiLibs\IPWorks 2020 Delphi Edition\pas
C:\DelphiLibs\IPWorks Auth 2020 Delphi Edition\pas
C:\DelphiLibs\IPWorks Encrypt 2020 Delphi Edition\pas
C:\DelphiLibs\IPWorks SSH 2020 Delphi Edition\pas
C:\DelphiLibs\IPWorks ZIP 2020 Delphi Edition\pas
C:\DelphiLibs\VirtualUI\dev\Delphi
c:\DelphiLibs\CEF4Delphi-master\source\
$(DXVCL)\Library\RS26

Delphi 10.4 中的 32 位库路径:

c:\DelphiLibs\CompanyName
c:\DelphiLibs\CompanyName\TTLib
c:\DelphiLibs\CompanyName\DataFox
C:\DelphiLibs\RBuilder\Source
c:\program files (x86)\embarcadero\studio\21.0\lib\Win32\release
C:\Users\Jan\Documents\Embarcadero\Studio\21.0\Imports
c:\program files (x86)\embarcadero\studio\21.0\Imports
C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp
c:\program files (x86)\embarcadero\studio\21.0\include
c:\delphilibs\plusmemo
C:\DelphiLibs\RBuilder\Lib\Win32
C:\DelphiLibs\Multilizer\LocalizationComponentsXEx_x86
C:\DelphiLibs\PlusMemo
C:\DelphiLibs\Pascal Script\Source
C:\DelphiLibs\Scalabium\SMExport\Sources
C:\DelphiLibs\Scalabium\SMImport\Sources
C:\DelphiLibs\Cooltray
C:\DelphiLibs\VirtualUI\dev\Delphi
C:\DelphiLibs\nSoftware\IPWorks 2020 Delphi Edition\pas
C:\DelphiLibs\nSoftware\IPWorks Auth 2020 Delphi Edition\pas
C:\DelphiLibs\nSoftware\IPWorks SSH 2020 Delphi Edition\pas
C:\DelphiLibs\nSoftware\IPWorks ZIP 2020 Delphi Edition\pas
C:\DelphiLibs\nSoftware\IPWorks Encrypt 2020 Delphi Edition\pas
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Dcu\D27\Win32
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\DataSnap
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\Grijjy
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\Synapse
C:\DelphiLibs\RemObjects Software\RemObjects SDK for Delphi\Source\ZLib
C:\Program Files (x86)\RemObjects Software\Everwood\Bin
C:\DelphiLibs\SQLDirect\Source
C:\DelphiLibs\CEF4Delphi-master\source
C:\DelphiLibs\DevExpress\VCL\Library\RS27

向上或向下移动最后一个或将其更改为 $(DXVCL)\Library\RS27 没有帮助

这 5 条 Embarcadero 线路看起来很奇怪(请参阅 this SO question, 我将它们替换为旧版本 (and reported to Embarcadero);问题没有变化。


额外的研究/失败的尝试

Ian Boyd 在 2014 年遇到了一个非常相似的问题
F2051: Unit %s was compiled with a different version of %s
建议有 RTTI 设置或编译器选项。
基于那里的David's answer,我决定尝试一下。 我的情况略有不同:我必须尝试找出在构建 DevEx 代码时使用了哪些编译器设置,并将 那些 插入到我修改后的 dxBar.pas 的顶部。

我注意到 DevExpress 安装中的 Packages 子文件夹中有两个 .dproj 文件:cxLibraryRS27.dprojdxBarRS27.dproj(需要 cxLibraryRS27 BTW)
通过将测试项目中的所有编译器选项设置为非默认值并将.dproj 与所有默认值进行比较,我能够理解(大部分)UI 选项设置和.dproj 内容之间的关系。
然后,我将他们的 cxLibraryRS27.dproj 设置与我们项目中的设置进行了比较,发现了以下差异(删除了不相关的行):

他们有这个额外的:

<PropertyGroup Condition="'$(Base)'!=''">
    <DCC_E>false</DCC_E>       No idea what these are...
    <DCC_F>false</DCC_F>
    <DCC_K>false</DCC_K>
    <DCC_N>false</DCC_N>
    <DCC_S>false</DCC_S>
    <DCC_DebugInformation>0</DCC_DebugInformation>
    <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
    <DCC_AssertionsAtRuntime>false</DCC_AssertionsAtRuntime>
    <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>

我们有这个额外的:

<PropertyGroup Condition="'$(Cfg_1)'!=''">
(this is the one with <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>)
    <DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>
    <DCC_RangeChecking>True</DCC_RangeChecking>
    <DCC_SYMBOL_DEPRECATED>False</DCC_SYMBOL_DEPRECATED>
    <DCC_SYMBOL_LIBRARY>False</DCC_SYMBOL_LIBRARY>
    <DCC_SYMBOL_PLATFORM>False</DCC_SYMBOL_PLATFORM>
    <DCC_UNIT_LIBRARY>False</DCC_UNIT_LIBRARY>
    <DCC_UNIT_PLATFORM>False</DCC_UNIT_PLATFORM>
    <DCC_UNIT_DEPRECATED>False</DCC_UNIT_DEPRECATED>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
    <DCC_COMBINING_SIGNED_UNSIGNED>false</DCC_COMBINING_SIGNED_UNSIGNED>
    <DCC_COMPARING_SIGNED_UNSIGNED>false</DCC_COMPARING_SIGNED_UNSIGNED>

<PropertyGroup Condition="'$(Cfg_2)'!=''">
(this is the one with <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>)
    <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
    <DCC_DebugDCUs>true</DCC_DebugDCUs>
    <DCC_WriteableConstants>True</DCC_WriteableConstants>
    <DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>
    <DCC_RangeChecking>True</DCC_RangeChecking>
    <DCC_SymbolReferenceInfo>2</DCC_SymbolReferenceInfo>
    <DCC_StackSize>16384,9437184</DCC_StackSize>
    <DCC_SYMBOL_DEPRECATED>False</DCC_SYMBOL_DEPRECATED>
    <DCC_SYMBOL_LIBRARY>False</DCC_SYMBOL_LIBRARY>
    <DCC_SYMBOL_PLATFORM>False</DCC_SYMBOL_PLATFORM>
    <DCC_UNIT_LIBRARY>False</DCC_UNIT_LIBRARY>
    <DCC_UNIT_PLATFORM>False</DCC_UNIT_PLATFORM>
    <DCC_UNIT_DEPRECATED>False</DCC_UNIT_DEPRECATED>
    <DCC_COMPARING_SIGNED_UNSIGNED>False</DCC_COMPARING_SIGNED_UNSIGNED>
    <DCC_COMBINING_SIGNED_UNSIGNED>False</DCC_COMBINING_SIGNED_UNSIGNED>

他们没有这个 PropertyGroup

<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
    <VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
    <DCC_DebugInfoInExe>false</DCC_DebugInfoInExe>
    <ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
    <BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
    <BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>
    <BT_BuildType>Debug</BT_BuildType>
    <DCC_ImportedDataReferences>false</DCC_ImportedDataReferences>
    <DCC_DebugDCUs>false</DCC_DebugDCUs>
</PropertyGroup>

通过这些,我认为这些设置是不同的,可能会影响生成的.dcu 文件:

  • 范围检查 {$R-}

  • 溢出检查 {$Q-}

  • 本地调试符号关闭 {$D-}

  • 运行时断言关闭 {$C-}

  • 符号参考信息关闭 {$L-}

  • 可写常量关闭 {$J-}

  • exe 中的调试信息关闭 {$Y-}

所以我把这个放在dxBar.pas的顶部:

{$C-,D-,J-,L-,Q-,R-,Y-}

不,没有成功...

【问题讨论】:

  • 通常这归结为编译选项,或接口部分的更改。如您所知。

标签: delphi delphi-units delphi-10.4-sydney


【解决方案1】:

我不相信它与编译器选项有关。我猜可能缺少cxBarEditItem.pas 文件。或者在您的链接路径中某处有一个旧的cxBarEditItem.dcu。所以编译器很困惑。

尝试清理组件源,只有.pas文件,没有.dcu,然后尝试重新编译。

如果还不够,那么可能是组件.inc文件的问题,以及不兼容的选项。不要试图修改第三方组件源代码,你很可能会破坏一些东西。

【讨论】:

    【解决方案2】:

    我没有完整阅读,但是当我看到编译错误时立即检查了 DevExpress 源代码。

    这与TdxBarItemControl.GetItem被标记为inline这一事实非常相关。当涉及inline 或泛型(它们的行为相似)时,通常要求如果您更改此类单元,则任何其他使用此单元的单元也必须重新编译。

    基于经验的建议(我们也使用 DevExpress 进行自定义修改):

    将它们放入版本控制(还有二进制文件!git lfs ftw),当您更改任何源时,只需重新编译并提交任何更改。将此存储库与您自己的源存储库分开,但将其标记/分支与您的源存储库相同。然后在版本之间进行更改也将是一件很容易的事。

    【讨论】:

    • 哎哟。好的,我会检查一下我必须将其他 DevEx 源文件复制到 PatchLibs 文件夹中。
    • 我不确定我是否完全理解你 - 我确实没有更改 cxBarEditItem...
    • 是的,您更改了 dxBar.pas,它具有其他未触及单元使用的内联 getter。那是罪魁祸首。 dcu 匹配基于编译器生成的一些哈希值,并且内联方法会发生变化,即使 iirc 只修改了其他内容。
    猜你喜欢
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 2016-05-14
    相关资源
    最近更新 更多