What is the difference between 'DependsOnTargets' and 'AfterTargets'?

What is the difference between DependsOnTargets and AfterTargets? I can not distinguish these two.


DependsOnTargets

Defines the targets that must be executed before the target can be executed.

<Target Name="DependsOn" DependsOnTargets="DependencyTarget1;DependencyTarget2">
  <Message Text="Target : DependsOn"/>
</Target>

<Target Name="DependencyTarget2">
  <Message Text="Target : DependencyTarget2"/>
</Target> 

<Target Name="DependencyTarget1">
  <Message Text="Target : DependencyTarget1"/>
</Target> 

Output
> Target : DependencyTarget1
> Target : DependencyTarget2
> Target : DependsOn

BeforeTargets and AfterTargets (Only available in MSBuild 4)

Indicates that the target should run before or after the specified target or targets.

<Target Name="BeforeAndAfter">
  <Message Text="Target : BeforeAndAfter"/>
</Target>

<!-- BeforeTarget1 will run BEFORE target "BeforeAndAfter" -->
<Target Name="BeforeTarget" BeforeTargets="BeforeAndAfter">
  <Message Text="BeforeTarget run before : BeforeAndAfter"/>
</Target> 

<!-- BeforeTarget1 will run AFTER target "BeforeAndAfter" -->
<Target Name="AfterTarget" AfterTargets="BeforeAndAfter">
  <Message Text="AfterTarget run after : BeforeAndAfter"/>
</Target> 

Output
> BeforeTarget run before : BeforeAndAfter
> Target : BeforeAndAfter
> AfterTarget run after : BeforeAndAfter
  • If you have multiples targets that should run before or after the same specified target, they will be executed in declaration order :

    <Target Name="BeforeAndAfter">
      <Message Text="Target : BeforeAndAfter"/>
    </Target>
    
    <!-- 
       BOTH BeforeTarget1 and BeforeTarget2 should run before target "BeforeAndAfter"
    -->
    <Target Name="BeforeTarget1" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget1 run before : BeforeAndAfter"/>
    </Target> 
    
    <Target Name="BeforeTarget2" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget2 run before : BeforeAndAfter"/>
    </Target> 
    

BeforeTargets and AfterTargets could be use to extend existing build process.

For example, with this attributes you can easily execute a target before CoreCompile (defines in Microsoft.CSharp.targets). Without that you'll have to override the property CoreCompileDependsOn.

Without AfterTargets you have no way to easily execute a target after another one if no extension point is defined (CallTarget at the end of the target with a property that you can override)

DependsOnTargets, BeforeTargets and AfterTargets execution order?

When DependsOnTargets, BeforeTargets and AfterTargets are used on the same target, the order of execution is :

  • DependsOnTargets
  • BeforeTargets
  • The target
  • AfterTargets

    <Target Name="MainTarget" DependsOnTargets="DefaultDependsOn">
      <Message Text="Target : MainTarget"/>
    </Target>
    
    <Target Name="DefaultDependsOn">
      <Message Text="Target : DefaultDependsOn"/>
    </Target>
    
    <Target Name="DefaultBeforeTarget" BeforeTargets="MainTarget">
      <Message Text="Target : DefaultBeforeTarget"/>
    </Target>
    
    <Target Name="DefaultAfterTarget" AfterTargets="MainTarget">
      <Message Text="Target : DefaultAfterTarget"/>
    </Target> 
    
    Output
    > Target : DefaultDependsOn
    > Target : DefaultBeforeTarget
    > Target : MainTarget
    > Target : DefaultAfterTarget
    

More succinctly from this GitHub issue on Microsoft Docs:

<Target Name="x" DependsOnTargets="y" /> means:

If something wants to run x, y must run first.

<Target Name="a" AfterTargets="b" /> means:

If something runs b, then run a after it.


While the other answers previously provided are correct, I think they failed to mention what I think is the primary benefit of AfterTargets over DependsOnTargets.

DependsOnTargets has been around from the beginning of MSBuild. The problem with DependsOnTargets, is that it requires a target author to explicitly allow for extensibility. This is done by defining a property that is used as the DependsOnTargets value, as follows:

<PropertyGroup>
   <SomeTargetDependsOnTargets>
     Dependency1;Dependency2
   </SomeTargetDependsOnTargets>
</PropertyGroup>

<Target Name="SomeTarget" DependsOnTargets="$(SomeTargetDependsOnTargets)">
 ...
</Target>

You could then add a dependency by modifying the SomeTargetDependsOnTargets property as follows:

<SomeTargetDependsOnTargets>
    $(SomeTargetDependsOnTargets);Dependency3
</SomeTargetDependsOnTargets>

The problem with this design, is that if the author had simply inlined Dependency1;Dependency2 rather than extracting it into a property, there would be no way to externally modify it to allow for customization.

AfterTargets, on the other hand, doesn't require the original target author to have explicitly extracted the DependsOnTargets value into a property to allow for extensibility.


I think the answer is much simpler. The effect of DependsOnTargets and AfterTargets is essentially the same. The reason for BeforeTargets & AfterTargets (from the Microsoft Documentation):

This lets the project author extend an existing set of targets without modifying them directly.

So if you have an existing target B and you want to add a new target A that must execute first, you have two choices:

  1. Modify target B to read: DependsOnTargets="A".

  2. Modify target A to read: BeforeTargets="B".

If you can't modify B (e.g. it's an existing Microsoft target), that's when you need BeforeTargets.