30

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?

Nam G VU
  • 33,193
  • 69
  • 233
  • 372

2 Answers2

56

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)

Limitation of CallTarget

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

What should I use?

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>
MStodd
  • 4,716
  • 3
  • 30
  • 50
Julien Hoarau
  • 48,964
  • 20
  • 128
  • 117
  • 5
    +1 for detailed explanation. I personally try to avoid using CallTarget as much as I can, instead use DependsOnTargets. – Sayed Ibrahim Hashimi May 12 '10 at 13:10
  • 1
    `CallTarget` goes against the grain of MSBuild - which is to build a dependency tree of targets and run it. It's a little like using `goto` in C++. – Jonathan Feb 27 '14 at 15:30
  • Please forgive my ignorance... If the current project depends on an artifact in another project, then what is the expression we should use for `DependsOnTargets`? For example, from `Bar.vcxproj`, I can't get something like `DependsOnTargets="Project=Foo.vcxproj;Configuration=Debug;Platform=Win32;` to work. And the MS docs absolutely suck. They tell me to go to [Target Element (MSBuild)](https://msdn.microsoft.com/en-us/library/t50z2hka.aspx) for the discussion, then they don't discuss it. – jww Oct 07 '16 at 20:54
  • @jonathan are there any drawbacks (other than the one in the answer) in doing this? I find `CallTarget` a lot more readable. – Raphael Aug 30 '18 at 12:52
-3

The critical difference is that a target specified in DependsOnTarget will not execute if it has already executed previously. In this way, multiple targets can then have the same dependency, but only the first target will trigger its execution (see MSDN documentation).

You can think of it as saying "Make sure this target has already executed, and execute it if it hasn't."

CallTarget will just simply execute the target specified, regardless of whether it has executed previously or not.

Indolent Coder
  • 708
  • 3
  • 5