Добавление модуля в проект - удаление директивы компилятора из источника проекта.
Должно ли это работать так или я делаю что-то не так?
У меня есть этот код в исходном коде моего проекта:
{$IFDEF DEBUG}
ADebugUnit,
{$ELSE}
ARelaseUnit,
{$ENDIF}
Я хочу, чтобы ADebugUnit использовался в режиме отладки, а AReleaseUnit - при компиляции в режиме выпуска. Это прекрасно работает, за исключением того, что я хочу добавить новый проект в проект. Когда я делаю это, он в основном обрабатывает код и сохраняет только тот модуль, который имеет отношение к любой конфигурации, в которой в данный момент настроен проект.
Например, если для конфигурации задано Debug, то после добавления нового модуля в мой проект приведенный выше код изменяется на просто:
ADebugUnit,
Или, если моя конфигурация настроена на выпуск, она изменится на следующее после добавления нового модуля:
ARelaseUnit,
Я должен всегда восстанавливать его обратно в условные операторы после добавления нового модуля. Есть ли способ сделать это без вмешательства нового устройства?
3 ответа
IDE принадлежит большая часть файла DPR. Будьте осторожны с тем, что вы делаете с ним, или вы рискуете именно тем, что вы наблюдали (или хуже - в зависимости от характера изменений, IDE может иногда решить вообще не разрешать компиляцию файла!).
Помимо прочего, это означает, что вы не можете условно включать единицы в файл DPR. Вам нужно будет найти другое решение для любой проблемы, которую вы пытались решить.
Например, возможно, вы могли бы использовать устройство из какого-то другого места в вашем проекте вместо файла DPR.
Или, может быть, вы могли бы объединить эти два блока в один, а затем скомпилировать их содержимое условно.
Или, может быть, вы можете просто использовать код отладки все время, так как это увеличивает вероятность того, что вы отправите тот же код, который вы тестировали.
Или, если эта проблема возникает только при использовании диалогового окна "Добавить устройство", вы можете просто отказаться от этого диалога и отредактировать файл DPR вручную. Никакого другого волшебства за добавлением модуля в проект нет, за исключением того, что, как вы заметили, предложение использования переписывается.
Проблема в том, что DPR не будет учитывать $ifdef в списке использований и фактически удалит их (как вы уже нашли), когда перезаписывает список использований в ответ на определенные операции IDE.
Один из вариантов - никогда не использовать эти операции IDE, такие как "Добавить / удалить модуль" и т. Д., И только когда-либо управлять списком использований DPR вручную.
В качестве альтернативы, проявив некоторую осторожность, вы можете использовать псевдонимы для достижения желаемого.
Рассмотрим два модуля, на которых вы хотите использовать один или другой, в зависимости от конфигурации сборки (отладка или выпуск):
- DebugUnit.pas
- ReleaseUnit.pas
В опциях вашего проекта добавьте псевдоним модуля для:
Конфигурацияотладки:
UnitToUse=DebugUnit
ВЫПУСТИТЕ конфигурацию:
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;
Чтобы опираться на ответ Роба, всякий раз, когда у меня возникают ситуации, когда мне нужно сделать что-то подобное, я переношу весь код 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% записал это прямо в Stackru, так что извините, если я что-то натворил в этом коде.