As far as I know, at the moment we can call other targets from within a target by using the attribute DependsOnTargets
or by using the task <CallTarget ...>
My question is when should we use each case?
If you want to build the default targets, use the MSBuild task and set the Projects parameter equal to $(MSBuildProjectFile) . When using CallTarget , MSBuild evaluates the called target in a new scope, as opposed to the same scope it's called from.
A target element can have both Inputs and Outputs attributes, indicating what items the target expects as input, and what items it produces as output. If all output items are up-to-date, MSBuild skips the target, which significantly improves the build speed. This is called an incremental build of the target.
If MSBuild determines that any output files are out of date with respect to the corresponding input file or files, then MSBuild executes the target. Otherwise, MSBuild skips the target. After the target is executed or skipped, any other target that lists it in an AfterTargets attribute is run.
MSBuild provides different ways to call target :
Using CallTarget
is an explicit approach, you start at your first target and call explicitly each target in the order you want.
Whereas DependsOnTargets
is an implicit approach, MSBuild infers the calling order by checking the dependency of the targets.
There is no difference between CallTarget
and DependsOnTargets
on the number of time a target could run : a target will never run twice during a single build (except if you use MSBuild task with different property)
One limitation of CallTarget
is with dynamic items and property : you can't access an item or a property that you have created in a target in another target called with CallTarget :
<Target Name="Caller"> <CreateProperty Value="MyValue"> <OutputTaskParameter="Value" PropertyName="NewProperty"/> </CreateProperty> <CallTarget Targets="Called"/> </Target> <Target Name="Called"> <Message Text="$(NewProperty)"/> </Target>
Dynamic property aren't publish until the target that created them is done executing. You don't have this problem using DependsOnTarget
You should use DependsOnTargets
for targets that need to be executed before your target. And CallTarget
for target to execute after your target. That's the way Microsoft do it.
<Target Name="CoreCompile" DependsOnTargets="$(CoreCompileDependsOn)"> <!-- Target execution --> <Csc ... /> ... <!-- Targets to execute after --> <CallTarget Targets="$(TargetsTriggeredByCompilation)"/> </Target>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With