簡體   English   中英

F2051 單元用不同的版本編譯(再次)

[英]F2051 Unit was compiled with a different version (again)

警告:長讀。這個問題引用了關於 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.dcu出現; dcBar.pascxBarEditItem.pas位於c:\DelphiLibs\DevExpress\VCL\ExpressBars\Sources\
    (我什至掃描了磁盤上的所有 cx*.* 和 dx*.* 文件)。

  • 該源文件夾也存在於瀏覽路徑中( $(DXVCL)\ExpressBars\Sources

  • 這些只是單位(沒有相應.dfm文件)

  • Patchlibs 中還有其他修改過的 DevExpress 文件,我對此沒有任何問題; 還有一些我有同樣的問題(不僅僅是dxBar )。

  • 項目設置為將.dcu文件放在其.pas源旁邊(單元 Output 目錄為空白)

  • 沒有 DevExpress 文件是項目的一部分

  • 項目中的其他源文件已更改

如果我將cxBarEditItem.pas的副本拉入 Patchlibs,則錯誤只會傳播到另一個單元(重復)。

盡管已經閱讀了很多答案(值得注意的 SO 問題: 為什么我的單位是“用不同版本編譯的”我自己的文件?我只是不明白為什么會發生錯誤以及這次如何修復它
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 線看起來很奇怪(請參閱這個 SO question ,我用舊的對應物替換了它們(並向 Embarcadero 報告);問題沒有變化。


額外的研究/失敗的嘗試

伊恩博伊德在 2014 年遇到了一個非常相似的問題
F2051: 單元 %s 是用不同版本的 %s 編譯的
建議有 RTTI 設置或編譯器選項。
根據大衛在那里的回答,我決定試一試。 我的情況略有不同:我必須嘗試找出在構建 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-}

不,沒有成功...

我沒有完整閱讀,但是當我看到編譯錯誤時立即檢查了 DevExpress 源代碼。

這與TdxBarItemControl.GetItem被標記為inline的事實非常相關。 當涉及inline或 generics(它們的行為相似)時,通常需要如果您更改這樣的單元,則還必須重新編譯使用該單元的任何其他單元。

基於經驗的建議(我們也使用帶有自定義修改的 DevExpress):

將它們放入版本控制(也是二進制文件。git lfs ftw),當您更改任何源時,只需重新編譯並提交任何更改。 將此存儲庫與您自己的源存儲庫分開,但將其標記/分支與您的源存儲庫相同。 然后在版本之間進行更改也將是不費吹灰之力。

我不相信它與編譯器選項有關。 我猜可能缺少cxBarEditItem.pas文件。 或者在您的鏈接路徑中某處有一個舊的cxBarEditItem.dcu 所以編譯器很困惑。

嘗試清理組件源,只有.pas文件而沒有.dcu ,然后再次嘗試重新編譯。

如果還不夠,那么這可能是組件.inc文件的問題,以及不兼容的選項。 不要試圖修改第三方組件源代碼,你很可能會破壞一些東西。

我只是遇到了同樣的問題,搜索了它,找到了這個,對我來說答案是這樣的:我忘記將一個單元的.pas文件添加到.dpr但仍然有一個來自另一個構建的.dcu

我不得不將文件添加到.dpr並且一切都再次正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM