Условие условной компиляции Delphi в разделе uses

Я пытаюсь изменить свой код Delphi 2010 для компиляции в XE7 (и хочу сохранить возможность его компиляции в 2010 году). Итак, в блоке, где находится моя основная форма, я добавил условные директивы. Следующее работает отлично в 2010 году

uses 
  {$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,  Dialogs;

Но XE7 автоматически добавляет System.Actions в конец для создания предложения uses, которое теперь объявляется System.Actions дважды (см. ниже) и дает сообщение об ошибке [dcc32 Error] MyForm.pas(10): E2004 Identifier redeclared: 'System.Actions'. Почему XE7 не принимает устройство из условной директивы?

uses 
  {$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,  Dialogs,
  System.Actions; // <- automatically added

Ответ 1

Как говорит Кен, предложение использования интерфейса будет изменено IDE, а процессы, с помощью которых это достигается, несколько менее сложны (как вы обнаружили). Эта же проблема влияет на предложение использования проекта. К сожалению, этого гораздо труднее избежать в случае использования предложений Form/DataModule.

Вы можете использовать псевдоним модуля (см. ответ Дэвида Хеффернана), но имейте в виду, что если вы создадите псевдоним для единицы, которую IDE хочет добавить, тогда среда IDE все равно добавит ссылку на требуемую единицу, поскольку она не распознает псевдоним как идентифицирующий требуемую единицу. Слияние с модулем Система позволит избежать этого, поскольку он уже (неявно) используется каждым модулем.

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

В этом случае в проекте Delphi 2010 создайте пустой элемент Действия:

 unit Actions;
 interface
 implementation
 end.

Конечно, вам необходимо убедиться, что этот блок не в пути к проекту для вашей версии XE7 проекта.

Одним из способов достижения этого является обеспечение того, чтобы пустой элемент Actions.pas не был явно указан в списке использования DPR, но помещен в подпапку вашего источника проекта (например,). Затем вы можете добавить эту подпапку в путь поиска проекта для версии Delphi 2010, но не версию XE7:

 \Project Folder

     project2010.dpr
     project2010.dproj
     projectXE7.dpr
     projectXE7.dproj

     \placeholders
          Actions.pas

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

     \placeholders
          \2010
               Actions.pas
          \XE7
               D2010UnitNotPresentInXE7.pas

Такая структура может быть рекомендована просто с точки зрения создания организации автодокументации.

Обратите внимание, что это необходимо только для ссылок на ссылки в разделе использует раздел интерфейса Формы (или Рамки и т.д.). В невидимых единицах или в разделе реализации среда IDE не мешает, поэтому директивы условной компиляции не должны содержать никаких проблем.

Ответ 2

Самый простой способ исправить это - добавить псевдоним устройства в проект Delphi 2010. Вам нужно будет использовать разные файлы .dproj для разных версий Delphi, но вам все равно нужно это делать.

В настройках псевдонимов блока для проекта Delphi 2010 добавьте следующее:

Actions=System

Я использую System в качестве цели псевдонима, потому что блок System автоматически включается в каждый блок Delphi, и поэтому псевдонимы включены доброкачественными. Это самый простой способ, с помощью которого компилятор может игнорировать запись в предложении uses.

Затем вы можете объявить свое предложение uses следующим образом:

uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  Actions, Actnlist;

Это будет прекрасно компилироваться в Delphi 2010, потому что обработка псевдонимов будет отображать Actions на System. В XE7 вы также прекрасны, потому что нет псевдонима, и IDE удовлетворяет наличием блока Actions и поэтому не чувствует принуждения изменять предложение uses.

Ответ 3

Будет ли что-то неправильно с

{$IF CompilerVersion < 24}Actnlist,{$IFEND}

или это академический аргумент?

Добавление...

Затем добавьте фиктивный System.Actions.dcu, содержащий ничего в ваш компиляционный путь 2010.

Я бы предположил, что IDE будет настаивать на вставке uses ... System.Actions, 2010 имеет то, что он хочет, XE7 имеет то, что он хочет.

Но у меня нет XE7, поэтому я не могу проверить его.

Ответ 4

у нас была та же проблема... Самый простой способ - сделать это следующим образом:

{$IF CompilerVersion < 24}{$ELSE}System.Actions,{$IFEND}
{$IF CompilerVersion >= 24}{$ELSE}Actnlist,{$IFEND}

Если вы открываете файл в старой среде IDE, вы можете увидеть ошибку, в которой говорится, что "единица X" не найдена, но она будет компилироваться нормально, и автоматическое добавление не выполняется. Это выглядит не очень хорошо, но это работает неплохо...

С уважением,

Бернд