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

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

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

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

введите описание изображения здесь

Попутно мы узнали, что нам нужно ограничить наши исправления 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): F2051 Модуль Vcl.Forms был скомпилирован с другой версией Vcl.Themes.TMouseTrackControlStyleHook

Почему

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

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

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

Есть и другие, неявные вопросы, которые связаны с попыткой ответить на почему:

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

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

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

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

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

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


person Ian Boyd    schedule 28.08.2014    source источник
comment
Извини, Ян, но тебе не повезло. Вам понадобится объезд. Я пытался убедить Марко, что это сломано, но он мне не верил. blog.marcocantu.com/blog/ Марко должен быть парнем по связям с разработчиками, так что боже помоги нам, когда он нас не слушает   -  person David Heffernan    schedule 28.08.2014
comment
Часто настройки компилятора имеют значение. Возможно дело в настройках RTTI. Похоже, Уоррен подумал, что это может быть зацепкой.   -  person David Heffernan    schedule 28.08.2014
comment
@DavidHeffernan Оказалось, что это был случай. Подожду несколько дней и добавлю ответ на вопрос.   -  person Ian Boyd    schedule 29.08.2014
comment
@ Ян Ты можешь расшириться? Есть ли у вас какие-нибудь настройки RTTI, которые исправляют все эти проблемы? Думаю, было бы хорошо добавить ответ на вопрос Уоррена. Жалко, что он ответил на отказ RRUZ, который проигнорировал реальную проблему. Или я был бы очень рад снова открыть этот вопрос и закрыть другие, если у вас есть ответ. Дай мне знать.   -  person David Heffernan    schedule 29.08.2014
comment
Я тоже очень хочу разобраться в этом, потому что без решения я не заинтересован в обновлении.   -  person David Heffernan    schedule 29.08.2014
comment
@DavidHeffernan, некоторая генерация кода в XE6 некорректна, см. Регрессия, недопустимая генерация кода, когда ссылки на константы, определенные в классах или записях. Устранено, но обновления или исправления недоступны. XE6 не будет использоваться нами для производства.   -  person LU RD    schedule 29.08.2014
comment
@LURD XE7 неизбежен. Без сомнения, с кучей исправлений и кучей новых ошибок. Эмба QA / QC убогая.   -  person David Heffernan    schedule 29.08.2014
comment
@DavidHeffernan Это было ваше собственное решение, о котором вы упоминали где-то. Ctrl+O+O, чтобы вставить стандартные параметры компилятора в верхнюю часть заменяемого файла pas. Вот почему я собирался ответить на него здесь: так что у него есть ответ, а не случайные спотыкания в другом месте :)   -  person Ian Boyd    schedule 29.08.2014
comment
Тогда позволь мне снова открыть. Готово. К тебе.   -  person David Heffernan    schedule 29.08.2014
comment
@DavidHeffernan Вы знаете, через что я прошел, чтобы получить XE6. Мы уже три недели находимся в режиме исправления ошибок. Какая была последняя хорошая версия Delphi? Также: я не могу ответить на свой вопрос в течение двух дней; обратно к вам!   -  person Ian Boyd    schedule 29.08.2014
comment
Хорошо, я добавил текст из другого ответа. Теперь не стесняйтесь редактировать его как хотите!   -  person David Heffernan    schedule 29.08.2014
comment
@IanBoyd XE2 возможно? Мы используем его уже пару лет и ни разу не столкнулись с какими-либо серьезными ошибками.   -  person Jerry Dodge    schedule 29.08.2014
comment
@Jerry Если вы не используете компилятор x64. Что неправильно реализует обработку исключений. Первая x64-версия нашего продукта была построена с использованием XE2, и мне пришлось самостоятельно исправить обработку исключений, что было непросто!   -  person David Heffernan    schedule 29.08.2014
comment
Возможный дубликат: stackoverflow.com/questions/429275/   -  person Z80    schedule 19.10.2015
comment
Вот как я это решил: stackoverflow.com/questions/429275/   -  person Z80    schedule 19.10.2015


Ответы (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+}

достаточно.

person David Heffernan    schedule 28.08.2014