18

I have set up multiple targets in a single xml file. I expect all targets to run but only the frist target gets executed.

Here is a simplified version of what iam trying to do:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="T1">
    <Copy SourceFiles="c:\temp\a.txt" DestinationFolder="C:\temp2\" />    
  </Target>
  <Target Name="T2">
    <Copy SourceFiles="c:\temp\b.txt" DestinationFolder="C:\temp2\" />    
  </Target>
</Project>

I'am running the build from the TeamCity CI Server and the logs reports Process exit code: 0.

Anyone got any ideas why it does not run T2?

4 Answers 4

30

You need to tell MSBuild about your multiple targets

Try

<Target Name="Build" DependsOnTargets="T1; T2">
</Target>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the pointer, actually i got it to work by specifying: <Target Name="T2" AfterTargets="T1">
Note the dependent targets should be separated by a semicolon, not a comma as shown. E.g. <Target Name="Build" DependsOnTargets="T1; T2">
19

MSBuild allows you to define a default Target and it allows you to define dependencies among your Targets. If no default is defined, then it runs the first one it finds. Using DefaultTargets you can call multiple:

<Project DefaultTargets="T1;T2">

A Target should accomplish all of one well defined step. For example a Clean target would remove all the necessary files and folders needed to clean the project. Compile would compile all the DLLs, etc.

Your targets should normally declare their own dependencies:

<Target Name="CI" DependsOnTargets="T1, T2">
</Target>

Otherwise your target should contain all the individual steps that you want to run:

<Target Name="XX">
    <CallTarget Targets="T1"/>
    <CallTarget Targets="T2"/>
</Target>

Comments

2

MSBuild uses this order to determine what target(s) should be executed. Once a value is found it stops there and begins execution.

  • The target(s) you specify using the /t switch on msbuild.exe
  • The targets(s) contained in the DefaultTargets attribute on the Project element
  • The first target which is found in the build script (slightly morecomplicated actually)

As the previous commenter stated you can use the DependsOnTargets list to have other targets execute first before that target.

About your solution, AfterTargets is only available in MSBuild 4.0 so that will not work with previous versions.

Sayed Ibrahim Hashimi

My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

Comments

0

Alternatively you can create a property group that defines all the dependent targets:

 <PropertyGroup>
        <BuildDependsOn>T1;T2</BuildDependsOn>
 </PropertyGroup>

And then pass the value of BuildDependsOn as a parameter as shown below:

<Target Name="Build" DependsOnTargets="@(BuildDependsOn)"/>

This approach allows the depends on list to be modified outside of this project file to inject other required steps. See this site for more info.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.