如果一个目标的输入取决于另一个目标的输出,则必须对目标进行排序。 可以使用这些属性来指定运行目标的顺序:
InitialTargets
。 此属性Project
指定将首先运行的目标,即使目标是在命令行或属性中指定的DefaultTargets
。DefaultTargets
。 此属性Project
指定如果未在命令行上显式指定目标,将运行哪些目标。DependsOnTargets
。 此属性Target
指定在运行此目标之前必须运行的目标。BeforeTargets
和AfterTargets
。 这些Target
属性指定此目标应在指定目标之前或之后运行。
通常情况下,不应依赖声明的顺序来决定哪些任务在其他任务之前运行。
即使生成中的后续目标依赖于它,目标也不会在生成期间运行两次。 运行目标后,它对构建的贡献已完成。
目标可以具有属性 Condition
。 如果指定条件的计算结果为false
,则不会执行目标,并且对构建没有影响。 有关条件的详细信息,请参阅 “条件”。
初始目标
Project元素的InitialTargets
属性指定运行时将首先执行的目标,即使这些目标是在命令行或DefaultTargets
属性中指定的。 初始目标通常用于错误检查。
该属性的值 InitialTargets
可以是以分号分隔的有序目标列表。 以下示例指定 Warm
运行目标,然后 Eject
运行目标。
<Project InitialTargets="Warm;Eject" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
导入的项目可以有自己的 InitialTargets
属性。 所有初始目标聚合在一起并按顺序运行。
有关详细信息,请参阅 “如何:指定要首先生成的目标”。
默认目标
DefaultTargets
是 Project 元素的属性,用于指定在命令行中未明确指定目标时要构建的任务或任务。
属性的值 DefaultTargets
可以是按顺序排列的以分号分隔的默认目标列表。 以下示例指定 Clean
目标会运行,然后 Build
目标会运行。
<Project DefaultTargets="Clean;Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
可以使用命令行上的 -target 开关替代默认目标。 以下示例指定先运行Build
目标,然后运行Report
目标。 以这种方式指定目标时,将忽略任何默认目标。
msbuild -target:Build;Report
如果同时指定了初始目标和默认目标,并且未指定命令行目标,则 MSBuild 首先运行初始目标,然后运行默认目标。
导入的项目可以有自己的 DefaultTargets
属性。 遇到的第一个 DefaultTargets
属性确定将运行哪个默认目标。
有关详细信息,请参阅 “如何:指定要首先生成的目标”。
第一个目标
如果没有初始目标、默认目标或命令行目标,MSBuild 会在项目文件或任何导入的项目文件中运行它遇到的第一个目标。
目标依赖关系
目标可以描述彼此之间的依赖关系。 该 DependsOnTargets
属性指示目标依赖于其他目标。 例如,
<Target Name="Serve" DependsOnTargets="Chop;Cook" />
告知 MSBuild,目标 Serve
取决于目标 Chop
和 Cook
。 MSBuild 运行Chop
目标,然后运行Cook
目标,再运行Serve
目标。
注释
SDK 中的标准目标定义一些DependsOn
属性,这些属性包含作为该目标的依赖项的目标列表(例如,$(BuildDependsOn)
$(CleanDependsOn)
等等)。 例如,
<Target Name="Build" DependsOnTargets="$(BuildDependsOn)">
若要自定义项目,可以使用扩展生成过程的其他自定义目标替代 DependsOn
属性,如 扩展 Visual Studio 生成过程中所述。
BeforeTargets 和 AfterTargets
可以通过使用BeforeTargets
和AfterTargets
属性来指定目标顺序。
请考虑以下脚本。
<Project DefaultTargets="Compile;Link" xmlns="http://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">
<Message Text="Optimizing" />
</Target>
或者,将顺序指定为
<Target Name="Optimize" BeforeTargets="Link">
<Message Text="Optimizing" />
</Target>
指定 这两个目标BeforeTargets
以及 AfterTargets
在同一目标上并不有用。 如下一部分所述,仅在遇到第一个目标时才会导致新目标开始运行。
确定目标构建顺序
MSBuild 确定目标生成顺序,如下所示:
InitialTargets
目标被运行。在命令行中,通过 -target 开关指定的目标会被运行。 如果在命令行上未指定任何目标,则执行
DefaultTargets
目标。 如果两者都不存在,则运行第一个遇到的目标。对目标的
Condition
属性进行评估。Condition
如果该属性存在并计算结果为false
,则该构建目标不会被执行,并且对构建没有进一步影响。其他在
BeforeTargets
或AfterTargets
中列出条件目标的目标,仍会按照规定的顺序执行,而不考虑条件的结果。在执行或跳过目标之前,将运行其
DependsOnTargets
目标,除非将Condition
属性应用于目标并计算结果为false
。注释
如果目标未执行,并且输出项 up-to-date,则视为跳过(请参阅 增量生成)。 此检查在目标内执行任务之前完成,不会影响目标的执行顺序。
在目标被执行或跳过之前,任何在
BeforeTargets
属性中列出此目标的其他目标都会被运行。在执行目标之前,将比较其
Inputs
属性和Outputs
属性。 如果 MSBuild 确定与相应的输入文件或文件相关的任何输出文件已过期,则 MSBuild 将执行目标。 否则,MSBuild 将跳过目标。执行或跳过目标后,任何在某个属性中列出它的其他目标都会运行。