如果一个目标的输入取决于另一个目标的输出,则必须对目标进行排序。 可以通过多种方法指定目标的运行顺序。
初始目标
默认目标
第一个目标
目标依赖项
BeforeTargets 和 AfterTargets (MSBuild 4.0)
一个目标决不会在生成过程中运行两次,即便生成中后面的目标依赖于它也是如此。 一个目标运行之后,它对相应生成的作用亦即完成。
目标可能有 Condition 特性。 如果指定条件的计算结果为 false,则目标将不会执行,并且对生成没有影响。 有关条件的更多信息,请参见 MSBuild 条件。
初始目标
Project 元素具有可选的 InitialTargets 特性,该特性的值可以是一个目标列表,其中的目标用分号分隔并已排序。 例如,
<Project InitialTargets="Warm;Eject" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
指定 Warm 目标运行,然后 Eject 目标再运行。
导入的项目可能有自己的 InitialTargets 特性。 所有初始目标都聚合在一起,并按顺序运行。 初始目标通常用于错误检查。
可使用命令行重写初始目标。 例如,
msbuild /target:Build;Report
指定 Build 目标运行,然后 Report 目标再运行。 如果通过此方式指定目标,则会忽略任何初始目标。
有关更多信息,请参见如何:指定首先生成的目标。
默认目标
Project 元素也具有可选的 DefaultTargets 特性,该特性的值可以为由分号分隔的默认目标已排序列表。 例如,
<Project DefaultTargets="Clean;Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
指定 Clean 目标运行,然后 Build 目标再运行。
导入的项目可能有自己的 DefaultTargets 特性。 遇到的第一个 DefaultTargets 特性确定哪个默认目标将运行。
可使用命令行重写默认目标。 例如,
msbuild /target:Build;Report
指定 Build 目标运行,然后 Report 目标再运行。 如果通过此方式指定目标,则会忽略任何默认目标。
如果同时指定了初始目标和默认目标,并且未指定任何命令行目标,则 MSBuild 将先运行初始目标,然后再运行默认目标。
第一个目标
如果没有初始目标、默认目标或命令行目标,则 MSBuild 将先运行它在项目文件或任何导入的项目文件中遇到的第一个目标。
目标依赖项
目标可以描述相互之间的依存关系。 DependsOnTargets 特性指示某个目标依赖于其他目标。 例如,
<Target Name="Serve" DependsOnTargets="Chop;Cook" />
告知 MSBuild,Serve 目标依赖于 Chop 目标和 Cook 目标。 因此,MSBuild 会先运行 Chop 目标,再运行 Cook 目标,然后才运行 Serve 目标。
BeforeTargets 和 AfterTargets
在 MSBuild 4.0 中,可以使用 BeforeTargets 和 AfterTargets 特性指定目标顺序。
请看下面的脚本。
<Project DefaultTargets="Compile;Link" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Compile">
<Message Text="Compiling" />
</Target>
<Target Name="Link">
<Message Text="Linking" />
</Target>
</Project>
要创建在 Compile 目标之后但在 Link 目标之前运行的中间目标 Optimize,请在 Project 元素中的任何位置添加以下目标。
<Target Name="Optimize"
AfterTargets="Compile" BeforeTargets="Link">
<Message Text="Optimizing" />
</Target>
确定目标生成顺序
MSBuild 按如下方式确定目标生成顺序:
运行通过 /target 开关在命令行上指定的目标。 如果未指定目标,则运行 InitialTargets 目标,然后再运行 DefaultTargets 目标。 如果两者均不存在,则运行遇到的第一个目标。
计算目标的 Condition 特性。 如果存在 Condition 特性,并且计算结果为 false,则不执行目标,并且对生成没有进一步影响。
在执行目标之前,将运行其 DependsOnTargets 目标。
在执行目标之前,将运行在 BeforeTargets 特性中列出该目标的任何目标。
在执行目标之前,将比较其 Inputs 特性和 Outputs 特性。 如果 MSBuild 确定任何输出文件相对于其对应的一个或多个输入文件而言已过期,则 MSBuild 将执行目标。 否则,MSBuild 将跳过目标。
执行或跳过目标之后,将运行在 AfterTargets 特性中列出该目标的任何目标。