Добавить модуль в проект удаляет директиву компилятора из исходного кода проекта.

Так должно работать или я что-то не так делаю?

У меня есть этот код в моем исходном коде проекта:

  {$IFDEF DEBUG}
  ADebugUnit,
  {$ELSE}
  ARelaseUnit,
  {$ENDIF}

Я хочу, чтобы ADebugUnit использовался в режиме отладки, а AReleaseUnit — при компиляции в режиме выпуска. Это прекрасно работает, ЗА ИСКЛЮЧЕНИЕМ, когда я выбираю добавить новый блок в проект. Когда я это сделаю, он в основном обработает код и сохранит только тот модуль, который относится к той конфигурации, на которую в данный момент установлен проект.

Например, если для конфигурации установлено значение «Отладка», то после добавления нового модуля в мой проект приведенный выше код изменится просто на:

ADebugUnit,

Или, если для моей конфигурации установлено значение Release, после добавления нового устройства оно изменится на следующее:

ARelaseUnit,

Я должен всегда восстанавливать его обратно в условные операторы после добавления нового модуля. Есть ли способ сделать это без вмешательства добавления нового устройства?


person Ann Gossard    schedule 16.10.2013    source источник
comment
Я пишу свой собственный файл .dpr и отменяю изменения, сделанные IDE. ВКС помогает. Некоторые вещи должны быть условными в файле .dpr.   -  person David Heffernan    schedule 16.10.2013
comment
К сожалению, среда IDE тоже не всегда справляется со своей задачей и часто уничтожает весь файл проекта. Я даже видел, как он копировал предложение uses дальше вниз, поэтому оно было продублировано.   -  person Jerry Dodge    schedule 17.10.2013
comment
Я хочу заявить, что у нас есть копия Delphi XE5, которую мы оцениваем, и мы попробовали ее в этой среде, и она работает так, как ожидалось, поскольку я могу включить условное включение в исходный код проекта и использовать опцию добавления единицы. в среде IDE, и он НЕ удалит директивы условного компилятора. Я ожидал, что это будет работать в Delphi XE2, но это не так.   -  person Ann Gossard    schedule 18.10.2013
comment
да. Delphi IDE действительно портит вещи, когда речь идет о DRP/DPK.   -  person Z80    schedule 16.10.2015


Ответы (3)


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

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

Например, возможно, вы могли бы использовать модуль из другого места в вашем проекте вместо файла DPR.

Или, может быть, вы могли бы объединить два модуля в один, а затем вместо этого условно скомпилировать его содержимое.

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

Или, если эта проблема возникает только при использовании диалогового окна «Добавить устройство», вы можете просто отказаться от этого диалогового окна и отредактировать файл DPR вручную. В добавлении модуля к проекту нет никакой другой магии, за исключением того, что предложение uses переписывается, как вы заметили.

person Rob Kennedy    schedule 16.10.2013
comment
Согласитесь, и это PITA. Есть несколько вещей, которые либо не работают в файле *.DPR, либо IDE иногда выбрасывает их. Это одна из них. Единственный лучший совет - поместить как можно больше в другой блок. - person JensG; 16.10.2013
comment
@Rob - Мы можем вручную добавлять единицы по мере необходимости, и именно так мы обходим это (или исправляем постфактум). Хотя мы рассматриваем возможность полного устранения условного оператора, что было бы идеальным решением. - person Ann Gossard; 17.10.2013

Проблема в том, что DPR не будет учитывать никакие $ifdef в списке использования и фактически удалит их (как вы обнаружили), когда перепишет список использования в ответ на определенные IDE. операции.

Один из вариантов — никогда не использовать такие операции IDE, как «Добавить/удалить устройство» и т. д., и управлять списком использования DPR только вручную.

В качестве альтернативы, с некоторой осторожностью, вы можете использовать псевдонимы единиц для достижения того, что вы хотите.

Рассмотрим два модуля, которые вы хотите использовать в зависимости от конфигурации сборки (отладка или выпуск):

  • DebugUnit.pas
  • ReleaseUnit.pas

В параметрах проекта добавьте Псевдоним объекта для:

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

  UnitToUse=DebugUnit

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

  UnitToUse=ReleaseUnit

В вашем DPR добавьте запись в список использования:

  uses
    UnitToUse,

Эта запись в DPR не может идентифицировать имя файла с использованием синтаксиса «in» и вместо этого должна полагаться на фактические требуемые единицы измерения, находящиеся в пути поиска проекта.

Везде, где вы обычно используете DebugUnit или ReleaseUnit, используйте UnitToUse. Очевидно, имя для псевдонима полностью зависит от вас.

Если два модуля имеют одинаковые интерфейсные «контракты», ваши сборки будут переключаться между этими двумя модулями, просто изменяя целевую конфигурацию.

Если у них разные интерфейсные контракты, вы все равно можете использовать директивы $ifdef в коде приложения для работы с содержимым модуля, на который ссылается UnitToUse. , в зависимости от ситуации, например

uses
  UnitToUse;


procedure DoSomethingInvolvingAliasedUnit;
begin
  {$ifdef DEBUG}
    // code which relies on the debug unit
  {$else}
    // code which relies on the release unit
  {$endif}
end;
person Deltics    schedule 17.10.2013

Чтобы опираться на ответ Роба, всякий раз, когда у меня возникают ситуации, когда мне нужно сделать что-то подобное, я переношу весь код DPR в другой модуль, например AppInit.pas.

unit AppInit;

interface

uses
  Vcl.Forms,
  Unit1,
{$IFDEF DEBUG}
  ADebugUnit
{$ELSE}
  AReleaseUnit
{$ENDIF}
  ;

procedure RunApp;

implementation

procedure RunApp;
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'Sample Application';
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end;

end.

Тогда ваш модуль проекта будет иметь только

program SampleApp;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  AppInit in 'AppInit.pas';

{$R *.res}

begin
  RunApp;
end.

Недостатком этого является то, что IDE будет путаться в том, что это за тип приложения, и когда вы перейдете к Project > Options, некоторые функции будут отключены, например, стили VCL. Однако при правильном кодировании такие вещи все же можно реализовать.

PS - Прошу прощения за то, что я написал это на 100% непосредственно в StackOverflow, так что извините, если я что-то напутал в этом коде.

person Jerry Dodge    schedule 17.10.2013