Reputation: 9096
(Warning: long read. This question references a lof of the other questions about F2051)
We have a folder named PatchLibs in our source tree in which we put modified files of third party sources.
This is in the project search path: ..\Skin;..\PatchLibs
I copied the file dxBar.pas from DevExpress controls into Patchlibs and modified some code in the implementation section only.
Now, when building (with all local .dcu
files deleted and a 'Cleanup') I get the infamous:
[dcc32 Fatal Error] F2051 Unit cxBarEditItem was compiled with a different version of dxBar.TdxBarItemControl.GetItem
It doesn't refer to a line of code. I get the message when it starts compiling.
Configuration:
New Delphi and DevExpress versions installed in a new VM; copied the program source tree.
C:\DelphiLibs\DevExpress\VCL\Library\RS27
is in the 32bit library path
That folder contains all the DevExpress dcu's, notably cxBarEditItem.dcu
and dxBar.dcu
(So does the $(DXVCL)\Library\RS27\Win64
library path, but this is a Win32 app)
There are no other occurrences of cxBarEditItem.dcu
anywhere; dcBar.pas
and cxBarEditItem.pas
are in c:\DelphiLibs\DevExpress\VCL\ExpressBars\Sources\
(I even scanned the disk for all cx*.* and dx*.* files).
That source folder is also present in the Browsing path ($(DXVCL)\ExpressBars\Sources
)
These are just units (no corresponding .dfm
files)
There are other modified DevExpress files in Patchlibs that I have no issues with; and there are some more with which I have the same issue (not just dxBar
).
Project is set up to place .dcu
files next to their .pas
sources (Unit Output Directory is blank)
No DevExpress files are part of the project
Other source files in the project have changed
If I pull a copy of cxBarEditItem.pas
into Patchlibs, the error only just propagates to another unit (repeatedly).
Despite having read many answers (Notable SO question: Why are my units "compiled with a different version" of my own files?)
I simply do not understand why the error occurs and how to fix it this time.
cxBarEditItem.pas
has dxBar
in its interface Uses section, and cxBarEditItem
is in my Uses clauses, but why would it want to recompile?
I can of course start adding the DevExpress source code directories into the Search Path, but there are a lot of those and this will result in .dcu
files in them as well.
I prefer not to do that because it masks the actual problem and this was not necessary in the previous Delphi/DevExpress setup:
32 bits library path in earlier Delphi 10.3:
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
32 bits library path in Delphi 10.4:
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
Moving that last one up or down or changing it to $(DXVCL)\Library\RS27
did not help
Those 5 Embarcadero lines look weird (see this SO question, I replaced them with their old counterparts (and reported to Embarcadero); no change in the issue.
Additional research/failed attempt
Ian Boyd had a very a similar problem way down in 2014
F2051: Unit %s was compiled with a different version of %s
Suggestions there were RTTI settings or compiler options.
Based on David's answer there, I decided to give that a try.
My situation was slightly different: I had to try to find out what compiler settings were used when building the DevEx code and insert those into the top of my modified dxBar.pas
.
I noticed that there are two .dproj
files in Packages
subfolders in the DevExpress installation: cxLibraryRS27.dproj
and dxBarRS27.dproj
(requiring cxLibraryRS27
BTW)
By setting all compiler options in a test project to non-defaults and comparing that .dproj
to one with all the defaults I was able to understand (most of) the relation between UI option settings and the .dproj
contents.
I then compared their cxLibraryRS27.dproj
settings against those from our project and found the following differences (irrelevant lines removed):
They had this extra:
<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>
We had this extra:
<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>
and
<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>
and they did not have this 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>
Going through these I think these are the settings they have differently and that may influence the generated .dcu
files:
Range checking off {$R-}
Overflow checking off {$Q-}
Local debugs symbols off {$D-}
Runtime assertions off {$C-}
Symbol reference info off {$L-}
Writeable constants off {$J-}
Debug info in exe off {$Y-}
So I put this at the top of dxBar.pas
:
{$C-,D-,J-,L-,Q-,R-,Y-}
Nope, no success...
Upvotes: 2
Views: 2765
Reputation: 5582
I just had the same problem, searched it, found this and for me the answer was this: I forgot to add a .pas
file for a unit to the .dpr
but still had a .dcu
for it lying around from another build.
I had to add the file to the .dpr
and everything worked again.
Upvotes: 0
Reputation: 21713
I did not read entirely but immediately checked the DevExpress sources when I saw the compile error.
This is very much related to the fact that TdxBarItemControl.GetItem
is marked as inline
. When inline
or generics (they behave similar) are involved it often is required that if you change such a unit also any other unit using this one has to be recompiled as well.
Suggestion based on experience (we also use DevExpress with custom modifications):
Put them into version control (also the binaries! git lfs ftw) and when you change any of the source just recompile and commit any changes. Keep this repository seperate from your own source repository but tag/branch it identical to your source repository. Changing between versions then also will be a no brainer.
Upvotes: 4
Reputation: 43023
I am not convinced it is about compiler options. I guess there may be a missing cxBarEditItem.pas
file. Or there is an old cxBarEditItem.dcu
somewhere in your linking path. So the compiler is confused.
Try to clean up the component sources, to have only .pas
files and no .dcu
, and try to recompile again.
If it is not enough, then maybe this is a problem with the components .inc
files, and incompatible options. Don't try to modify the third-party component source code, you will most probably break something.
Upvotes: 0