Delphi XE custom build target is always disabled

DelphiMsbuildDelphi Xe

Delphi Problem Overview


I've created a custom MSBuild .targets file that I've included in a Delphi XE project via the IDE and enabled it from the Project Manager's context menu. Although the file validates, it always gets disabled after I re-save the project file.

Here's a simplified version of the targets file, named Custom.targets.

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

As a stand alone file this works as expected: typing...

MSBuild Custom.target /t:Hello

...at the command line gives the expected message.

Adding Custom.targets to a Delphi project via the IDE displays the file in the Project Manager as expected, and the .dproj file now contains the line...

<TargetsFile Include="Custom.targets"/>

I right-clicked the file in the IDE's Project Manager and selected Enable. But when the project is built the Build message window displays:

> [MSBuild Warning] Custom.targets(1): Ignoring disabled import: PathToProjectSource\\Custom.targets

Right-clicking again in Project Manager still shows the Enable option instead of the expected Disable.

At the command line MSBuild ProjectName.dproj /t:Hello also fails.

I've tried hacking the .dproj file to add the line...

<Import Project="Custom.targets"/>

Typing MSBuild ProjectName.dproj /t:Hello now works. But the next time I save the project file from the IDE the <Import> statement gets removed.

Anyone got any idea what's going wrong please?

Delphi Solutions


Solution 1 - Delphi

Delphi generates the entire dproj content itself and this custom import will always be deleted.

You could write your own msbuild xml files but the dproj belongs to Delphi.

Unless you have source code or are willing to monkey patch the ide you cant do that.

If you really want a flexible xml way to build delphi projects and create targets galore try want or want vnext (my fork on bitbucket)

Solution 2 - Delphi

I would include the targets file manually and build externally using MSBuild rather than from the IDE, because when compiling from the IDE its a bit messy to know which configuration and target have you applied (is the one clicked on the project? or the one from enabled target? you dont get any visual hint that a custom target is enabled).

I usually do it before the Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" so they will not show on the IDE (they exist, but are hidden to developers).

For example my Delphi XE4 projects end with:

    <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>

My .targets file defines a custom "PropertyGroup" and "Target" with a condition, so they will only apply when called from 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>

Then compile it with:

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

Using this approach lets you customize build targets to make sure every application gets the correct settings without being affected by changes made by anyone.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondelphidabblerView Question on Stackoverflow
Solution 1 - DelphiWarren PView Answer on Stackoverflow
Solution 2 - DelphiFranView Answer on Stackoverflow