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:
Modify target B to read:
DependsOnTargets="A"
.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
.