views:

226

answers:

2

I have a custom target (a group of copy tasks, among others) in my build that I need to call a couple of times to effect change in different places. However, this only runs the first time it is called, after which TFS build skips the said target.

The process goes as follows:

<!-- Copy some files to another location -->
<CallTarget Targets="CopyFiles"></CallTarget>

...

<!-- Copy the above files to yet another location -->
<CallTarget Targets="CopyFiles"></CallTarget>

In the build log, it is seen that the target "CopyFiles" is skipped the second time it is called:

Target "CopyLicenseManagerFiles" skipped. Previously built successfully.

Why is this happening? Is there a way to force the target (or any custom target I write) to run multiple times?

+1  A: 

This is by design. Targets should not be thought of as "methods". MSBuild is more declarative. So it keeps track of targets that have been executed and purposefully skips those which have already been completed.

Sayed Ibrahim Hashimi
+1  A: 

It should be called once per MSBuild instance, per parameter set. Team Build does spin off separate instances of MSBuild in some circumstances (eg if you provide more than one solution configuration). But that probably doesn't help you.

More applicable to your scenario, MSBuild will re-run a task if you call it with a different set of parameters. If you're copying two different sets of files that sounds like the feature you're looking for.

<MSBuild Project=".\CommonStuff.targets" Targets="CopyFiles" Properties="Location=1" />
<!--  ....  -->
<MSBuild Project=".\CommonStuff.targets" Targets="CopyFiles" Properties="Location=2" />

The other solution is to refactor the functionality into a Task instead of a Target. While there are still declarative vs procedural quirks, Tasks behave much closer to what you think of as a "function" from more familiar languages.

Richard Berg