F2051 Устройство было скомпилировано с другой версией (снова)

(Предупреждение: долгое чтение. Этот вопрос ссылается на многие другие вопросы о 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

Это не относится к строке кода. Я получаю сообщение, когда начинается компиляция.

Конфигурация:

  • Новые версии Delphi и DevExpress, установленные в новой виртуальной машине; скопировал исходное дерево программы.

  • C:\DelphiLibs\DevExpress\VCL\Library\RS27 находится в 32-битном библиотечном пути

  • Эта папка содержит все контроллеры DevExpress, в частности 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: почему мои модули "скомпилированы с другой версией" моих собственных файлов?),Я просто не понимаю, почему возникает ошибка и как ее исправить на этот раз.
cxBarEditItem.pas имеет dxBar в его интерфейсе используется раздел и cxBarEditItem есть в моих предложениях Uses, но зачем его перекомпилировать?

Я, конечно, могу начать добавлять каталоги исходного кода DevExpress в путь поиска, но их много, и это приведет к .dcuфайлы в них.
Я предпочитаю не делать этого, потому что это маскирует реальную проблему, а в предыдущей настройке Delphi/DevExpress в этом не было необходимости:

32-битный путь к библиотеке в более ранней версии 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-битный путь к библиотеке в 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

Перемещение последнего вверх или вниз или изменение на $(DXVCL)\Library\RS27 не помогло

Эти 5 строк Embarcadero выглядят странно (см. Этот вопрос SO, я заменил их их старыми аналогами ( и сообщил в Embarcadero); никаких изменений в проблеме.


Дополнительное исследование / неудачная попытка

У Иэна Бойда была очень похожая проблема в 2014 году в
F2051: модуль%s был скомпилирован с другой версией%s.
Предположения, что были настройки RTTI или параметры компилятора.
Основываясь на ответе Дэвида там, я решил попробовать. Моя ситуация была немного другой: мне пришлось попытаться выяснить, какие настройки компилятора использовались при сборке кода DevEx, и вставить их в верхнюю часть моего измененногоdxBar.pas.

Я заметил, что есть два .dproj файлы в Packages вложенные папки в установке DevExpress: cxLibraryRS27.dproj а также dxBarRS27.dproj (требуя cxLibraryRS27BTW)
Установив все параметры компилятора в тестовом проекте на значения, отличные от значений по умолчанию, и сравнив это.dproj к одному со всеми значениями по умолчанию, я смог понять (большую часть) связь между настройками параметров пользовательского интерфейса и .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-}

Нет, безуспешно...

3 ответа

Я не читал полностью, но сразу же проверил исходники DevExpress, когда увидел ошибку компиляции.

Это во многом связано с тем, что TdxBarItemControl.GetItem отмечен как inline. когдаinline или дженерики (они ведут себя аналогично) часто требуется, чтобы при изменении такого модуля также перекомпилировался любой другой модуль, использующий этот модуль.

Предложение основано на опыте (мы также используем DevExpress с индивидуальными модификациями):

Поместите их в систему контроля версий (также двоичные файлы! Git lfs ftw), и когда вы измените любой из источников, просто перекомпилируйте и зафиксируйте любые изменения. Храните этот репозиторий отдельно от вашего собственного исходного репозитория, но пометьте его / ветвь идентичным вашему исходному репозиторию. Переходить между версиями тогда тоже не составит труда.

Я не уверен, что дело в параметрах компилятора. Я думаю, может быть пропущенныйcxBarEditItem.pasфайл. Или есть старыйcxBarEditItem.dcuгде-нибудь на вашем пути ссылки. Так что компилятор запутался.

Попытайтесь очистить источники компонентов, чтобы было только .pas файлы и нет .dcu, и попробуйте перекомпилировать снова.

Если его мало, то возможно это проблема с компонентами .incфайлы и несовместимые параметры. Не пытайтесь изменять исходный код сторонних компонентов, вы, скорее всего, что-то сломаете.

У меня просто была такая же проблема, искал ее, нашел это, и для меня ответ был таким: я забыл добавить.pasфайл для устройства, но все еще имел.dcuибо он завалялся от другого билда.

Пришлось добавить файл в.dprи все снова заработало.

Другие вопросы по тегам