Подтвердить что ты не робот

F2051: Единица% s была скомпилирована с другой версией% s

Мы исправляли ошибки в VCL в Delphi XE6. Пока папка содержит:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas

И мы добавляем папку в путь поиска нашей библиотеки:

enter image description here

Попутно мы узнали, что мы должны ограничить наши исправления только разделом implementation. В противном случае хеш-подписи символов в разделе interface изменятся. Это заставляет компоновщика понять, что символы внутри DCU не являются той версией, которую они ожидают.

У Барри Келли было хорошее объяснение этому поведению:

Важной концепцией является версия символа. При сохранении DCU Delphi вычисляет хэш на основе объявления интерфейса символа и связывает его с символом. Другие юниты, которые используют символ, также хранят версию символа. Таким образом, избегаются конфликты времени соединения, вызванные устаревшими символами, в отличие от большинства C-линкеров.

Результатом этого является то, что вы должны иметь возможность добавлять Classes.pas в ваш проект и изменять его раздел реализации почти в соответствии с вашим содержанием, и при этом иметь возможность статически связываться с остальными библиотеками RTL и VCL и сторонними библиотеками, даже те, которые предоставляются только в объектном формате.

Вещи, чтобы быть осторожным:

  • Встроенные процедуры; тело встроенных подпрограмм является частью версии символа
  • Дженерики; сторона реализации универсальных типов и методов является частью соответствующих версий символов

Поэтому мы постарались ограничить исправления ошибками в разделе реализации (например, ввести новые классы взломщика, а не переопределять метод в общедоступном классе).

А потом

Тогда я пошел, чтобы исправить в Vcl.Themes.pas. Я начинаю с простого, копируя файл и помещая его в папку исправлений:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
|----- Vcl.Themes.pas

Несмотря на то, что я (пока) даже не модифицировал Vcl.Themes.pas, компилятор его подавляет:

[dcc32 Fatal Error] Vcl.Themes.pas(2074): V20.Forms модуля F2051 был скомпилирован с другой версией Vcl.Themes.TMouseTrackControlStyleHook

Зачем

Важный вопрос:

Почему это происходит?

Что происходит, что компилятор не может понять, что точно такой же файл - точно такой же файл? Возможно ли, что источник VCL, поставляемый с XE6, неверен и не соответствует тому, что поставляется в DCU? Это как-то связано с порядком поиска в библиотеке? Это как-то связано с встраиванием, обобщениями, итераторами, платформами, отладкой dcus, 64-битным компилятором, ifdefs, дополнением кода, синергией, за пределами коробки?

Есть и другие, неявные вопросы, которые сопровождают попытки ответить на вопрос:

Почему это работает для двух других файлов, но не этот?
Почему происходит сбой, когда я даже не изменил файл?

Что вы пробовали?

  • попытался переместить VCL Source Fixes выше и ниже в пути поиска
  • попытался включить использование отладки dcus
  • попытался перейти на 64-битную платформу
  • попытался удалить все файлы dcu в папке моего проекта (хотя не dcu D:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu который поставляется с Delphi XE6)
  • закрытие XE6 и повторный запуск
  • собираюсь в Венди на обед

Конечно, я хочу это исправить. Но больше, чем желание исправить это, я хочу понять, почему это не удается. Компилятор не использует магию, вуду или Q-подобные способности. Это детерминированная машина, работающая в соответствии с фиксированным набором (недокументированных) правил.

Почему это происходит?

Смотрите также

4b9b3361

Ответ 1

Вам нужны параметры компилятора, чтобы они соответствовали тем, которые использовались, когда блок был скомпилирован Embarcadero. Причина, по которой ваша секция реализации изменяется только сбой, кажется, что она должна быть успешной.

Запустите проект по умолчанию и используйте CTRL + O + O, чтобы сгенерировать эти параметры. Я получаю

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

когда я делаю это в XE6.

Поместите это в верхнюю часть своей копии устройства, и вам должно быть хорошо идти. Вероятно, вы можете уйти с подсетой сокращения, в зависимости от ваших вариантов проекта хоста. В моем коде я обнаружил, что:

{$R-,T-,H+,X+}

достаточно.