- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Friday, 27 June 2008

MSBuild Conditions on Targets

This post is related to my  previous post MSBuild RE: Enforcing the Build Agent in a Team Build which is a response on the post by Michael Ruminer at http://manicprogrammer.com/cs/blogs/michaelruminer/archive/2008/06/19/enforcing-the-build-agent-in-a-team-build.aspx.

Basically every MSBuild element can contain a Condtions attribute. You can read more at MSBuild Conditions. So even targets can have conditions attached to them! Despite the fact that you can do this, you should not. I recommend that you do not use conditions on targets. Conditions on targets seem straight forward but after you take a closer look they are more complicated. We can take a look at some of the items that come to mind here.

Conditions on targets and DependsOnTargets don’t play well

Take a look at this simple project file

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="2.0"
         xmlns="
http://schemas.microsoft.com/developer/msbuild/2003"
         DefaultTargets="Demo">

  <PropertyGroup>
    <AllowTarget>true</AllowTarget>
  </PropertyGroup>

  <Target Name="SupressTarget">
    <CreateProperty Value="false">
      <Output PropertyName="AllowTarget" TaskParameter="Value"/>
    </CreateProperty>
    <Message Text=" ==== SupressTarget ==== " Importance="high"/>
    <Message Text="AllowTarget: $(AllowTarget)"/>
  </Target>
 
 
  <Target Name="Demo" Condition="'$(AllowTarget)'=='true'"
          DependsOnTargets="SupressTarget">
    <Message Text=" ===== Demo ===== " Importance="high" />

    <Message Text="AllowTarget: $(AllowTarget)"/>
  </Target>
 
</Project>

In this project the main target is Demo and it depends on a target SupressTarget which actually disables the Demo target based on its condition. If you execute the command msbuild /t:Demo you get the results shown below.

Most users would expect that the target SupressTarget target would execute which sets the AllowTarget value to false, and then the Demo target is skipped. But what is happening here is that by the time DependsOnTargets is evaluated the condition has already been evaluated and has passed! The even more interesting thing here is if you execute msbuild /t:SupressTarget;Demo the results are shown below.

 

So this time it was skipped, because SupressTarget was called before the Demo target was invoked so the condition evaluated to false.

 

Conditions and target batching doesn’t work well either

If you are batching a target and you want to execute the target for some batches but not others, this cannot be achieved with target conditions, for a few reasons but the simplest is: Either a target is or is not defined. When the target is going to be executed for the first time the condition is evaluated. If the condition is true it will exist, otherwise it will not.

I thought of some other issues but they are not coming to me at this time, but I think this is enough to deter you from using target dependencies. Instead of target dependencies you should take a look at other way of achieving the same results.

 

Sayed Ibrahim Hashimi

msbuild | Team Build | TFS Friday, 27 June 2008 07:28:35 (GMT Daylight Time, UTC+01:00)  #     |