【发布时间】: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.dcu和dxBar.dcu
($(DXVCL)\Library\RS27\Win64库路径也是如此,但这是一个 Win32 应用程序) -
在任何地方都没有出现其他
cxBarEditItem.dcu;dcBar.pas和cxBarEditItem.pas在c:\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.dproj 和 dxBarRS27.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