Пользовательская цель сборки Delphi XE всегда отключена

177

Я создал собственный .targetsфайл MSBuild, который я включил в проект Delphi XE через IDE, и включил его из контекстного меню диспетчера проектов. Хотя файл проверяется, он всегда отключается после повторного сохранения файла проекта.

Вот упрощенная версия файла целей с именем Custom.targets.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Hello">
    <Message Text="Hello from custom target"/>
  </Target>
</Project>

В качестве отдельного файла это работает как ожидалось: печатать ...

MSBuild Custom.target /t:Hello

... в командной строке выдает ожидаемое сообщение.

При добавлении Custom.targetsв проект Delphi через IDE файл в диспетчере проектов отображает файл, как и ожидалось, и .dprojтеперь файл содержит строку ...

<TargetsFile Include="Custom.targets"/>

Я щелкнул правой кнопкой мыши файл в диспетчере проектов среды IDE и выбрал Enable. Но когда проект построен, в Buildокне сообщения отображается:

[MSBuild Warning] Custom.targets (1): игнорирование отключенного импорта: PathToProjectSource\\Custom.targets

Повторное нажатие правой кнопкой мыши в Диспетчере проектов по-прежнему показывает Enableвариант вместо ожидаемого Disable.

В командной строке MSBuild ProjectName.dproj /t:Helloтоже не получается.

Я попытался взломать .dprojфайл, чтобы добавить строку ...

<Import Project="Custom.targets"/>

Печатание MSBuild ProjectName.dproj /t:Helloтеперь работает. Но в следующий раз, когда я сохраню файл проекта из IDE, <Import>оператор будет удален.

Кто-нибудь есть идеи, что идет не так, пожалуйста?

delphidabbler
источник
10
В вашем примере использования msbuild из командной строки вы показываете Custom.target, в то время как везде вы используете Custom.targets . Что это?
Кеннет Кокран
4
Хорошее место - я не заметил этого, несмотря на то, что много смотрел на код. Я не могу добраться до машины с Delphi в течение нескольких дней (в больнице!), Но попробую код, используя «target» или «target», когда смогу.
delphidabbler
6
Не пользователь Delphi, но в соответствии с этим все файлы .targets должны содержать действительные сценарии MSBuild без ошибок. Если в файле есть какие-либо ошибки, вы получаете уведомление, и, если проект ссылается на недопустимый файл .targets, он отключается и не может быть повторно включен, пока ошибки не будут исправлены. Возможно, стоит дважды проверить, все ли правильно, поскольку это объясняет симптомы, которые вы получаете.
Даниэль Морритт
К сожалению, в XE7 я не могу воспроизвести вашу проблему, кажется, что все работает должным образом: сборка из командной строки с помощью, /t:Helloа также из IDE с помощью правой кнопки мыши в Диспетчере проектов - Цели - Привет. Я добавил Custom.targetsв проект, щелкнув правой кнопкой мыши в Project Manager - Add - (просматривая файл). Путь находится в том же каталоге, что и файл .dproj.
Ондрей Келле

Ответы:

1

Delphi генерирует весь контент dproj, и этот пользовательский импорт всегда будет удален.

Вы можете написать свои собственные файлы msbuild xml, но dproj принадлежит Delphi.

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

Если вам действительно нужен гибкий XML-способ для создания проектов Delphi и создания целей, попробуйте хотеть или хотеть vnext (мой ответвление на bitbucket)

Уоррен П
источник
1

Я бы включил файл целей вручную и собрал его внешне, используя MSBuild, а не из IDE, потому что при компиляции из IDE было бы немного грязно знать, какую конфигурацию и цель вы применили (выбрана ли та, что в проекте? включенная цель - вы не получите никаких визуальных подсказок о том, что пользовательская цель включена).

Я обычно делаю это раньше, Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"чтобы они не отображались в IDE (они существуют, но скрыты для разработчиков).

Например, мои проекты Delphi XE4 заканчиваются на:

    <Import Project="..\BuildServer.Targets"/>
    <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
    <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

Мой файл .targets определяет пользовательские «PropertyGroup» и «Target» с условием, поэтому они будут применяться только при вызове из MSBuild:

  <PropertyGroup  Condition="'$(Config)'=='CustomConfig'">
    <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
    ...
  </PropertyGroup>
  <Target Name="DisplayProjectInfo">
    <Message Text="Project File Name = $(MSBuildProjectFile)"/>
    <Message Text="Version = $(VerInfo_Keys)"/>
    <Message Text="OutputDir = $(DCC_ExeOutput)"/>
  </Target>
  <Target Name="CustomTarget" Condition="'$(Config)'=='CustomConfig'">
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="Clean" />
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" />
    <CallTarget Targets="DisplayProjectInfo"/>
  </Target>

Затем скомпилируйте это с:

msbuild /t:CustomTarget /p:config=CustomConfig poject.dproj

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

Fran
источник