团队基础生成自动化流程之最佳实践总论(I) – 自动化生成流程基础

 

写在最前

      首先得声明的是, 这篇文章不是来讲技术的而是讲实践的. 我理解这个题目的英文应该是<Best Practices On Team Foundation Build Automation Process> - 想要解决的问题是, 在微软提供的团队基础框架内, 如何更好的利用框架进行安排生成自动化流程的实践性问题. 想听技术讲解, 看细节分析的同学就不要苛求了, 因为技术还是那些技术. 但是, 实践虽然没有对错之分, 却有优劣之别. 本文的主旨, 就是将一些已经成熟的方案, 以及笔者在方面的经验, 汇集到一起讲述出来, 以备后来者之用. 考虑到平滑过渡的讲述需要, 我们会简单讲解基础概念和默认流程, 但是绝对不会面面俱到的讲解MSBuild和Team Foundation Build的所有细节.

      另外需要说明的是, 本文所有的实践上的选择, 都是建立在现状的基础上. 这个现状指的是Team Foundation 2008平台和它的成熟应用. 其它不成熟或未发布的平台譬如Team Foundation 2010, 不在本文的讨论范围之内. 本文当然也不负责解释从TFS 2010成功发布, 直到进入软件生产领域真正需要的时间长度.

      第三点需要说明的, 本文只假设所有的源代码都是基于.NET平台上的.如果您的代码项目中有大量标准C++项目, 那么在实践上选择可能会大不一样. 有可能这篇文章提到的一些实践方案, 反而是比较拙劣的.

      第四点, 这篇文章假定您有了一定的MSBuild基础. 您应该了解目标(Target), 任务(Task)等MSBuild基本概念.

      好了, 如果您看到这里还没有走掉, 那就让我们一起开始这段讨论吧.

 

团队基础之生成流程

 

生成(Build)重要吗?

      对于软件开发者来说, 可能更关注的是编写代码, 是设计模式, 是将明确的需求转化为实实在在的代码. 编译生成? 不就是按一下F6(VS 默认快捷键)看看没有编译错误就可以了吗?

      对于管理者来讲, 生成处于软件生产的核心地位. 最简单的原因是在生成之前, 是没有任何可以交付给用户的产品的. 如果我们把空间和时间上的范围扩大来看, 一个复杂软件系统的成功生成, 是各部分进行集成的最基本要求; 一个完整的生成流程, 也不仅仅是将代码转化为程序集这么简单, 它还可以包含自动化测试, 打包, 签名, 自动分发等过程. 这个流程的概念, 从代码文件一直延伸到可投递的产品.

      所以生成很重要! 笔者曾一度认为完整的程序员应该了解整个系统的生成流程. 它既可以让程序员从整体上掌握各个部分对于整个系统的意义, 也可以明白以后再某个特定模块中做的修改对于整个系统和整个系统的生成流程的影响.

 

默认的团队项目生成流程

      了解MSBuild的您肯定知道, MSBuild可执行脚本的内容, 无非就是一些Target标记和Task标记告诉MSBuild引擎去执行相应的一系列操作或某个特定操作. 这些Target被团队基础框架有机地组织起来组成"一整条"流程, 就是我们说的团队基础的生成流程. 在这篇文章中我们以"EndToEndIteration Build"来称谓团队基础的服务器端完整的生成过程, 这是一个单纯的过程定义(名字是具体的). EndToEndIteration Build这个过程中的某些相邻的逻辑上关系紧密的步骤, 我们把它拿出来赋予新的名字, 就成了它的子过程. 它的最大的也是最核心的子过程, 叫做"Team Build". 注意这也是个过程定义(同样名字是具体的). 生成代理(Build Agent)以MSBuild为生成引擎, 执行生成脚本文件, 完成完整的生成流程.  Team Build在呈现上就是定义了一系列生成流程和生成任务的MSBuild脚本文件. 微软为Team Build定义了默认的Target脚本, 一般在本地硬盘的的这个位置: %ProgramFile%\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets. 下面就是这个默认脚本文件的全文.  在这个文件里微软定义了它认为合理的流程和各步骤职责.

 

Microsoft.TeamFoundation.Build
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project InitialTargets="CanonicalizePaths" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
  3.  
  4.   <!-- These tasks are used by the Team Build process defined in this file -->
  5.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties"
  6.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  7.               Condition=" '$(ProjectFileVersion)' != '2' "/>
  8.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.SetBuildProperties"
  9.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  10.               Condition=" '$(ProjectFileVersion)' != '2' "/>
  11.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.BuildStep"
  12.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  13.               Condition=" '$(ProjectFileVersion)' != '2' "/>           
  14.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.Get"
  15.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  16.               Condition=" '$(ProjectFileVersion)' != '2' "/>            
  17.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.Label"
  18.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  19.               Condition=" '$(ProjectFileVersion)' != '2' "/>
  20.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.CreateNewWorkItem"
  21.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  22.               Condition=" '$(ProjectFileVersion)' != '2' "/>
  23.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.GenCheckinNotesUpdateWorkItems"
  24.               AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  25.               Condition=" '$(ProjectFileVersion)' != '2' "/>
  26.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.UpdateBuildNumberDropLocation"
  27.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  28.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  29.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.CreateWorkspaceTask"
  30.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  31.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  32.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.DeleteWorkspaceTask"
  33.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  34.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  35.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.WorkspaceItemConverterTask"
  36.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  37.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  38.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.TestToolsTask"
  39.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  40.              Condition=" '$(ProjectFileVersion)' != '2' "/>            
  41.   <UsingTask TaskName="Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildTasks.GetImpactedTests"
  42.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.TestImpact.BuildIntegration.dll"
  43.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  44.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.RevertWorkspaceTask"
  45.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
  46.              Condition=" '$(ProjectFileVersion)' != '2' "/>
  47.  
  48.   <!-- These tasks are used by the Team Build process defined in this file -->
  49.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties"
  50.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.dll"
  51.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  52.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.SetBuildProperties"
  53.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.dll"
  54.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  55.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.BuildStep"
  56.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.dll"
  57.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  58.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.Get"
  59.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  60.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  61.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.Label"
  62.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  63.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  64.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.CreateNewWorkItem"
  65.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  66.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  67.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.GenCheckinNotesUpdateWorkItems"
  68.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  69.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  70.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.UpdateBuildNumberDropLocation"
  71.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.dll"
  72.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  73.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.CreateWorkspaceTask"
  74.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  75.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  76.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.DeleteWorkspaceTask"
  77.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  78.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  79.   <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.WorkspaceItemConverterTask"
  80.              AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.Tasks.VersionControl.dll"
  81.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  82.   <UsingTask TaskName="TestToolsTask"
  83.              AssemblyFile="$(MSTestRefPath)\Microsoft.VisualStudio.QualityTools.MSBuildTasks.dll"
  84.              Condition=" '$(ProjectFileVersion)' == '2' "/>
  85.  
  86.   <!-- The Skip flags may be set to skip certain targets. -->
  87.   <PropertyGroup>
  88.  
  89.     <!-- Version of Team Build -->
  90.     <TeamBuildVersion>3.0</TeamBuildVersion>
  91.  
  92.     <!-- Path to Microsoft.VisualStudio.QualityTools.MSBuildTasks.dll. Overridable so that the 8.0 version can be used
  93.          for test assemblies compiled against the 8.0 unit test framework. -->
  94.     <MSTestRefPath Condition=" '$(MSTestRefPath)'=='' ">$(TeamBuildRefPath)</MSTestRefPath>
  95.  
  96.     <!-- Set this property to true to use the 8.0 TestToolsTask. -->
  97.     <V8TestToolsTask Condition=" '$(V8TestToolsTask)'=='' ">false</V8TestToolsTask>
  98.  
  99.     <!-- Set this property to true to do an incremental get - this will override the CleanCompilationOutputOnly,
  100.          SkipInitializeWorkspace, and ForceGet properties.
  101.         -->
  102.     <IncrementalGet Condition=" '$(IncrementalGet)'=='' " >false</IncrementalGet>
  103.  
  104.     <!-- Set this property to true to do an incremental build - this will override the SkipClean,
  105.          SkipInitializeWorkspace, and ForceGet properties.
  106.         -->
  107.     <IncrementalBuild Condition=" '$(IncrementalBuild)'=='' ">false</IncrementalBuild>
  108.  
  109.     <!-- By default desktop build is true. The build agent overriddes this for end to end builds -->
  110.     <IsDesktopBuild Condition=" '$(IsDesktopBuild)'=='' " >true</IsDesktopBuild>
  111.  
  112.     <!-- The Project File Version is defaulted here to 2. This ensures that older project files will find the correct
  113.          versions of the Task dlls referenced above. For versions of Team Build above 2, this property will be
  114.          overriden on the command line to match that version. -->
  115.     <ProjectFileVersion Condition=" '$(ProjectFileVersion)'=='' and '$(IsDesktopBuild)'!='true' ">2</ProjectFileVersion>
  116.  
  117.  
  118.     <!-- For desktop builds, the Project File Version is defaulted to 3 so that Dev10 can support desktop builds without requiring
  119.          an override to be passed in. -->
  120.     <ProjectFileVersion Condition=" '$(ProjectFileVersion)'=='' and '$(IsDesktopBuild)'=='true' ">3</ProjectFileVersion>
  121.  
  122.     <!-- If BuildProjectFolderPath is not specified (typically in a Desktop build), assume local paths
  123.          and set to MSBuildProjectDirectory
  124.          -->
  125.     <BuildProjectFolderPath Condition=" '$(BuildProjectFolderPath)'=='' ">$(MSBuildProjectDirectory)</BuildProjectFolderPath>
  126.  
  127.     <!-- Set this property to true to skip the CoreClean target. -->
  128.     <SkipClean Condition=" '$(SkipClean)'=='' " >false</SkipClean>
  129.  
  130.     <!-- Set this property to true to clean without deleting sources.
  131.          Note that direct use of this property is discouraged - the IncrementalGet and IncrementalBuild properties
  132.          should be used instead.
  133.         -->
  134.     <CleanCompilationOutputOnly Condition=" '$(CleanCompilationOutputOnly)'=='' and '$(IsDesktopBuild)'!='true' ">false</CleanCompilationOutputOnly>
  135.  
  136.     <!-- For a Desktop build, cleaning without deleting sources is the default behavior -->
  137.     <CleanCompilationOutputOnly Condition=" '$(CleanCompilationOutputOnly)'=='' and '$(IsDesktopBuild)'=='true' ">true</CleanCompilationOutputOnly>
  138.  
  139.     <!-- Set this property to true to skip the CoreInitializeWorkspace target.
  140.          Note that direct use of this property is discouraged - the IncrementalGet and IncrementalBuild properties
  141.          should be used instead.
  142.      -->
  143.     <SkipInitializeWorkspace Condition=" '$(SkipInitializeWorkspace)'=='' " >false</SkipInitializeWorkspace>
  144.  
  145.     <!-- Set this property to true to skip the CoreGet target.
  146.          Note that direct use of this property is discouraged - the IncrementalGet and IncrementalBuild properties
  147.          should be used instead.
  148.      -->
  149.     <SkipGet Condition=" '$(SkipGet)'=='' " >false</SkipGet>
  150.  
  151.     <!-- Set this property to true to skip the CoreLabel target. -->
  152.     <SkipLabel Condition=" '$(SkipLabel)'=='' " >false</SkipLabel>
  153.  
  154.     <!-- Set this property to true to skip the PostBuild target. -->
  155.     <SkipPostBuild Condition=" '$(SkipPostBuild)'=='' " >false</SkipPostBuild>
  156.  
  157.     <!-- Set this property to skip the CoreGetChangesetsAndUpdateWorkItems target, which calls the GenCheckinNotesUpdateWorkItems task. -->
  158.     <SkipGetChangesetsAndUpdateWorkItems Condition=" '$(SkipGetChangesetsAndUpdateWorkItems)'=='' ">false</SkipGetChangesetsAndUpdateWorkItems>
  159.  
  160.     <!-- Set this property to true to skip the CoreDropBuild target. -->
  161.     <SkipDropBuild Condition=" '$(SkipDropBuild)'=='' " >false</SkipDropBuild>
  162.  
  163.     <!-- Set this property to true to skip the CoreCreateWorkItem target. -->
  164.     <SkipWorkItemCreation Condition=" '$(SkipWorkItemCreation)'=='' " >false</SkipWorkItemCreation>
  165.  
  166.     <!-- Set this property to false to skip the publishing of test results (tests will still be run). -->
  167.     <PublishTestResults Condition=" '$(PublishTestResults)' == '' ">true</PublishTestResults>
  168.  
  169.   </PropertyGroup>
  170.  
  171.   <!-- Additional properties that may be set to customize the build process -->
  172.   <PropertyGroup>
  173.  
  174.     <!-- Set this property to true to enable building configurations in parallel. -->
  175.     <BuildConfigurationsInParallel Condition=" '$(BuildConfigurationsInParallel)'=='' ">true</BuildConfigurationsInParallel>
  176.  
  177.     <!-- Set this property to true to enable building solutions in parallel. -->
  178.     <BuildSolutionsInParallel Condition=" '$(BuildSolutionsInParallel)'=='' ">true</BuildSolutionsInParallel>
  179.    
  180.     <!-- Set this property to false to generate an error when an invalid configuration is encountered. -->
  181.     <SkipInvalidConfigurations Condition=" '$(SkipInvalidConfigurations)'=='' ">true</SkipInvalidConfigurations>
  182.    
  183.     <!-- Set this property to true to stop Cleaning, Compiling, and/or Testing on the first failure encountered -->
  184.     <StopOnFirstFailure Condition=" '$(StopOnFirstFailure)'=='' ">false</StopOnFirstFailure>
  185.  
  186.     <!-- Set this property to true to stop on a test failure or false to continue on a test failure -->
  187.     <StopOnTestFailure Condition=" '$(StopOnTestFailure)'=='' ">false</StopOnTestFailure>
  188.  
  189.     <!-- Set this property to true to mark builds as Failed when TestStatus is Failed -->
  190.     <TreatTestFailureAsBuildFailure Condition=" '$(TreatTestFailureAsBuildFailure)'=='' ">false</TreatTestFailureAsBuildFailure>
  191.  
  192.     <!-- The targets specified in this property will cause ProjectStartedEvents to not be logged. The default values are the P2P reference targets
  193.          from MSBuild 3.5 - GetTargetPath, GetNativeManifest, and GetCopyToOutputDirectoryItems.
  194.      -->
  195.     <TargetsNotLogged Condition=" '$(TargetsNotLogged)' == '' ">GetTargetPath;GetNativeManifest;GetCopyToOutputDirectoryItems</TargetsNotLogged>
  196.  
  197.     <!-- The default solution root for desktop builds -->
  198.     <SolutionRoot Condition=" '$(SolutionRoot)'=='' and '$(IsDesktopBuild)'=='true' " >$(MSBuildProjectDirectory)\..\..</SolutionRoot>
  199.  
  200.     <!-- The default sources subdirectory -->
  201.     <SourcesSubdirectory Condition=" '$(SourcesSubdirectory)'=='' ">Sources</SourcesSubdirectory>
  202.  
  203.     <!-- The default solution root for end to end builds -->
  204.     <SolutionRoot Condition=" '$(SolutionRoot)'=='' and '$(IsDesktopBuild)'!='true' " >$(MSBuildProjectDirectory)\..\$(SourcesSubdirectory)</SolutionRoot>
  205.  
  206.     <!-- The default binaries subdirectory -->
  207.     <BinariesSubdirectory Condition=" '$(BinariesSubdirectory)'=='' ">Binaries</BinariesSubdirectory>
  208.  
  209.     <!-- The default binaries root -->
  210.     <BinariesRoot Condition=" '$(BinariesRoot)'=='' " >$(SolutionRoot)\..\$(BinariesSubdirectory)</BinariesRoot>
  211.  
  212.     <!-- The default test results subdirectory-->
  213.     <TestResultsSubdirectory Condition=" '$(TestResultsSubdirectory)'=='' ">TestResults</TestResultsSubdirectory>
  214.  
  215.     <!-- The default test results root -->
  216.     <TestResultsRoot Condition=" '$(TestResultsRoot)'=='' " >$(SolutionRoot)\..\$(TestResultsSubdirectory)</TestResultsRoot>
  217.  
  218.     <!--
  219.          The name of the workspace that will be used for getting sources.
  220.          Note: Workspace name can be up to 64 characters long - after that it will be truncated.
  221.      -->
  222.     <WorkspaceName Condition=" '$(WorkspaceName)'=='' " >$(COMPUTERNAME)_$(BuildDefinitionId)_$(BuildAgentId)</WorkspaceName>
  223.  
  224.     <!-- The comment used for workspace creation -->
  225.     <CreateWorkspaceTaskComment Condition=" '$(CreateWorkspaceTaskComment)'=='' ">Workspace created by Team Build</CreateWorkspaceTaskComment>
  226.  
  227.     <!-- Set this to false to do an incremental get.
  228.          Note that direct use of this property is discouraged - the IncrementalGet and IncrementalBuild properties
  229.          should be used instead.
  230.      -->
  231.     <ForceGet Condition=" '$(ForceGet)'=='' ">true</ForceGet>
  232.  
  233.     <!-- Set this value to true to enable overwriting of writable files without a force get -->
  234.     <GetOverwrite Condition=" '$(GetOverwrite)'=='' ">false</GetOverwrite>
  235.      
  236.     <!-- Set this to false to do only a top-level get -->
  237.     <RecursiveGet Condition=" '$(RecursiveGet)'=='' ">true</RecursiveGet>
  238.  
  239.     <!-- The VersionSpec to be used by the Get task -->
  240.     <GetVersion Condition=" '$(GetVersion)'=='' ">$(SourceGetVersion)</GetVersion>
  241.  
  242.     <!-- The FileSpec to be used by the Get task.  When empty, all top-level folders in the workspace are used. -->
  243.     <GetFileSpec Condition=" '$(GetFileSpec)'=='' "></GetFileSpec>
  244.  
  245.     <!-- Set this to true to populate the Gets, Replaces, and Deletes item group outputs of the Get task -->
  246.     <GetPopulateOutput Condition=" '$(GetPopulateOutput)'=='' ">false</GetPopulateOutput>
  247.  
  248.     <!-- Set this to false to fail the build if unmapped files exist in a shelveset -->
  249.     <GetAllowUnmapped Condition=" '$(GetAllowUnmapped)'=='' ">true</GetAllowUnmapped>
  250.  
  251.     <!-- Set this to false to fail if there are any change conflicts (even if they can be auto merged) -->
  252.     <GetAutoMerge Condition=" '$(GetAutoMerge)'=='' ">true</GetAutoMerge>
  253.  
  254.     <!-- Set this to false to remove the ***NO_CI*** which is appended to gated check-ins -->
  255.     <GetNoCIOption Condition=" '$(GetNoCIOption)'=='' ">true</GetNoCIOption>
  256.    
  257.     <!-- Set this to false to do only a top-level label -->
  258.     <LabelRecursive Condition=" '$(LabelRecursive)'=='' ">true</LabelRecursive>
  259.  
  260.     <!-- Set this to Merge or Replace to control the treatment of unchanged items -->
  261.     <LabelChild Condition=" '$(LabelChild)'=='' ">Replace</LabelChild>
  262.  
  263.     <!-- The comment used by the Label task -->
  264.     <LabelComment Condition=" '$(LabelComment)'=='' ">Label created by Team Build</LabelComment>
  265.  
  266.     <!-- The label name used by the Label task.  By default the label name is set to $(BuildNumber) in the
  267.          InitializeEndToEndIteration target.
  268.      -->
  269.     <LabelName Condition=" '$(LabelName)'=='' "></LabelName>
  270.  
  271.     <!-- The FileSpec to be used by the Label task -->
  272.     <LabelFiles Condition=" '$(LabelFiles)'=='' ">$/</LabelFiles>
  273.  
  274.     <!-- The scope to be used by the Label task -->
  275.     <LabelScope Condition=" '$(LabelScope)'=='' ">$/$(TeamProject)</LabelScope>
  276.  
  277.     <!-- The AdditionalLibPaths property of the VCBuild task used to compile VC++ projects -->
  278.     <VCBuildAdditionalLibPaths Condition=" '$(VCBuildAdditionalLibPaths)'=='' "></VCBuildAdditionalLibPaths>
  279.  
  280.     <!-- The AdditionalOptions property of the VCBuild task used to compile VC++ projects -->
  281.     <VCBuildAdditionalOptions Condition=" '$(VCBuildAdditionalOptions)'=='' "></VCBuildAdditionalOptions>
  282.  
  283.     <!-- The ToolPath property of the VCBuild task used to compile VC++ projects -->
  284.     <VCBuildToolPath Condition=" '$(VCBuildToolPath)'=='' "></VCBuildToolPath>
  285.  
  286.     <!-- The UseEnvironment property of the VCBuild task used to compile VC++ projects -->
  287.     <VCBuildUseEnvironment Condition=" '$(VCBuildUseEnvironment)'=='' "></VCBuildUseEnvironment>
  288.  
  289.     <!-- The beginning of the vsprops file used to override VCBuild properties. -->
  290.     <VCOverridesOpen Condition=" '$(VCOverridesOpen)'=='' ">%3C?xml version=%221.0%22?%3E%0D%0A%3CVisualStudioPropertySheet ProjectType=%22Visual C++%22 Version=%228.00%22 Name=%22Team Build Overrides%22</VCOverridesOpen>
  291.  
  292.     <!-- The end of the vsprops file used to override VCBuild properties. -->
  293.     <VCOverridesClose Condition=" '$(VCOverridesClose)'=='' ">%3C/VisualStudioPropertySheet%3E</VCOverridesClose>
  294.  
  295.     <!-- Set this to true to update associated work items even on a build break -->
  296.     <UpdateAssociatedWorkItemsOnBuildBreak Condition=" '$(UpdateAssociatedWorkItemsOnBuildBreak)'=='' ">false</UpdateAssociatedWorkItemsOnBuildBreak>
  297.  
  298.     <!-- Set this to true to allow OutDir customization -->
  299.     <CustomizableOutDir Condition=" '$(CustomizableOutDir)'=='' ">false</CustomizableOutDir>
  300.  
  301.     <!-- Set this to true to allow PublishDir customization -->
  302.     <CustomizablePublishDir Condition=" '$(CustomizablePublishDir)'=='' ">false</CustomizablePublishDir>
  303.  
  304.     <!-- Set OutDir so that it is always available within TfsBuild.proj for backwards compatibility -->
  305.     <OutDir Condition=" '$(OutDir)'=='' and '$(TeamBuildOutDir)'!='' ">$(TeamBuildOutDir)</OutDir>
  306.    
  307.     <!-- Set PublishDir so that it is always available within TfsBuild.proj for backwards compatibility -->
  308.     <PublishDir Condition=" '$(PublishDir)'=='' and '$(TeamBuildPublishDir)'!='' ">$(TeamBuildPublishDir)</PublishDir>
  309.  
  310.     <!-- Set this property to false to disable test impact analysis. -->
  311.     <PerformTestImpactAnalysis Condition="'$(PerformTestImpactAnalysis)' == ''">true</PerformTestImpactAnalysis>
  312.  
  313.   </PropertyGroup>
  314.  
  315.   <ItemGroup>
  316.     <!-- Create the various paths as items so we can use %(FullPath) on them. -->
  317.     <SolutionRootItem Include="$(SolutionRoot)" />
  318.     <BinariesRootItem Include="$(BinariesRoot)" />
  319.     <TestResultsRootItem Include="$(TestResultsRoot)" />
  320.   </ItemGroup>
  321.  
  322.   <PropertyGroup>
  323.     <!-- Canonicalize the various paths. -->
  324.     <_SolutionRoot>@(SolutionRootItem->'%(FullPath)')</_SolutionRoot>
  325.     <_BinariesRoot>@(BinariesRootItem->'%(FullPath)')</_BinariesRoot>
  326.     <_TestResultsRoot>@(TestResultsRootItem->'%(FullPath)')</_TestResultsRoot>
  327.   </PropertyGroup>
  328.  
  329.   <!-- Properties needed to locate required assemblies during the build process -->
  330.   <PropertyGroup Condition=" '$(IsDesktopBuild)'=='true' ">
  331.  
  332.     <!-- The location of Team Build task assemblies on the build machine -->
  333.     <DevEnvDir Condition=" '$(DevEnvDir)'=='' and '$(NetSamplePath)'!='' " >$(NetSamplePath)\..\..\Common7\IDE</DevEnvDir>
  334.     <TeamBuildRefPath Condition=" '$(TeamBuildRefPath)'=='' " >$(DevEnvDir)\PrivateAssemblies</TeamBuildRefPath>
  335.  
  336.     <!-- Path to Microsoft.VisualStudio.QualityTools.MSBuildTasks.dll. Overridable so that the 8.0 version can be used
  337.          for test assemblies compiled against the 8.0 unit test framework. -->
  338.     <MSTestRefPath Condition=" '$(MSTestRefPath)'=='' ">$(TeamBuildRefPath)</MSTestRefPath>
  339.  
  340.     <!-- The location of Code Analysis assemblies on the build machine -->
  341.     <VSINSTALLDIR Condition=" '$(VSINSTALLDIR)'=='' and '$(NetSamplePath)'!='' " >$(NetSamplePath)\..\..</VSINSTALLDIR>
  342.     <FxCopDir Condition=" '$(FxCopDir)'=='' " >$(VSINSTALLDIR)\Team Tools\Static Analysis Tools\FxCop</FxCopDir>
  343.  
  344.   </PropertyGroup>
  345.  
  346.   <Target Name="CanonicalizePaths">
  347.  
  348.     <!-- Force evaluation of canonicalized paths. -->
  349.     <PropertyGroup>
  350.       <SolutionRoot>$(_SolutionRoot)</SolutionRoot>
  351.       <BinariesRoot>$(_BinariesRoot)</BinariesRoot>
  352.       <TestResultsRoot>$(_TestResultsRoot)</TestResultsRoot>
  353.     </PropertyGroup>
  354.    
  355.   </Target>
  356.  
  357.   <Target Name="InitializeBuildProperties">
  358.  
  359.     <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  360.                         BuildUri="$(BuildUri)"
  361.                         Condition=" '$(IsDesktopBuild)' != 'true' ">
  362.       <!-- Outputs are the initial values for the various properties of the build. -->
  363.       <Output TaskParameter="BuildDefinitionName" PropertyName="BuildDefinitionName" />
  364.       <Output TaskParameter="BuildDefinitionUri" PropertyName="BuildDefinitionUri" />
  365.       <Output TaskParameter="BuildNumber" PropertyName="BuildNumber" />
  366.       <Output TaskParameter="CompilationStatus" PropertyName="CompilationStatus" />
  367.       <Output TaskParameter="CompilationSuccess" PropertyName="CompilationSuccess" />
  368.       <Output TaskParameter="ConfigurationFolderUri" PropertyName="ConfigurationFolderUri" />
  369.       <Output TaskParameter="DropLocation" PropertyName="DropLocation" />
  370.       <Output TaskParameter="LabelName" PropertyName="FullLabelName" />
  371.       <Output TaskParameter="LastChangedBy" PropertyName="LastChangedBy" />
  372.       <Output TaskParameter="LastChangedOn" PropertyName="LastChangedOn" />
  373.       <Output TaskParameter="LogLocation" PropertyName="LogLocation" />
  374.       <Output TaskParameter="Port" PropertyName="Port" />
  375.       <Output TaskParameter="Quality" PropertyName="Quality" />
  376.       <Output TaskParameter="Reason" PropertyName="Reason" />
  377.       <Output TaskParameter="RequestedBy" PropertyName="RequestedBy" />
  378.       <Output TaskParameter="RequestedFor" PropertyName="RequestedFor" />
  379.       <Output TaskParameter="SourceGetVersion" PropertyName="SourceGetVersion" />
  380.       <Output TaskParameter="StartTime" PropertyName="StartTime" />
  381.       <Output TaskParameter="Status" PropertyName="Status" />
  382.       <Output TaskParameter="TeamProject" PropertyName="TeamProject" />
  383.       <Output TaskParameter="TestStatus" PropertyName="TestStatus" />
  384.       <Output TaskParameter="TestSuccess" PropertyName="TestSuccess" />
  385.       <!-- Get these properties for backwards compatibility only if they are not already set. -->
  386.       <Output TaskParameter="BuildAgentName" PropertyName="BuildAgentName" Condition=" '$(BuildAgentName)' == '' " />
  387.       <Output TaskParameter="BuildAgentUri" PropertyName="BuildAgentUri" Condition=" '$(BuildAgentUri)' == '' " />
  388.       <Output TaskParameter="BuildDirectory" PropertyName="BuildDirectory" Condition=" '$(BuildDirectory)' == '' " />
  389.       <Output TaskParameter="MachineName" PropertyName="MachineName" Condition=" '$(MachineName)' == '' " />
  390.       <Output TaskParameter="MaxProcesses" PropertyName="MaxProcesses" Condition=" '$(MaxProcesses)' == '' " />
  391.     </GetBuildProperties>
  392.    
  393.   </Target>
  394.  
  395.   <!-- Check settings for EndToEndIteration -->
  396.   <Target Name="CheckSettingsForEndToEndIteration"
  397.           Condition=" '$(IsDesktopBuild)'!='true' ">
  398.  
  399.     <Error Condition=" '$(BuildDefinition)'=='' " Text="The BuildDefinition property is not set." />
  400.     <Error Condition=" '$(BuildDefinitionId)'=='' " Text="The BuildDefinitionId property is not set." />
  401.     <Error Condition=" '$(BuildUri)'=='' " Text="The BuildUri property is not set." />
  402.     <Error Condition=" '$(COMPUTERNAME)'=='' " Text="The COMPUTERNAME property is not set." />
  403.     <Error Condition=" '$(TeamFoundationServerUrl)'=='' " Text="The TeamFoundationServerUrl property is not set." />
  404.     <Error Condition=" '$(TeamProject)'=='' " Text="The TeamProject property is not set." />
  405.  
  406.     <Message Text="BuildDefinition=$(BuildDefinition)" Importance="Low" />
  407.     <Message Text="BuildDefinitionId=$(BuildDefinitionId)" Importance="Low" />
  408.     <Message Text="BuildUri=$(BuildUri)" Importance="Low" />
  409.     <Message Text="ComputerName=$(COMPUTERNAME)" Importance="Low" />
  410.     <Message Text="TeamFoundationServerUrl=$(TeamFoundationServerUrl)" Importance="Low" />
  411.     <Message Text="TeamProject=$(TeamProject)" Importance="Low" />
  412.  
  413.   </Target>
  414.  
  415.   <!-- Entry point for desktop build -->
  416.   <PropertyGroup>
  417.     <DesktopBuildDependsOn>
  418.       Compile;
  419.       Test;
  420.       GenerateDocumentation;
  421.       PackageBinaries;
  422.     </DesktopBuildDependsOn>
  423.   </PropertyGroup>
  424.   <Target Name="DesktopBuild"
  425.           Condition=" '$(IsDesktopBuild)'=='true' "
  426.           DependsOnTargets="$(DesktopBuildDependsOn)" />
  427.  
  428.   <!-- Entry point for desktop rebuild -->
  429.   <PropertyGroup>
  430.     <DesktopRebuildDependsOn>
  431.       Clean;
  432.       DesktopBuild;
  433.     </DesktopRebuildDependsOn>
  434.   </PropertyGroup>
  435.   <Target Name="DesktopRebuild"
  436.           Condition=" '$(IsDesktopBuild)'=='true' "
  437.           DependsOnTargets="$(DesktopRebuildDependsOn)" />
  438.  
  439.   <!-- Override this target to execute custom tasks before EndToEndIteration -->
  440.   <Target Name="BeforeEndToEndIteration" />
  441.  
  442.   <!--
  443.        Override this target to execute a task for customizing the build number and/or drop location.
  444.        Make sure that the task outputs properties with the names 'BuildNumber' and/or 'DropLocation'.
  445.     -->
  446.   <Target Name="BuildNumberOverrideTarget" />
  447.  
  448.   <PropertyGroup>
  449.     <EndToEndIterationDependsOn>
  450.       CheckSettingsForEndToEndIteration;
  451.       InitializeBuildProperties;
  452.       BeforeEndToEndIteration;
  453.       BuildNumberOverrideTarget;
  454.       InitializeEndToEndIteration;
  455.       InitializeWorkspace;
  456.       TeamBuild;
  457.       DropBuild;
  458.       RevertWorkspace;
  459.       AfterEndToEndIteration;
  460.     </EndToEndIterationDependsOn>
  461.   </PropertyGroup>
  462.   <!-- Entry point: this target is invoked on the build machine by the build agent -->
  463.   <Target Name="EndToEndIteration"
  464.           Condition=" '$(IsDesktopBuild)'!='true' "
  465.           DependsOnTargets="$(EndToEndIterationDependsOn)" />
  466.  
  467.   <!-- Override this target to execute custom tasks after EndToEndIteration -->
  468.   <Target Name="AfterEndToEndIteration" />
  469.  
  470.   <!-- Initialize the build for EndToEndIteration -->
  471.   <Target Name="InitializeEndToEndIteration" >
  472.  
  473.     <!-- IncrementalGet == true implies CleanCompilationOutputOnly = true, SkipInitializeWorkspace = true, and ForceGet = false -->
  474.     <PropertyGroup Condition=" '$(IncrementalGet)'=='true' ">
  475.       <CleanCompilationOutputOnly>true</CleanCompilationOutputOnly>
  476.       <SkipInitializeWorkspace>true</SkipInitializeWorkspace>
  477.       <ForceGet>false</ForceGet>
  478.     </PropertyGroup>
  479.  
  480.     <!-- IncrementalBuild == true implies SkipClean = true, SkipInitializeWorkspace = true, and ForceGet = false -->
  481.     <PropertyGroup Condition=" '$(IncrementalBuild)'=='true' ">
  482.       <SkipClean>true</SkipClean>
  483.       <SkipInitializeWorkspace>true</SkipInitializeWorkspace>
  484.       <ForceGet>false</ForceGet>
  485.     </PropertyGroup>
  486.  
  487.     <!-- Update the build number and drop location in the database. This task will also create the drop directory
  488.          and grant the service account full rights on it.
  489.      -->
  490.     <UpdateBuildNumberDropLocation
  491.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  492.           BuildUri="$(BuildUri)"
  493.           BuildNumber="$(BuildNumber)"
  494.           DropLocation="$(DropLocation)\$(BuildNumber)" />
  495.  
  496.     <PropertyGroup>
  497.       <LabelName Condition=" '$(LabelName)'=='' ">$(BuildNumber)</LabelName>
  498.     </PropertyGroup>
  499.  
  500.   </Target>
  501.  
  502.   <!-- CleanAll - executes the Clean target after the Get target, and deletes the entire
  503.        sources directory. -->
  504.   <PropertyGroup>
  505.     <CleanAllDependsOn>
  506.       BeforeClean;
  507.       CoreCleanAll;
  508.       AfterClean;
  509.     </CleanAllDependsOn>
  510.   </PropertyGroup>
  511.   <Target Name="CleanAll"
  512.           Condition=" '$(CleanCompilationOutputOnly)'!='true' "
  513.           DependsOnTargets="$(CleanAllDependsOn)" />
  514.  
  515.   <!-- CleanComilationOutput - executes the Clean target before the Get target, and executes
  516.        the Clean target of each item in the SolutionToBuild item group. -->
  517.   <PropertyGroup>
  518.     <CleanCompilationOutputDependsOn>
  519.       BeforeClean;
  520.       CallClean;
  521.       AfterClean;
  522.     </CleanCompilationOutputDependsOn>
  523.   </PropertyGroup>
  524.   <Target Name="CleanCompilationOutput"
  525.           Condition=" '$(CleanCompilationOutputOnly)'=='true' "
  526.           DependsOnTargets="$(CleanCompilationOutputDependsOn)" />
  527.  
  528.   <!-- Override this target to execute custom tasks before clean -->
  529.   <Target Name="BeforeClean" />
  530.  
  531.   <!-- Backwards compatibility. Calls appropriate Core target based on the value of
  532.        $(CleanCompilationOutputOnly). -->
  533.   <PropertyGroup>
  534.     <CleanDependsOn>
  535.       BeforeClean;
  536.       CoreClean;
  537.       AfterClean;
  538.     </CleanDependsOn>
  539.   </PropertyGroup>
  540.   <!-- Batch target for cleanup -->
  541.   <Target Name="Clean"
  542.           DependsOnTargets="$(CleanDependsOn)" />
  543.  
  544.   <!-- Override this target to execute custom tasks after clean -->
  545.   <Target Name="AfterClean" />
  546.  
  547.   <PropertyGroup>
  548.     <CoreCleanDependsOn>
  549.     </CoreCleanDependsOn>
  550.   </PropertyGroup>
  551.   <Target Name="CoreClean"
  552.           DependsOnTargets="$(CoreCleanDependsOn)">
  553.  
  554.     <CallTarget Condition=" '$(CleanCompilationOutputOnly)'!='true' "
  555.                 Targets="CoreCleanAll" />
  556.  
  557.     <CallTarget Condition=" '$(CleanCompilationOutputOnly)'=='true' "
  558.                 Targets="CallClean" />
  559.    
  560.   </Target>
  561.  
  562.   <PropertyGroup>
  563.     <CoreCleanAllDependsOn/>
  564.   </PropertyGroup>
  565.   <!-- Old style Clean - just remove directories -->
  566.   <Target Name="CoreCleanAll"
  567.           Condition=" '$(SkipClean)'!='true' "
  568.           DependsOnTargets="$(CoreCleanAllDependsOn)">
  569.  
  570.     <RemoveDir Condition="Exists('$(SolutionRoot)')"
  571.                Directories="$(SolutionRoot)" />
  572.  
  573.     <RemoveDir Condition="Exists('$(BinariesRoot)')"
  574.                Directories="$(BinariesRoot)" />
  575.  
  576.     <RemoveDir Condition="Exists('$(TestResultsRoot)')"
  577.                Directories="$(TestResultsRoot)" />
  578.  
  579.   </Target>
  580.  
  581.   <!-- Call CoreCleanCompilationOutput via an MSBuild Task to ensure that ComputeConfigurationList gets executed
  582.        if any properties have changed. -->
  583.   <Target Name="CallClean"
  584.           Condition=" '$(SkipClean)'!='true' ">
  585.     <!-- Pass in all properties that users might want during the course of the clean targets. -->
  586.     <MSBuild Projects="$(MSBuildProjectFile)"
  587.              Properties="BuildAgentName=$(BuildAgentName);BuildAgentUri=$(BuildAgentUri);BuildDefinitionName=$(BuildDefinitionName);BuildDefinitionUri=$(BuildDefinitionUri);
  588.                          BuildDirectory=$(BuildDirectory);BuildNumber=$(BuildNumber);CompilationStatus=$(CompilationStatus);CompilationSuccess=$(CompilationSuccess);
  589.                          ConfigurationFolderUri=$(ConfigurationFolderUri);DropLocation=$(DropLocation);
  590.                          FullLabelName=$(FullLabelName);LastChangedBy=$(LastChangedBy);LastChangedOn=$(LastChangedOn);LogLocation=$(LogLocation);
  591.                          MachineName=$(MachineName);MaxProcesses=$(MaxProcesses);Port=$(Port);Quality=$(Quality);Reason=$(Reason);RequestedBy=$(RequestedBy);RequestedFor=$(RequestedFor);
  592.                          SourceGetVersion=$(SourceGetVersion);StartTime=$(StartTime);Status=$(Status);TeamProject=$(TeamProject);TestStatus=$(TestStatus);
  593.                          TestSuccess=$(TestSuccess);WorkspaceName=$(WorkspaceName);WorkspaceOwner=$(WorkspaceOwner);
  594.                          SolutionRoot=$(SolutionRoot);BinariesRoot=$(BinariesRoot);TestResultsRoot=$(TestResultsRoot);
  595.                          $(CustomPropertiesForClean)"
  596.              Targets="CoreCleanCompilationOutput">
  597.       <Output TaskParameter="TargetOutputs" ItemName="CleanOutputs" />
  598.     </MSBuild>
  599.   </Target>
  600.  
  601.   <PropertyGroup>
  602.     <CoreCleanCompilationOutputDependsOn>
  603.       ComputeConfigurationList;
  604.     </CoreCleanCompilationOutputDependsOn>
  605.   </PropertyGroup>
  606.   <!-- New style Clean - call MSBuild /t:Clean for each solution, then remove the Binaries and TestResults directories -->
  607.   <Target Name="CoreCleanCompilationOutput"
  608.           DependsOnTargets="$(CoreCleanCompilationOutputDependsOn)"
  609.           Outputs="@(CleanOutputs)">
  610.  
  611.     <MSBuild BuildInParallel="$(BuildConfigurationsInParallel)"
  612.              Projects="@(ConfigurationList)"
  613.              Targets="CleanConfiguration"
  614.              StopOnFirstFailure="$(StopOnFirstFailure)">
  615.       <Output TaskParameter="TargetOutputs" ItemName="CleanOutputs" />
  616.     </MSBuild>
  617.  
  618.     <RemoveDir
  619.           Condition="Exists('$(BinariesRoot)')"
  620.           Directories="$(BinariesRoot)" />
  621.  
  622.     <RemoveDir
  623.           Condition="Exists('$(TestResultsRoot)')"
  624.           Directories="$(TestResultsRoot)" />
  625.  
  626.   </Target>
  627.  
  628.   <Target Name="BeforeCleanConfiguration" />
  629.  
  630.   <PropertyGroup>
  631.     <CleanConfigurationDependsOn>
  632.       BeforeCleanConfiguration;
  633.       CoreCleanConfiguration;
  634.       AfterCleanConfiguration;
  635.     </CleanConfigurationDependsOn>
  636.   </PropertyGroup>
  637.  
  638.   <Target Name="CleanConfiguration"
  639.           DependsOnTargets="$(CleanConfigurationDependsOn)"
  640.           Outputs="@(CleanOutputs)" />
  641.  
  642.   <Target Name="AfterCleanConfiguration" />
  643.  
  644.   <PropertyGroup>
  645.     <CoreCleanConfigurationDependsOn>
  646.       ComputeSolutionList;
  647.     </CoreCleanConfigurationDependsOn>
  648.   </PropertyGroup>
  649.   <!-- Clean for Platform / Configuration combination -->
  650.   <Target Name="CoreCleanConfiguration"
  651.           DependsOnTargets="$(CoreCleanConfigurationDependsOn)">
  652.  
  653.     <MSBuild BuildInParallel="$(BuildSolutionsInParallel)"
  654.              Projects="@(SolutionList)"
  655.              Targets="CleanSolution"
  656.              StopOnFirstFailure="$(StopOnFirstFailure)">
  657.       <Output TaskParameter="TargetOutputs" ItemName="CleanOutputs" />
  658.     </MSBuild>
  659.  
  660.     <!-- Add Platform and Configuration metadata to CleanOutputs. -->
  661.     <ItemGroup>
  662.       <CleanOutputs>
  663.         <Platform>$(Platform)</Platform>
  664.         <Configuration>$(Configuration)</Configuration>
  665.       </CleanOutputs>
  666.     </ItemGroup>
  667.  
  668.   </Target>
  669.  
  670.   <!-- Override this target to execute custom tasks before cleaning an individual solution -->
  671.   <Target Name="BeforeCleanSolution" />
  672.  
  673.   <!-- Clean for individual Solution -->
  674.   <PropertyGroup>
  675.     <CleanSolutionDependsOn>
  676.       BeforeCleanSolution;
  677.       CoreCleanSolution;
  678.       AfterCleanSolution;
  679.     </CleanSolutionDependsOn>
  680.   </PropertyGroup>
  681.   <Target Name="CleanSolution"
  682.           DependsOnTargets="$(CleanSolutionDependsOn)"
  683.           Outputs="@(CleanOutputs)" />
  684.  
  685.   <!-- Override this target to execute custom tasks after cleaning an individual solution -->
  686.   <Target Name="AfterCleanSolution" />
  687.  
  688.   <Target Name="CoreCleanSolution"
  689.           Condition=" Exists($(Solution)) ">
  690.  
  691.     <PropertyGroup>
  692.       <VsPropsFile Condition=" '$(Platform)' != 'Any CPU' ">$(Solution).$(Platform).$(Configuration).vsprops</VsPropsFile> 
  693.       <VsPropsFile Condition=" '$(Platform)' == 'Any CPU' ">$(Solution).$(Configuration).vsprops</VsPropsFile>
  694.       <OutDirOption Condition=" '$(CustomizableOutDir)' != 'true' ">OutDir=$(TeamBuildOutDir)</OutDirOption>
  695.       <PublishDirOption Condition=" '$(CustomizablePublishDir)' != 'true' ">PublishDir=$(TeamBuildPublishDir)</PublishDirOption>
  696.     </PropertyGroup>
  697.  
  698.     <!-- Generate the VCOverride file for C++ projects -->
  699.     <WriteLinesToFile Condition=" '$(CustomizableOutDir)' != 'true' "
  700.                       File="$(VsPropsFile)"
  701.                       Lines="$(VCOverridesOpen) OutputDirectory=%22$(OutDir)%22%3E%0D%0A$(AdditionalVCOverrides)$(VCOverridesClose)"
  702.                       Overwrite="true" />
  703.  
  704.     <WriteLinesToFile Condition=" '$(CustomizableOutDir)' == 'true' "
  705.                       File="$(VsPropsFile)"
  706.                       Lines="$(VCOverridesOpen) %3E%0D%0A$(AdditionalVCOverrides)$(VCOverridesClose)"
  707.                       Overwrite="true" />
  708.  
  709.     <!-- Call MSBuild /t:Clean for each solution -->
  710.     <MSBuild BuildInParallel="$(BuildSolutionsInParallel)"
  711.              Projects="$(Solution)"
  712.              Properties="Configuration=$(Configuration);Platform=$(Platform);$(OutDirOption);$(PublishDirOption);SkipInvalidConfigurations=$(SkipInvalidConfigurations);
  713.                          VCBuildOverride=$(VsPropsFile);VCBuildAdditionalLibPaths=$(VCBuildAdditionalLibPaths);VCBuildAdditionalOptions=$(VCBuildAdditionalOptions);VCBuildToolPath=$(VCBuildToolPath);VCBuildUseEnvironment=$(VCBuildUseEnvironment);
  714.                          $(CustomPropertiesForClean)"
  715.              Targets="Clean"
  716.              StopOnFirstFailure="$(StopOnFirstFailure)">
  717.       <Output TaskParameter="TargetOutputs" ItemName="CleanOutputs" />
  718.     </MSBuild>
  719.  
  720.   </Target>
  721.  
  722.   <PropertyGroup>
  723.     <TeamBuildDependsOn>
  724.       CleanAll;
  725.       InitializeBuild;
  726.       PreBuild;
  727.       CleanCompilationOutput;
  728.       Compile;
  729.       PostBuild;
  730.       GetImpactedTests;     
  731.       Test;
  732.       GenerateDocumentation;
  733.       PackageBinaries;
  734.     </TeamBuildDependsOn>
  735.   </PropertyGroup>
  736.   <!-- Batch target for non desktop build -->
  737.   <Target Name="TeamBuild"
  738.           Condition=" '$(IsDesktopBuild)'!='true' "
  739.           DependsOnTargets="$(TeamBuildDependsOn)" />
  740.  
  741.   <Target Name="InitializeBuild"
  742.           Condition=" '$(IsDesktopBuild)'!='true' " >
  743.  
  744.     <!-- Create a folder for the source files -->
  745.     <MakeDir
  746.           Directories="$(SolutionRoot)"
  747.           Condition="!Exists('$(SolutionRoot)')" />
  748.  
  749.   </Target>
  750.  
  751.   <PropertyGroup>
  752.     <PreBuildDependsOn>
  753.       Get;
  754.       Label;
  755.     </PreBuildDependsOn>
  756.   </PropertyGroup>
  757.   <Target Name="PreBuild"
  758.           Condition=" '$(IsDesktopBuild)'!='true' "
  759.           DependsOnTargets="$(PreBuildDependsOn)" />
  760.  
  761.   <!-- Override this target to execute custom tasks before workspace initialization -->
  762.   <Target Name="BeforeInitializeWorkspace" />
  763.  
  764.   <PropertyGroup>
  765.     <InitializeWorkspaceDependsOn>
  766.       BeforeInitializeWorkspace;
  767.       CoreInitializeWorkspace;
  768.       AfterInitializeWorkspace;
  769.     </InitializeWorkspaceDependsOn>
  770.   </PropertyGroup>
  771.   <!-- Batch target for initializing the workspace -->
  772.   <Target Name="InitializeWorkspace"
  773.           DependsOnTargets="$(InitializeWorkspaceDependsOn)"/>
  774.  
  775.   <!-- Override this target to execute custom tasks after workspace initialization  -->
  776.   <Target Name="AfterInitializeWorkspace" />
  777.  
  778.   <PropertyGroup>
  779.     <CoreInitializeWorkspaceDependsOn />
  780.   </PropertyGroup>
  781.   <Target Name="CoreInitializeWorkspace"
  782.           Condition=" '$(IsDesktopBuild)'!='true' "
  783.           DependsOnTargets="$(CoreInitializeWorkspaceDependsOn)" >
  784.  
  785.     <!-- Delete the workspace left by the previous build -->
  786.     <DeleteWorkspaceTask
  787.           Condition=" '$(SkipInitializeWorkspace)'!='true' and '$(CleanCompilationOutputOnly)' != 'true' and '$(SkipClean)' != 'true' "
  788.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  789.           BuildUri="$(BuildUri)"
  790.           Name="$(WorkspaceName)"
  791.           DeleteLocalItems="true" />
  792.  
  793.     <DeleteWorkspaceTask
  794.           Condition=" '$(SkipInitializeWorkspace)'!='true' and ('$(CleanCompilationOutputOnly)' == 'true' or '$(SkipClean)' == 'true') "
  795.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  796.           BuildUri="$(BuildUri)"
  797.           Name="$(WorkspaceName)"
  798.           DeleteLocalItems="false" />
  799.  
  800.     <!-- Create the workspace for this build -->
  801.     <CreateWorkspaceTask
  802.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  803.           BuildUri="$(BuildUri)"
  804.           BuildDirectory="$(BuildDirectory)"
  805.           SourcesDirectory="$(SolutionRoot)"
  806.           Name="$(WorkspaceName)"
  807.           Comment="$(CreateWorkspaceTaskComment)">
  808.       <Output TaskParameter="Name" PropertyName="WorkspaceName" />
  809.       <Output TaskParameter="Owner" PropertyName="WorkspaceOwner" />
  810.     </CreateWorkspaceTask>
  811.  
  812.   </Target>
  813.  
  814.   <!-- Override this target to execute custom tasks before getting sources -->
  815.   <Target Name="BeforeGet" />
  816.  
  817.   <PropertyGroup>
  818.     <GetDependsOn>
  819.       BeforeGet;
  820.       CoreGet;
  821.       AfterGet;
  822.     </GetDependsOn>
  823.   </PropertyGroup>
  824.   <!-- Batch target for getting sources -->
  825.   <Target Name="Get"
  826.           DependsOnTargets="$(GetDependsOn)" />
  827.  
  828.   <!-- Override this target to execute custom tasks after getting sources -->
  829.   <Target Name="AfterGet" />
  830.  
  831.   <PropertyGroup>
  832.     <CoreGetDependsOn/>
  833.   </PropertyGroup>
  834.   <Target Name="CoreGet"
  835.           Condition=" '$(SkipGet)'!='true' and '$(IsDesktopBuild)'!='true' "
  836.           DependsOnTargets="$(CoreGetDependsOn)" >
  837.  
  838.     <!-- Get the sources for the given workspace-->
  839.     <Get TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  840.          BuildUri="$(BuildUri)"
  841.          Workspace="$(WorkspaceName)"
  842.          Version="$(GetVersion)"
  843.          Filespec="$(GetFilespec)"
  844.          PopulateOutput="$(GetPopulateOutput)"
  845.          Overwrite="$(GetOverwrite)"
  846.          Preview="$(PreviewGet)"
  847.          Recursive="$(RecursiveGet)"
  848.          Force="$(ForceGet)"
  849.          Condition=" '$(ProjectFileVersion)' == '2' ">
  850.       <Output TaskParameter="Gets" ItemName="Gets" />
  851.       <Output TaskParameter="Replaces" ItemName="Replaces" />
  852.       <Output TaskParameter="Deletes" ItemName="Deletes" />
  853.       <Output TaskParameter="Warnings" ItemName="GetWarnings" />
  854.     </Get>
  855.  
  856.     <Get TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  857.          BuildUri="$(BuildUri)"
  858.          Workspace="$(WorkspaceName)"
  859.          Version="$(GetVersion)"
  860.          Filespec="$(GetFilespec)"
  861.          PopulateOutput="$(GetPopulateOutput)"
  862.          Overwrite="$(GetOverwrite)"
  863.          Preview="$(PreviewGet)"
  864.          Recursive="$(RecursiveGet)"
  865.          Force="$(ForceGet)"
  866.          AllowUnmapped="$(GetAllowUnmapped)"
  867.          AutoMerge="$(GetAutoMerge)"
  868.          NoCIOption="$(GetNoCIOption)"
  869.          BuildDirectory="$(BuildDirectory)"
  870.          Condition=" '$(ProjectFileVersion)' != '2' ">
  871.       <Output TaskParameter="Gets" ItemName="Gets" />
  872.       <Output TaskParameter="Replaces" ItemName="Replaces" />
  873.       <Output TaskParameter="Deletes" ItemName="Deletes" />
  874.       <Output TaskParameter="Warnings" ItemName="GetWarnings" />
  875.     </Get>
  876.  
  877.     <SetBuildProperties Condition=" '$(GetVersion)' != '$(SourceGetVersion)' "
  878.                         TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  879.                         BuildUri="$(BuildUri)"
  880.                         SourceGetVersion="$(GetVersion)" />
  881.  
  882.     <PropertyGroup>
  883.       <SourceGetVersion>$(GetVersion)</SourceGetVersion>
  884.     </PropertyGroup>
  885.    
  886.   </Target>
  887.  
  888.   <!-- Override this target to execute custom tasks before labeling sources -->
  889.   <Target Name="BeforeLabel" />
  890.  
  891.   <PropertyGroup>
  892.     <LabelDependsOn>
  893.       BeforeLabel;
  894.       CoreLabel;
  895.       AfterLabel;
  896.     </LabelDependsOn>
  897.   </PropertyGroup>
  898.   <!-- Batch target for labeling sources -->
  899.   <Target Name="Label"
  900.           DependsOnTargets="$(LabelDependsOn)" />
  901.  
  902.   <!-- Override this target to execute custom tasks after labeling sources -->
  903.   <Target Name="AfterLabel" />
  904.  
  905.   <PropertyGroup>
  906.     <CoreLabelDependsOn/>
  907.   </PropertyGroup>
  908.   <Target Name="CoreLabel"
  909.           Condition=" '$(SkipLabel)'!='true' and '$(IsDesktopBuild)'!='true' "
  910.           DependsOnTargets="$(CoreLabelDependsOn)" >
  911.  
  912.     <!-- The VersionSpec to be used by the Label task. Set it here to pick up any WorkspaceName overrides. -->
  913.     <PropertyGroup>
  914.       <LabelVersion Condition=" '$(LabelVersion)'=='' ">W$(WorkspaceName)</LabelVersion>
  915.     </PropertyGroup>
  916.    
  917.     <!-- Label the latest sources in the workspace -->
  918.     <Label TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  919.            BuildUri="$(BuildUri)"
  920.            Name="$(LabelName)"
  921.            Scope="$(LabelScope)"
  922.            Version="$(LabelVersion)"
  923.            Files="$(LabelFiles)"
  924.            Child="$(LabelChild)"
  925.            Comments="$(LabelComment)"
  926.            Recursive="$(LabelRecursive)">
  927.       <Output TaskParameter="Name" PropertyName="LabelName" />
  928.     </Label>
  929.  
  930.     <!-- Set the build's LabelName property -->
  931.     <SetBuildProperties
  932.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  933.           BuildUri="$(BuildUri)"
  934.           LabelName="$(LabelName)@$(LabelScope)" />
  935.  
  936.   </Target>
  937.  
  938.   <!-- Override this target to execute custom tasks before compilation -->
  939.   <Target Name="BeforeCompile" />
  940.  
  941.   <PropertyGroup>
  942.     <CompileDependsOn>
  943.       BeforeCompile;
  944.       CallCompile;
  945.       AfterCompile;
  946.     </CompileDependsOn>
  947.   </PropertyGroup>
  948.   <!-- Batch target for compilation -->
  949.   <Target Name="Compile"
  950.           DependsOnTargets="$(CompileDependsOn)" />
  951.  
  952.   <!-- Override this target to execute custom tasks after compilation -->
  953.   <Target Name="AfterCompile" />
  954.  
  955.   <!-- Call CoreCompile via an MSBuild Task to ensure that ComputeConfigurationList gets executed. -->
  956.   <PropertyGroup>
  957.     <!-- Backwards Compatibility
  958.          Make sure the CoreCompileDependsOn targets are executed in the main MSBuild call (not in a task invocation).
  959.         -->
  960.     <CoreCompileDependsOn />
  961.   </PropertyGroup>
  962.   <Target Name="CallCompile"
  963.           DependsOnTargets="$(CoreCompileDependsOn)">
  964.     <!-- Backwards Compatibility
  965.       In Team Build v1 the OutDir property would remain set to its value for the final item in the ConfigurationToBuild
  966.       item group for the duration of the build. These two property declarations mimic this behavior for backwards
  967.       compatibility, to preserve support for the approach laid out in the MSDN article at:
  968.       http://msdn2.microsoft.com/en-us/library/ms404859.aspx 
  969.      
  970.       A better approach for this version of Microsoft.TeamFoundation.Build.targets would be to use the OutDir property
  971.       for a particular configuration by overriding BeforeCompileConfiguration / AfterCompileConfiguration or
  972.       BeforeCompileSolution / AfterCompileSolution.  In these targets, OutDir will be set to the output directory for
  973.       the current item in the ConfigurationToBuild item group.
  974.      -->
  975.     <PropertyGroup>
  976.       <OutDir Condition=" '%(ConfigurationToBuild.PlatformToBuild)' != 'Any CPU' ">$(BinariesRoot)\%(ConfigurationToBuild.PlatformToBuild)\%(ConfigurationToBuild.FlavorToBuild)\\cf1 </OutDir>
  977.       <OutDir Condition=" '%(ConfigurationToBuild.PlatformToBuild)' == 'Any CPU' ">$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\\cf1 </OutDir>
  978.     </PropertyGroup>
  979.  
  980.     <!-- Pass in all properties that users might want during the course of the compile targets. -->
  981.     <MSBuild Projects="$(MSBuildProjectFile)"
  982.              Properties="BuildAgentName=$(BuildAgentName);BuildAgentUri=$(BuildAgentUri);BuildDefinitionName=$(BuildDefinitionName);BuildDefinitionUri=$(BuildDefinitionUri);
  983.                          BuildDirectory=$(BuildDirectory);BuildNumber=$(BuildNumber);CompilationStatus=$(CompilationStatus);CompilationSuccess=$(CompilationSuccess);
  984.                          ConfigurationFolderUri=$(ConfigurationFolderUri);DropLocation=$(DropLocation);
  985.                          FullLabelName=$(FullLabelName);LastChangedBy=$(LastChangedBy);LastChangedOn=$(LastChangedOn);LogLocation=$(LogLocation);
  986.                          MachineName=$(MachineName);MaxProcesses=$(MaxProcesses);Port=$(Port);Quality=$(Quality);Reason=$(Reason);RequestedBy=$(RequestedBy);RequestedFor=$(RequestedFor);
  987.                          SourceGetVersion=$(SourceGetVersion);StartTime=$(StartTime);Status=$(Status);TeamProject=$(TeamProject);TestStatus=$(TestStatus);
  988.                          TestSuccess=$(TestSuccess);WorkspaceName=$(WorkspaceName);WorkspaceOwner=$(WorkspaceOwner);
  989.                          SolutionRoot=$(SolutionRoot);BinariesRoot=$(BinariesRoot);TestResultsRoot=$(TestResultsRoot);
  990.                          $(CustomPropertiesForBuild)"
  991.              Targets="CoreCompile">
  992.       <Output TaskParameter="TargetOutputs" ItemName="CompilationOutputs" />
  993.     </MSBuild>
  994.  
  995.     <OnError ExecuteTargets="SetBuildBreakProperties;OnBuildBreak;" />
  996.  
  997.   </Target>
  998.  
  999.   <PropertyGroup>
  1000.     <_CoreCompileDependsOn>
  1001.       ComputeConfigurationList;
  1002.     </_CoreCompileDependsOn>
  1003.   </PropertyGroup>
  1004.   <!-- Main compile target -->
  1005.   <Target Name="CoreCompile"
  1006.           DependsOnTargets="$(_CoreCompileDependsOn)"
  1007.           Outputs="@(CompilationOutputs)">
  1008.  
  1009.     <MakeDir Directories="$(BinariesRoot)" Condition="!Exists('$(BinariesRoot)')" />
  1010.  
  1011.     <MSBuild BuildInParallel="$(BuildConfigurationsInParallel)"
  1012.              Projects="@(ConfigurationList)"
  1013.              Targets="CompileConfiguration"
  1014.              StopOnFirstFailure="$(StopOnFirstFailure)">
  1015.       <Output TaskParameter="TargetOutputs" ItemName="CompilationOutputs" />
  1016.     </MSBuild>
  1017.  
  1018.   </Target>
  1019.  
  1020.   <!-- Override this target to execute custom tasks before the compilation of an individual configuration -->
  1021.   <Target Name="BeforeCompileConfiguration" />
  1022.  
  1023.   <PropertyGroup>
  1024.     <CompileConfigurationDependsOn>
  1025.       BeforeCompileConfiguration;
  1026.       CoreCompileConfiguration;
  1027.       AfterCompileConfiguration;
  1028.     </CompileConfigurationDependsOn>
  1029.   </PropertyGroup>
  1030.  
  1031.   <!-- Batch target for individual configuration compilation -->
  1032.   <Target Name="CompileConfiguration"
  1033.           DependsOnTargets="$(CompileConfigurationDependsOn)"
  1034.           Outputs="@(CompilationOutputs)" />
  1035.  
  1036.   <!-- Override this target to execute custom tasks after the compilation of an individual configuration -->
  1037.   <Target Name="AfterCompileConfiguration" />
  1038.  
  1039.   <PropertyGroup>
  1040.     <CoreCompileConfigurationDependsOn>
  1041.       ComputeSolutionList;
  1042.     </CoreCompileConfigurationDependsOn>
  1043.   </PropertyGroup>
  1044.   <!-- Compile an individual configuration -->
  1045.   <Target Name="CoreCompileConfiguration" DependsOnTargets="$(CoreCompileConfigurationDependsOn)">
  1046.  
  1047.     <MSBuild BuildInParallel="$(BuildSolutionsInParallel)"
  1048.              Projects="@(SolutionList)"
  1049.              Targets="CompileSolution"
  1050.              StopOnFirstFailure="$(StopOnFirstFailure)">
  1051.       <Output TaskParameter="TargetOutputs" ItemName="CompilationOutputs" />
  1052.     </MSBuild>
  1053.  
  1054.     <!-- Add Platform and Configuration metadata to CompilationOutputs. -->
  1055.     <ItemGroup>
  1056.       <CompilationOutputs>
  1057.         <Platform>$(Platform)</Platform>
  1058.         <Configuration>$(Configuration)</Configuration>
  1059.       </CompilationOutputs>
  1060.     </ItemGroup>
  1061.  
  1062.   </Target>
  1063.  
  1064.   <!-- Override this target to execute custom tasks before the compilation of an individual solution -->
  1065.   <Target Name="BeforeCompileSolution" />
  1066.  
  1067.   <PropertyGroup>
  1068.     <CompileSolutionDependsOn>
  1069.       BeforeCompileSolution;
  1070.       CoreCompileSolution;
  1071.       AfterCompileSolution;
  1072.     </CompileSolutionDependsOn>
  1073.   </PropertyGroup>
  1074.   <!-- Batch target for individual solution compilation. -->
  1075.   <Target Name="CompileSolution"
  1076.           DependsOnTargets="$(CompileSolutionDependsOn)"
  1077.           Outputs="@(CompilationOutputs)" />
  1078.  
  1079.   <!-- Override this target to execute custom tasks after the compilation of an individual solution -->
  1080.   <Target Name="AfterCompileSolution" />
  1081.  
  1082.   <!-- Compile an individual solution -->
  1083.   <PropertyGroup>
  1084.     <!-- This property is used by FxCopTask to determine whether it is being used within Team Build. -->
  1085.     <TeamBuildConstants>_TEAM_BUILD_</TeamBuildConstants>
  1086.   </PropertyGroup>
  1087.   <Target Name="CoreCompileSolution">
  1088.  
  1089.     <PropertyGroup>
  1090.       <CodeAnalysisOption Condition=" '$(RunCodeAnalysis)'=='Always'">RunCodeAnalysis=true</CodeAnalysisOption>
  1091.       <VCOverridesCodeAnalysis Condition=" '$(RunCodeAnalysis)'=='Always'">%09%3CTool Name=%22VCCLCompilerTool%22 EnablePREfast=%22true%22 /%3E%0D%0A%09%3CTool Name=%22VCFxCopTool%22 EnableFxCop=%22true%22 /%3E%0D%0A</VCOverridesCodeAnalysis>
  1092.       <CodeAnalysisOption Condition=" '$(RunCodeAnalysis)'=='Never'">RunCodeAnalysis=false</CodeAnalysisOption>
  1093.       <VCOverridesCodeAnalysis Condition=" '$(RunCodeAnalysis)'=='Never'">%09%3CTool Name=%22VCCLCompilerTool%22 EnablePREfast=%22false%22 /%3E%0D%0A%09%3CTool Name=%22VCFxCopTool%22 EnableFxCop=%22false%22 /%3E%0D%0A</VCOverridesCodeAnalysis>
  1094.       <VsPropsFile Condition=" '$(Platform)' != 'Any CPU' ">$(Solution).$(Platform).$(Configuration).vsprops</VsPropsFile>
  1095.       <VsPropsFile Condition=" '$(Platform)' == 'Any CPU' ">$(Solution).$(Configuration).vsprops</VsPropsFile>
  1096.       <ReferencePathOption Condition=" '@(AdditionalReferencePath)'!='' ">ReferencePath=$(ReferencePath);@(AdditionalReferencePath)</ReferencePathOption>
  1097.       <OutDirOption Condition=" '$(CustomizableOutDir)' != 'true'">OutDir=$(TeamBuildOutDir)</OutDirOption>
  1098.       <PublishDirOption Condition=" '$(CustomizablePublishDir)' != 'true' ">PublishDir=$(TeamBuildPublishDir)</PublishDirOption>
  1099.       <FxCopDirOption Condition=" '$(FxCopDir)' != '' ">FxCopDir=$(FxCopDir)</FxCopDirOption>
  1100.     </PropertyGroup>
  1101.  
  1102.     <!-- Generate the VCOverride file for C++ projects -->
  1103.     <WriteLinesToFile Condition=" '$(CustomizableOutDir)' != 'true' "
  1104.                       File="$(VsPropsFile)"
  1105.                       Lines="$(VCOverridesOpen) OutputDirectory=%22$(OutDir)%22%3E%0D%0A$(VCOverridesCodeAnalysis)$(AdditionalVCOverrides)$(VCOverridesClose)"
  1106.                       Overwrite="true" />
  1107.  
  1108.     <WriteLinesToFile Condition=" '$(CustomizableOutDir)' == 'true' "
  1109.                       File="$(VsPropsFile)"
  1110.                       Lines="$(VCOverridesOpen) %3E%0D%0A$(VCOverridesCodeAnalysis)$(AdditionalVCOverrides)$(VCOverridesClose)"
  1111.                       Overwrite="true" />
  1112.  
  1113.     <!-- Build using MSBuild task -->
  1114.     <MSBuild BuildInParallel="$(BuildSolutionsInParallel)"
  1115.              Projects="$(Solution)"
  1116.              Properties="Configuration=$(Configuration);Platform=$(Platform);$(OutDirOption);$(PublishDirOption);SkipInvalidConfigurations=$(SkipInvalidConfigurations);$(FxCopDirOption);$(ReferencePathOption);$(CodeAnalysisOption);
  1117.                              VCBuildOverride=$(VsPropsFile);VCBuildAdditionalLibPaths=$(VCBuildAdditionalLibPaths);VCBuildAdditionalOptions=$(VCBuildAdditionalOptions);VCBuildToolPath=$(VCBuildToolPath);VCBuildUseEnvironment=$(VCBuildUseEnvironment);
  1118.                              TeamBuildConstants=$(TeamBuildConstants);TargetsNotLogged=$(TargetsNotLogged);$(CustomPropertiesForBuild);$(CustomProperties)"
  1119.              Targets="$(Targets)"
  1120.              StopOnFirstFailure="$(StopOnFirstFailure)">
  1121.       <Output TaskParameter="TargetOutputs" ItemName="CompilationOutputs" />
  1122.     </MSBuild>
  1123.  
  1124.     <!-- Add Solution metadata to CompilationOutputs. -->
  1125.     <ItemGroup>
  1126.       <CompilationOutputs>
  1127.         <Solution>$(Solution)</Solution>
  1128.       </CompilationOutputs>
  1129.     </ItemGroup>
  1130.  
  1131.   </Target>
  1132.  
  1133.   <PropertyGroup>
  1134.     <PostBuildDependsOn>
  1135.       GetChangesetsAndUpdateWorkItems;
  1136.     </PostBuildDependsOn>
  1137.   </PropertyGroup>
  1138.   <Target Name="PostBuild"
  1139.           Condition=" '$(SkipPostBuild)'!='true' and '$(IsDesktopBuild)'!='true' "
  1140.           DependsOnTargets="$(PostBuildDependsOn)" />
  1141.  
  1142.   <!-- Override this target to execute custom tasks before associating changesets and updating work items -->
  1143.   <Target Name="BeforeGetChangesetsAndUpdateWorkItems" />
  1144.  
  1145.   <PropertyGroup>
  1146.     <GetChangesetsAndUpdateWorkItemsDependsOn>
  1147.       BeforeGetChangesetsAndUpdateWorkItems;
  1148.       CoreGetChangesetsAndUpdateWorkItems;
  1149.       AfterGetChangesetsAndUpdateWorkItems;
  1150.     </GetChangesetsAndUpdateWorkItemsDependsOn>
  1151.   </PropertyGroup>
  1152.   <!-- Batch target for associating changesets and updating work items -->
  1153.   <Target Name="GetChangesetsAndUpdateWorkItems"
  1154.           DependsOnTargets="$(GetChangesetsAndUpdateWorkItemsDependsOn)" />
  1155.  
  1156.   <!-- Override this target to execute custom tasks after associating changesets and updating work items -->
  1157.   <Target Name="AfterGetChangesetsAndUpdateWorkItems" />
  1158.  
  1159.   <PropertyGroup>
  1160.     <CoreGetChangesetsAndUpdateWorkItemsDependsOn />
  1161.   </PropertyGroup>
  1162.   <Target Name="CoreGetChangesetsAndUpdateWorkItems"
  1163.           Condition=" '$(SkipGetChangesetsAndUpdateWorkItems)'!='true' "
  1164.           DependsOnTargets="$(CoreGetChangesetsAndUpdateWorkItemsDependsOn)">
  1165.  
  1166.     <GenCheckinNotesUpdateWorkItems
  1167.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1168.           BuildUri="$(BuildUri)"
  1169.           BuildNumber="$(BuildNumber)"
  1170.           CurrentLabel="$(LabelName)@$(LabelScope)"
  1171.           LastLabel="$(LastGoodBuildLabel)"
  1172.           UpdateWorkItems="$(UpdateAssociatedWorkItems)"
  1173.           ContinueOnError="true">
  1174.       <Output TaskParameter="AssociatedChangesets" ItemName="AssociatedChangesets" />
  1175.     </GenCheckinNotesUpdateWorkItems>
  1176.  
  1177.   </Target>
  1178.  
  1179.   <!-- Override this target to execute custom tasks before running tests -->
  1180.   <Target Name="BeforeTest" />
  1181.  
  1182.   <PropertyGroup>
  1183.     <TestDependsOn>
  1184.       BeforeTest;
  1185.       CoreTest;
  1186.       AfterTest;
  1187.     </TestDependsOn>
  1188.   </PropertyGroup>
  1189.   <!-- Batch target for running tests -->
  1190.   <Target Name="Test"
  1191.           DependsOnTargets="$(TestDependsOn)" />
  1192.  
  1193.   <!-- Override this target to execute custom tasks after running tests -->
  1194.   <Target Name="AfterTest" />
  1195.  
  1196.   <PropertyGroup>
  1197.     <CoreTestDependsOn/>
  1198.   </PropertyGroup>
  1199.   <!-- Run tests, if $(RunTest) is true -->
  1200.   <Target Name="CoreTest"
  1201.           DependsOnTargets="$(CoreTestDependsOn)" >
  1202.  
  1203.     <!-- Pass in all properties that users might want during the course of the test targets. -->
  1204.     <MSBuild Condition=" '$(RunTest)' == 'true' "
  1205.              Projects="$(MSBuildProjectFile)"
  1206.              Properties="BuildAgentName=$(BuildAgentName);BuildAgentUri=$(BuildAgentUri);BuildDefinitionName=$(BuildDefinitionName);BuildDefinitionUri=$(BuildDefinitionUri);
  1207.                          BuildDirectory=$(BuildDirectory);BuildNumber=$(BuildNumber);CompilationStatus=$(CompilationStatus);CompilationSuccess=$(CompilationSuccess);
  1208.                          ConfigurationFolderUri=$(ConfigurationFolderUri);DropLocation=$(DropLocation);
  1209.                          FullLabelName=$(FullLabelName);LastChangedBy=$(LastChangedBy);LastChangedOn=$(LastChangedOn);LogLocation=$(LogLocation);
  1210.                          MachineName=$(MachineName);MaxProcesses=$(MaxProcesses);Port=$(Port);Quality=$(Quality);Reason=$(Reason);RequestedBy=$(RequestedBy);RequestedFor=$(RequestedFor);
  1211.                          SourceGetVersion=$(SourceGetVersion);StartTime=$(StartTime);Status=$(Status);TeamProject=$(TeamProject);TestStatus=$(TestStatus);
  1212.                          TestSuccess=$(TestSuccess);WorkspaceName=$(WorkspaceName);WorkspaceOwner=$(WorkspaceOwner);
  1213.                          SolutionRoot=$(SolutionRoot);BinariesRoot=$(BinariesRoot);TestResultsRoot=$(TestResultsRoot)"
  1214.              Targets="RunTest"
  1215.              StopOnFirstFailure="$(StopOnFirstFailure)">
  1216.       <Output TaskParameter="TargetOutputs" ItemName="TestOutputs" />
  1217.     </MSBuild>
  1218.  
  1219.     <!-- Refresh the test properties so that they can be used in AfterTest, etc. -->
  1220.     <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1221.                         BuildUri="$(BuildUri)"
  1222.                         Condition=" '$(IsDesktopBuild)' != 'true' ">
  1223.       <Output TaskParameter="TestStatus" PropertyName="TestStatus" />
  1224.       <Output TaskParameter="TestSuccess" PropertyName="TestSuccess" />
  1225.     </GetBuildProperties>
  1226.  
  1227.     <OnError ExecuteTargets="SetTestBreakProperties;OnBuildBreak" />
  1228.  
  1229.   </Target>
  1230.  
  1231.   <PropertyGroup>
  1232.     <RunTestDependsOn>
  1233.       ComputeConfigurationList;
  1234.     </RunTestDependsOn>
  1235.   </PropertyGroup>
  1236.   <!-- Run tests -->
  1237.   <Target Name="RunTest"
  1238.           DependsOnTargets="$(RunTestDependsOn)"
  1239.           Outputs="@(TestOutputs)">
  1240.  
  1241.     <MakeDir
  1242.           Directories="$(TestResultsRoot)"
  1243.           Condition="!Exists('$(TestResultsRoot)')" />
  1244.  
  1245.     <MSBuild Projects="@(ConfigurationList)"
  1246.              Properties="TreatTestFailureAsBuildFailure=$(TreatTestFailureAsBuildFailure)"
  1247.              Targets="TestConfiguration"
  1248.              StopOnFirstFailure="$(StopOnFirstFailure)">
  1249.       <Output TaskParameter="TargetOutputs" ItemName="TestOutputs" />
  1250.     </MSBuild>
  1251.  
  1252.   </Target>
  1253.  
  1254.   <!-- Override this target to execute custom tasks before the testing of an individual configuration -->
  1255.   <Target Name="BeforeTestConfiguration" />
  1256.  
  1257.   <PropertyGroup>
  1258.     <TestConfigurationDependsOn>
  1259.       BeforeTestConfiguration;
  1260.       CoreTestConfiguration;
  1261.       AfterTestConfiguration;
  1262.     </TestConfigurationDependsOn>
  1263.   </PropertyGroup>
  1264.   <!-- Batch target for individual configuration testing -->
  1265.   <Target Name="TestConfiguration"
  1266.           DependsOnTargets="$(TestConfigurationDependsOn)"
  1267.           Outputs="@(TestOutputs)" />
  1268.  
  1269.   <!-- Override this target to execute custom tasks after the testing of an individual configuration -->
  1270.   <Target Name="AfterTestConfiguration" />
  1271.  
  1272.   <Target Name="ResolveTestFilesForEndToEndIteration">
  1273.  
  1274.     <WorkspaceItemConverterTask
  1275.           Condition=" '@(MetaDataFile)' != '' and '$(IsDesktopBuild)' != 'true' "
  1276.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1277.           BuildUri="$(BuildUri)"
  1278.           WorkspaceName="$(WorkspaceName)"
  1279.           WorkspaceOwner="$(WorkspaceOwner)"
  1280.           ServerItems="@(MetaDataFile)">
  1281.       <Output TaskParameter="LocalItems" ItemName="LocalMetaDataFile" />
  1282.     </WorkspaceItemConverterTask>
  1283.  
  1284.     <WorkspaceItemConverterTask
  1285.           Condition=" '@(TestContainer)' != '' and '$(IsDesktopBuild)' != 'true' "
  1286.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1287.           BuildUri="$(BuildUri)"
  1288.           WorkspaceName="$(WorkspaceName)"
  1289.           WorkspaceOwner="$(WorkspaceOwner)"
  1290.           ServerItems="@(TestContainer)">
  1291.       <Output TaskParameter="LocalItems" ItemName="TempTestContainer" />
  1292.     </WorkspaceItemConverterTask>
  1293.  
  1294.     <!-- Expand TempTestContainer wild cards to create LocalTestContainer item that will be used later (this will replace * and ? with matching file paths)-->
  1295.     <CreateItem Include="@(TempTestContainer)" Condition=" '$(IsDesktopBuild)' != 'true' ">
  1296.       <Output TaskParameter="Include" ItemName="LocalTestContainer"/>
  1297.     </CreateItem>
  1298.  
  1299.     <CreateItem Include="@(TestContainer)" Condition=" '$(IsDesktopBuild)' == 'true' ">
  1300.       <Output TaskParameter="Include" ItemName="LocalTestContainer"/>
  1301.     </CreateItem>
  1302.  
  1303.   </Target>
  1304.  
  1305.   <!-- Test an individual configuration -->
  1306.   <PropertyGroup>
  1307.     <CoreTestConfigurationDependsOn>
  1308.       ResolveTestFilesForEndToEndIteration;
  1309.     </CoreTestConfigurationDependsOn>
  1310.   </PropertyGroup>
  1311.   <Target Name="CoreTestConfiguration"
  1312.           DependsOnTargets="$(CoreTestConfigurationDependsOn)"
  1313.           Outputs="@(TestOutputs)">
  1314.  
  1315.     <Warning Condition=" '$(V8TestToolsTask)'=='true' and '$(TestNames)'!='' "
  1316.              Text="Warning: The TestNames property cannot be used in in combination with the V8 TestToolsTask and will be ignored." />
  1317.     <Warning Condition=" '$(V8TestToolsTask)'=='true' and '@(LocalTestContainer)' != '' "
  1318.              Text="Warning: The TestContainer item group cannot be used in combination with the V8 TestToolsTask and will be ignored." />
  1319.  
  1320.     <PropertyGroup>
  1321.       <ContinueOnTestError Condition=" '$(StopOnTestFailure)' != 'true' ">true</ContinueOnTestError>
  1322.       <ContinueOnTestError Condition=" '$(StopOnTestFailure)' == 'true' ">false</ContinueOnTestError>
  1323.     </PropertyGroup>
  1324.    
  1325.     <!-- 10.0 MetaDataFile tests for non-desktop builds. -->
  1326.     <TestToolsTask
  1327.           Condition=" '$(ProjectFileVersion)' != '2' and '$(IsDesktopBuild)'!='true' and '$(V8TestToolsTask)'!='true' and '%(LocalMetaDataFile.Identity)' != '' "
  1328.           ToolPath="$(TestToolsTaskToolPath)"
  1329.           BuildFlavor="$(Configuration)"
  1330.           BuildUri="$(BuildUri)"
  1331.           Platform="$(Platform)"
  1332.           SearchPathRoot="$(OutDir)"
  1333.           PathToResultsFilesRoot="$(TestResultsRoot)"
  1334.           MetaDataFile="%(LocalMetaDataFile.Identity)"
  1335.           RunConfigFile="$(RunConfigFile)"
  1336.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1337.           TestLists="%(LocalMetaDataFile.TestList)"
  1338.           TeamProject="$(TeamProject)"
  1339.           TestNames="$(TestNames)"
  1340.           Publish="$(PublishTestResults)"
  1341.           ContinueOnError="$(ContinueOnTestError)" />
  1342.  
  1343.     <!-- 10.0 TestContainer tests for non-desktop builds. -->
  1344.     <TestToolsTask
  1345.             Condition=" '$(ProjectFileVersion)' != '2' and '$(IsDesktopBuild)'!='true' and '$(V8TestToolsTask)'!='true' and '@(LocalTestContainer)' != '' "
  1346.             ToolPath="$(TestToolsTaskToolPath)"
  1347.             BuildFlavor="$(Configuration)"
  1348.             BuildUri="$(BuildUri)"
  1349.             Platform="$(Platform)"
  1350.             SearchPathRoot="$(OutDir)"
  1351.             PathToResultsFilesRoot="$(TestResultsRoot)"
  1352.             RunConfigFile="$(RunConfigFile)"
  1353.             TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1354.             TestContainers="@(LocalTestContainer)"
  1355.             TeamProject="$(TeamProject)"
  1356.             TestNames="$(TestNames)"
  1357.             Publish="$(PublishTestResults)"
  1358.             ContinueOnError="$(ContinueOnTestError)" />
  1359.  
  1360.     <!-- 9.0 MetaDataFile tests for non-desktop builds. -->
  1361.     <TestToolsTask
  1362.           Condition=" '$(ProjectFileVersion)' == '2' and '$(IsDesktopBuild)'!='true' and '$(V8TestToolsTask)'!='true' and '%(LocalMetaDataFile.Identity)' != '' "
  1363.           BuildFlavor="$(Configuration)"
  1364.           Platform="$(Platform)"
  1365.           PublishServer="$(TeamFoundationServerUrl)"
  1366.           PublishBuild="$(BuildUri)"
  1367.           SearchPathRoot="$(OutDir)"
  1368.           PathToResultsFilesRoot="$(TestResultsRoot)"
  1369.           MetaDataFile="%(LocalMetaDataFile.Identity)"
  1370.           RunConfigFile="$(RunConfigFile)"
  1371.           TestLists="%(LocalMetaDataFile.TestList)"
  1372.           TeamProject="$(TeamProject)"
  1373.           TestNames="$(TestNames)"
  1374.           ContinueOnError="$(ContinueOnTestError)" />
  1375.  
  1376.     <!-- 8.0 MetaDataFile tests for non-desktop builds. -->
  1377.     <TestToolsTask
  1378.           Condition=" '$(IsDesktopBuild)'!='true' and '$(V8TestToolsTask)'=='true' and '%(LocalMetaDataFile.Identity)' != '' "
  1379.           BuildFlavor="$(Configuration)"
  1380.           Platform="$(Platform)"
  1381.           PublishServer="$(TeamFoundationServerUrl)"
  1382.           PublishBuild="$(BuildNumber)"
  1383.           SearchPathRoot="$(OutDir)"
  1384.           PathToResultsFilesRoot="$(TestResultsRoot)"
  1385.           MetaDataFile="%(LocalMetaDataFile.Identity)"
  1386.           RunConfigFile="$(RunConfigFile)"
  1387.           TestLists="%(LocalMetaDataFile.TestList)"
  1388.           TeamProject="$(TeamProject)"
  1389.           ContinueOnError="$(ContinueOnTestError)" />
  1390.  
  1391.     <!-- 9.0 TestContainer tests for non-desktop builds. -->
  1392.     <TestToolsTask
  1393.             Condition=" '$(ProjectFileVersion)' == '2' and '$(IsDesktopBuild)'!='true' and '$(V8TestToolsTask)'!='true' and '@(LocalTestContainer)' != '' "
  1394.             BuildFlavor="$(Configuration)"
  1395.             Platform="$(Platform)"
  1396.             PublishServer="$(TeamFoundationServerUrl)"
  1397.             PublishBuild="$(BuildUri)"
  1398.             SearchPathRoot="$(OutDir)"
  1399.             PathToResultsFilesRoot="$(TestResultsRoot)"
  1400.             RunConfigFile="$(RunConfigFile)"
  1401.             TestContainers="@(LocalTestContainer)"
  1402.             TeamProject="$(TeamProject)"
  1403.             TestNames="$(TestNames)"
  1404.             ContinueOnError="$(ContinueOnTestError)" />
  1405.  
  1406.     <!-- 10.0/9.0 MetaDataFile tests for desktop builds. -->
  1407.     <TestToolsTask
  1408.           Condition=" '$(IsDesktopBuild)'=='true' and '$(V8TestToolsTask)'!='true' and '%(MetaDataFile.Identity)' != '' "
  1409.           ToolPath="$(TestToolsTaskToolPath)"
  1410.           SearchPathRoot="$(OutDir)"
  1411.           PathToResultsFilesRoot="$(TestResultsRoot)"
  1412.           MetaDataFile="%(MetaDataFile.Identity)"
  1413.           RunConfigFile="$(RunConfigFile)"
  1414.           TestLists="%(MetaDataFile.TestList)"
  1415.           TestNames="$(TestNames)"
  1416.           ContinueOnError="$(ContinueOnTestError)" />
  1417.  
  1418.     <!-- 8.0 MetaDataFile tests for desktop builds. -->
  1419.     <TestToolsTask
  1420.           Condition=" '$(IsDesktopBuild)'=='true' and '$(V8TestToolsTask)'=='true' and '%(MetaDataFile.Identity)' != '' "
  1421.           SearchPathRoot="$(OutDir)"
  1422.           PathToResultsFilesRoot="$(TestResultsRoot)"
  1423.           MetaDataFile="%(MetaDataFile.Identity)"
  1424.           RunConfigFile="$(RunConfigFile)"
  1425.           TestLists="%(MetaDataFile.TestList)"
  1426.           ContinueOnError="$(ContinueOnTestError)" />
  1427.  
  1428.     <!-- 10.0/9.0 TestContainer tests for desktop builds. -->
  1429.     <TestToolsTask
  1430.             Condition=" '$(IsDesktopBuild)'=='true' and '$(V8TestToolsTask)'!='true' and '@(LocalTestContainer)' != '' "
  1431.             ToolPath="$(TestToolsTaskToolPath)"
  1432.             SearchPathRoot="$(OutDir)"
  1433.             PathToResultsFilesRoot="$(TestResultsRoot)"
  1434.             RunConfigFile="$(RunConfigFile)"
  1435.             TestContainers="@(LocalTestContainer)"
  1436.             TestNames="$(TestNames)"
  1437.             ContinueOnError="$(ContinueOnTestError)" />
  1438.  
  1439.     <!-- Populate TestOutputs with MetaData Files and Test Containers. -->
  1440.     <ItemGroup>
  1441.       <!-- TestContainer tests for non-desktop and desktop builds. -->
  1442.       <TestOutputs Condition=" '@(LocalTestContainer)' != '' "
  1443.                    Include="%(LocalTestContainer.Identity)">
  1444.         <Platform>$(Platform)</Platform>
  1445.         <Configuration>$(Configuration)</Configuration>
  1446.       </TestOutputs>
  1447.       <!-- MetaDataFile tests for non-desktop builds. -->
  1448.       <TestOutputs Condition=" '$(IsDesktopBuild)'!='true' and '%(LocalMetaDataFile.Identity)' != '' "
  1449.                    Include="%(LocalMetaDataFile.Identity)">
  1450.         <Platform>$(Platform)</Platform>
  1451.         <Configuration>$(Configuration)</Configuration>
  1452.       </TestOutputs>
  1453.       <!-- MetaDataFile tests for desktop builds. -->
  1454.       <TestOutputs Condition=" '$(IsDesktopBuild)'=='true' and '%(MetaDataFile.Identity)' != '' "
  1455.                    Include="%(MetaDataFile.Identity)">
  1456.         <Platform>$(Platform)</Platform>
  1457.         <Configuration>$(Configuration)</Configuration>
  1458.       </TestOutputs>
  1459.     </ItemGroup>
  1460.  
  1461.   </Target>
  1462.  
  1463.   <!-- Override this target to generate documentation. -->
  1464.   <Target Name="GenerateDocumentation" />
  1465.  
  1466.   <!-- Override this target to package all binaries for deployment. -->
  1467.   <Target Name="PackageBinaries" />
  1468.  
  1469.   <!-- Override this target to execute custom tasks before copying files to the drop location -->
  1470.   <Target Name="BeforeDropBuild" />
  1471.  
  1472.   <PropertyGroup>
  1473.     <DropBuildDependsOn>
  1474.       BeforeDropBuild;
  1475.       CoreDropBuild;
  1476.       AfterDropBuild;
  1477.     </DropBuildDependsOn>
  1478.   </PropertyGroup>
  1479.   <!-- Batch target for copying files to the drop location -->
  1480.   <Target Name="DropBuild"
  1481.           DependsOnTargets="$(DropBuildDependsOn)" />
  1482.  
  1483.   <!-- Override this target to execute custom tasks after copying files to the drop location -->
  1484.   <Target Name="AfterDropBuild" />
  1485.  
  1486.   <PropertyGroup>
  1487.     <CoreDropBuildDependsOn />
  1488.   </PropertyGroup>
  1489.   <Target Name="CoreDropBuild"
  1490.           Condition=" '$(SkipDropBuild)'!='true' and '$(IsDesktopBuild)'!='true' "
  1491.           DependsOnTargets="$(CoreDropBuildDependsOn)" >
  1492.  
  1493.     <ItemGroup>
  1494.       <FilesToCopy Include="$(BinariesRoot)\**\*.*" />
  1495.     </ItemGroup>
  1496.  
  1497.     <Copy Condition=" '$(BuildBreak)'!='true' "
  1498.           SourceFiles="@(FilesToCopy)"
  1499.           DestinationFiles="@(FilesToCopy ->'$(DropLocation)\$(BuildNumber)\%(RecursiveDir)%(Filename)%(Extension)')" />
  1500.  
  1501.     <Copy Condition=" '$(BuildBreak)'=='true' "
  1502.           SourceFiles="@(FilesToCopy)"
  1503.           DestinationFiles="@(FilesToCopy ->'$(DropLocation)\$(BuildNumber)\%(RecursiveDir)%(Filename)%(Extension)')"
  1504.           ContinueOnError="true" />
  1505.  
  1506.   </Target>
  1507.  
  1508.   <!-- Override this target to execute custom tasks before reverting the workspace -->
  1509.   <Target Name="BeforeRevertWorkspace" />
  1510.  
  1511.   <PropertyGroup>
  1512.     <RevertWorkspaceDependsOn>
  1513.       BeforeRevertWorkspace;
  1514.       CoreRevertWorkspace;
  1515.       AfterRevertWorkspace;
  1516.     </RevertWorkspaceDependsOn>
  1517.   </PropertyGroup>
  1518.   <!-- Batch target for reverting the workspace after a shelveset build -->
  1519.   <Target Name="RevertWorkspace"
  1520.           DependsOnTargets="$(RevertWorkspaceDependsOn)" />
  1521.  
  1522.   <!-- Override this target to execute custom tasks after reverting the workspace -->
  1523.   <Target Name="AfterRevertWorkspace" />
  1524.  
  1525.   <PropertyGroup>
  1526.     <CoreRevertWorkspaceDependsOn />
  1527.   </PropertyGroup>
  1528.   <Target Name="CoreRevertWorkspace"
  1529.           Condition=" '$(IsDesktopBuild)' != 'true' and '$(ProjectFileVersion)' != '2' and ('$(Reason)' == 'CheckinShelveset' or '$(Reason)' == 'ValidateShelveset') "
  1530.           DependsOnTargets="$(CoreRevertWorkspaceDependsOn)">
  1531.  
  1532.     <RevertWorkspaceTask TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1533.                          BuildUri="$(BuildUri)"
  1534.                          WorkspaceName="$(WorkspaceName)"
  1535.                          WorkspaceOwner="$(WorkspaceOwner)" />
  1536.    
  1537.   </Target>
  1538.  
  1539.   <!-- Set the TestBreak property to true. -->
  1540.   <Target Name="SetTestBreakProperties">
  1541.  
  1542.     <PropertyGroup>
  1543.       <TestBreak>true</TestBreak>
  1544.     </PropertyGroup>
  1545.  
  1546.     <!-- Refresh the test properties so that they can be used in AfterTestBreak, etc. -->
  1547.     <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1548.                         BuildUri="$(BuildUri)"
  1549.                         Condition=" '$(IsDesktopBuild)' != 'true' ">
  1550.       <Output TaskParameter="TestStatus" PropertyName="TestStatus" />
  1551.       <Output TaskParameter="TestSuccess" PropertyName="TestSuccess" />
  1552.     </GetBuildProperties>
  1553.  
  1554.   </Target>
  1555.  
  1556.   <!-- Set the BuildBreak property to true. -->
  1557.   <Target Name="SetBuildBreakProperties">
  1558.    
  1559.     <PropertyGroup>
  1560.       <BuildBreak>true</BuildBreak>
  1561.     </PropertyGroup>
  1562.  
  1563.     <!-- Refresh the compilation properties so that they can be used in AfterBuildBreak, etc. -->
  1564.     <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1565.                         BuildUri="$(BuildUri)"
  1566.                         Condition=" '$(IsDesktopBuild)' != 'true' ">
  1567.       <Output TaskParameter="CompilationStatus" PropertyName="CompilationStatus" />
  1568.       <Output TaskParameter="CompilationSuccess" PropertyName="CompilationSuccess" />
  1569.     </GetBuildProperties>
  1570.  
  1571.   </Target>
  1572.  
  1573.   <!-- Override this target to execute custom tasks before the BuildBreak target -->
  1574.   <Target Name="BeforeOnBuildBreak" />
  1575.  
  1576.   <PropertyGroup>
  1577.     <OnBuildBreakDependsOn>
  1578.       BeforeOnBuildBreak;
  1579.       CoreOnBuildBreak;
  1580.       AfterOnBuildBreak;
  1581.     </OnBuildBreakDependsOn>
  1582.   </PropertyGroup>
  1583.   <Target Name="OnBuildBreak"
  1584.           Condition=" '$(IsDesktopBuild)'!='true' "
  1585.           DependsOnTargets="$(OnBuildBreakDependsOn)" />
  1586.  
  1587.   <!-- Override this target to execute custom tasks after the BuildBreak target -->
  1588.   <Target Name="AfterOnBuildBreak" />
  1589.  
  1590.   <PropertyGroup>
  1591.     <CoreOnBuildBreakDependsOn>
  1592.       GetChangesetsOnBuildBreak;
  1593.       DropBuild;
  1594.       CreateWorkItem;
  1595.       RevertWorkspace;
  1596.     </CoreOnBuildBreakDependsOn>
  1597.   </PropertyGroup>
  1598.   <Target Name="CoreOnBuildBreak"
  1599.           DependsOnTargets="$(CoreOnBuildBreakDependsOn)" />
  1600.  
  1601.   <!-- Override the target to execute custom tasks before associating changesets on a build break -->
  1602.   <Target Name="BeforeGetChangesetsOnBuildBreak" />
  1603.  
  1604.   <PropertyGroup>
  1605.     <GetChangesetsOnBuildBreakDependsOn>
  1606.       BeforeGetChangesetsOnBuildBreak;
  1607.       CoreGetChangesetsOnBuildBreak;
  1608.       AfterGetChangesetsOnBuildBreak;
  1609.     </GetChangesetsOnBuildBreakDependsOn>
  1610.   </PropertyGroup>
  1611.   <!-- Batch target for associating changesets on a build break -->
  1612.   <Target Name="GetChangesetsOnBuildBreak"
  1613.           Condition=" '$(BuildBreak)' == 'true' "
  1614.           DependsOnTargets="$(GetChangesetsOnBuildBreakDependsOn)" />
  1615.  
  1616.   <!-- Override the target to execute custom tasks after associating changesets on a build break -->
  1617.   <Target Name="AfterGetChangesetsOnBuildBreak" />
  1618.  
  1619.   <PropertyGroup>
  1620.     <CoreGetChangesetsOnBuildBreakDependsOn />
  1621.   </PropertyGroup>
  1622.   <Target Name="CoreGetChangesetsOnBuildBreak"
  1623.           Condition=" '$(IsDesktopBuild)'!='true' and
  1624.                       '$(SkipGetChangesetsAndUpdateWorkItems)'!='true' "
  1625.           DependsOnTargets="$(CoreGetChangesetsOnBuildBreakDependsOn)">
  1626.  
  1627.     <GenCheckinNotesUpdateWorkItems
  1628.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1629.           BuildUri="$(BuildUri)"
  1630.           BuildNumber="$(BuildNumber)"
  1631.           CurrentLabel="$(LabelName)@$(LabelScope)"
  1632.           LastLabel="$(LastGoodBuildLabel)"
  1633.           UpdateWorkItems="$(UpdateAssociatedWorkItemsOnBuildBreak)"
  1634.           ContinueOnError="true" />
  1635.  
  1636.   </Target>
  1637.  
  1638.   <!-- Override this target to execute custom tasks before work item creation -->
  1639.   <Target Name="BeforeCreateWorkItem" />
  1640.  
  1641.   <PropertyGroup>
  1642.     <CreateWorkItemDependsOn>
  1643.       BeforeCreateWorkItem;
  1644.       CoreCreateWorkItem;
  1645.       AfterCreateWorkItem;
  1646.     </CreateWorkItemDependsOn>
  1647.   </PropertyGroup>
  1648.   <!-- Batch target for work item creation -->
  1649.   <Target Name="CreateWorkItem"
  1650.           DependsOnTargets="$(CreateWorkItemDependsOn)"/>
  1651.  
  1652.   <!-- Override this target to execute custom tasks after work item creation-->
  1653.   <Target Name="AfterCreateWorkItem" />
  1654.  
  1655.   <PropertyGroup>
  1656.     <CoreCreateWorkItemDependsOn />
  1657.   </PropertyGroup>
  1658.   <Target Name="CoreCreateWorkItem"
  1659.           Condition=" '$(SkipWorkItemCreation)'!='true' and '$(IsDesktopBuild)'!='true' "
  1660.           DependsOnTargets="$(CoreCreateWorkItemDependsOn)">
  1661.  
  1662.     <PropertyGroup>
  1663.       <WorkItemTitle>$(WorkItemTitle) $(BuildNumber)</WorkItemTitle>
  1664.       <BuildLogText>$(BuildlogText) &lt;a href='file:///$(DropLocation)\$(BuildNumber)\BuildLog.txt'&gt;$(DropLocation)\$(BuildNumber)\BuildLog.txt&lt;/a &gt;.</BuildLogText>
  1665.       <ErrorWarningLogText Condition="!Exists('$(MSBuildProjectDirectory)\ErrorsWarningsLog.txt')"></ErrorWarningLogText>
  1666.       <ErrorWarningLogText Condition="Exists('$(MSBuildProjectDirectory)\ErrorsWarningsLog.txt')">$(ErrorWarningLogText) &lt;a href='file:///$(DropLocation)\$(BuildNumber)\ErrorsWarningsLog.txt'&gt;$(DropLocation)\$(BuildNumber)\ErrorsWarningsLog.txt&lt;/a &gt;.</ErrorWarningLogText>
  1667.       <WorkItemDescription>$(DescriptionText) %3CBR%2F%3E $(BuildlogText) %3CBR%2F%3E $(ErrorWarningLogText)</WorkItemDescription>
  1668.     </PropertyGroup>
  1669.    
  1670.     <CreateNewWorkItem
  1671.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1672.           BuildUri="$(BuildUri)"
  1673.           BuildNumber="$(BuildNumber)"
  1674.           Description="$(WorkItemDescription)"
  1675.           TeamProject="$(TeamProject)"
  1676.           Title="$(WorkItemTitle)"
  1677.           WorkItemFieldValues="$(WorkItemFieldValues)"
  1678.           WorkItemType="$(WorkItemType)"
  1679.           ContinueOnError="true" />
  1680.  
  1681.   </Target>
  1682.  
  1683.   <!-- Compute the list of all Platform / Configuration combinations -->
  1684.   <Target Name="ComputeConfigurationList">
  1685.  
  1686.     <ItemGroup>
  1687.       <!-- ConfigurationList for any Platform but Any CPU -->
  1688.       <ConfigurationList Condition=" '%(ConfigurationToBuild.PlatformToBuild)' != 'Any CPU' " Include="$(MSBuildProjectFile)">
  1689.         <Properties>Configuration=%(ConfigurationToBuild.FlavorToBuild);Platform=%(ConfigurationToBuild.PlatformToBuild);TeamBuildOutDir=$(BinariesRoot)\%(ConfigurationToBuild.PlatformToBuild)\%(ConfigurationToBuild.FlavorToBuild)\;TeamBuildPublishDir=$(BinariesRoot)\%(ConfigurationToBuild.PlatformToBuild)\%(ConfigurationToBuild.FlavorToBuild)\\cf1 </Properties>
  1690.       </ConfigurationList>
  1691.       <!-- ConfigurationList for Any CPU Platform -->
  1692.       <ConfigurationList Condition=" '%(ConfigurationToBuild.PlatformToBuild)' == 'Any CPU' " Include="$(MSBuildProjectFile)">
  1693.         <Properties>Configuration=%(ConfigurationToBuild.FlavorToBuild);Platform=%(ConfigurationToBuild.PlatformToBuild);TeamBuildOutDir=$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\;TeamBuildPublishDir=$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\\cf1 </Properties>
  1694.       </ConfigurationList>
  1695.     </ItemGroup>
  1696.    
  1697.   </Target>
  1698.  
  1699.   <Target Name="ResolveSolutionPathsForDesktopBuild"
  1700.           Condition=" '$(IsDesktopBuild)' == 'true' ">
  1701.  
  1702.     <ItemGroup>
  1703.       <LocalSolutionToBuild Include="@(SolutionToBuild)" />
  1704.       <LocalSolutionToPublish Include="@(SolutionToPublish)" />
  1705.     </ItemGroup>
  1706.  
  1707.   </Target>
  1708.  
  1709.   <Target Name="ResolveSolutionPathsForEndToEndIteration"
  1710.           Condition=" '$(IsDesktopBuild)' != 'true' ">
  1711.  
  1712.     <WorkspaceItemConverterTask
  1713.           Condition=" '@(SolutionToBuild)' != '' "
  1714.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1715.           BuildUri="$(BuildUri)"
  1716.           WorkspaceName="$(WorkspaceName)"
  1717.           WorkspaceOwner="$(WorkspaceOwner)"
  1718.           ServerItems="@(SolutionToBuild)">
  1719.       <Output TaskParameter="LocalItems" ItemName="LocalSolutionToBuild" />
  1720.     </WorkspaceItemConverterTask>
  1721.  
  1722.     <WorkspaceItemConverterTask
  1723.           Condition=" '@(SolutionToPublish)' != '' "
  1724.           TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1725.           BuildUri="$(BuildUri)"
  1726.           WorkspaceName="$(WorkspaceName)"
  1727.           WorkspaceOwner="$(WorkspaceOwner)"
  1728.           ServerItems="@(SolutionToPublish)">
  1729.       <Output TaskParameter="LocalItems" ItemName="LocalSolutionToPublish" />
  1730.     </WorkspaceItemConverterTask>
  1731.  
  1732.   </Target>
  1733.  
  1734.  
  1735.   <!-- Compute the list of all Solutions (for each Platform / Configuration combination) -->
  1736.   <PropertyGroup>
  1737.     <ComputeSolutionListDependsOn>
  1738.       ResolveSolutionPathsForDesktopBuild;
  1739.       ResolveSolutionPathsForEndToEndIteration;
  1740.     </ComputeSolutionListDependsOn>
  1741.   </PropertyGroup>
  1742.   <Target Name="ComputeSolutionList"
  1743.           DependsOnTargets="$(ComputeSolutionListDependsOn)">
  1744.  
  1745.     <ItemGroup>
  1746.       <!-- SolutionToBuild -->
  1747.       <SolutionList Condition=" '@(LocalSolutionToBuild)' != '' " Include="$(MSBuildProjectFile)">
  1748.         <Properties>Solution=%(LocalSolutionToBuild.Identity);Targets=%(LocalSolutionToBuild.Targets);CustomProperties=%(LocalSolutionToBuild.Properties)</Properties>
  1749.       </SolutionList>
  1750.       <!-- Maintain support for SolutionToPublish -->
  1751.       <SolutionList Condition=" '@(LocalSolutionToPublish)' != '' " Include="$(MSBuildProjectFile)">
  1752.         <Properties>Solution=%(LocalSolutionToPublish.Identity);Targets=Publish;CustomProperties=%(LocalSolutionToPublish.Properties)</Properties>
  1753.       </SolutionList>
  1754.     </ItemGroup>
  1755.    
  1756.   </Target>
  1757.  
  1758.  
  1759.   <PropertyGroup>
  1760.     <GetImpactedTestsDependsOn />
  1761.   </PropertyGroup>
  1762.   <Target Name="GetImpactedTests"
  1763.           DependsOnTargets="$(GetImpactedTestsDependsOn)"
  1764.           Condition=" '$(ProjectFileVersion)' != '2' and '$(PerformTestImpactAnalysis)' == 'true' and '$(IsDesktopBuild)' != 'true' and '@(CompilationOutputs)' != '' and '@(AssociatedChangesets)' != '' ">
  1765.  
  1766.     <GetImpactedTests
  1767.       TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
  1768.       BuildUri="$(BuildUri)"
  1769.       BuildBinariesRoot="$(BinariesRoot)"
  1770.       Assemblies="@(CompilationOutputs)"
  1771.       WorkspaceName="$(WorkspaceName)"
  1772.       Changesets="@(AssociatedChangesets)"
  1773.       >
  1774.         <Output TaskParameter="CodeChanges" ItemName="CodeChanges" />
  1775.         <Output TaskParameter="ImpactedTests" ItemName="ImpactedTests" />
  1776.     </GetImpactedTests>
  1777.    
  1778.   </Target>
  1779.  
  1780. </Project>

 

      让我们来完整的阅读并理解这个文件, 比较痛苦而且没有必要. 我们只需要知道:

      1. UsingTask. UsingTask标签表示引入一个指定程序集(AssemblyFile)中的特定功能(TaskName). 作用就是在某处被用来告诉MSBuild引擎执行该指定功能完成一个特定操作.

      2. Targets. 这些Targets就是微软定义的Team Build 流程中的各个步骤. 各个Target的执行顺序, 并不是Target在该文件中的书写顺序, 而是依赖于显式指出的DependsOnTargets属性(Attribute). 这是MSBuild的特性, MSbuild引擎会统揽所有Target及其DependsOnTargets属性, 从而推断出一条唯一的执行顺序(完全无依赖关系的两个Target将以书写顺序执行).

     微软根据自己的判断, 在执行流程的不同阶段提供了许多未实现具体逻辑的空白Target, 并推荐用户来重写这些Target. Microsoft.TeamFoundation.Build.targets文件大多数时候是隐藏在团队项目后面的, 而且微软极不推荐直接修改这个文件因为它会影响所有在这个生成服务器上生成的团队项目的流程. 在我们为一个团队项目添加生成定义的时候, 在我们的团队项目源代码里面$/<TeamProject>/TeamBuildTypes/<TeamBuildDefinitionName>目录下添加了一个名叫<TFSBuild.proj>的文件, 这个文件才是用来提供给我们做自定义修改的. 现在这个未修改的文件中除了一些默认定义的属性和元组外, 只有我们在创建团队生成类型定义时, 指定的需要编译的源代码方案.