MSBuild 目标

更新:2007 年 11 月

目标以特定的顺序将任务组合到一起,并允许从命令行调用生成过程的各个部分。目标通常被组合为逻辑部分,以允许进行项目文件扩展并提高可读性。例如,一个目标可能会删除输出目录中的所有文件以准备进行生成,而另一个目标可能会编译项目的输入并将它们放到该空目录中。

在项目文件中声明目标

目标是使用 Target 元素在项目文件中声明的。例如,下面的 XML 创建一个名为 Compile 的目标,然后,该目标对 Compile 项集合调用 Csc 任务。

<Target Name="Compile>
    <Csc Sources="@(Compile)" />
</Target>

目标还可以使用 Condition 属性。如果指定的条件计算结果为 False,则目标将不运行,并且 MSBuild 引擎将不会运行 DependsOnTargets 属性中所指定的目标。有关控件的更多信息,请参见 MSBuild 条件

依赖性分析

在更高级的方案中,目标可以描述彼此之间的关系并执行依赖性分析,如果目标是最新的,则允许跳过生成过程的整个部分。通过使用 DependsOnTargets 属性,可以声明目标必须在某个特定目标之前运行。目标运行时,MSBuild 引擎将首先自动运行此属性中列出的任何目标。有关更多信息,请参见如何:增量生成

说明:

目标永远不会在一次生成期间运行两次。一旦运行,则假设目标已经完成了它的工作,即使生成结果中的随后目标依赖于它,它也不会再次运行。

最佳做法

以这种方式划分项目文件,可以更改文件的某些部分而不影响其他部分。例如,生成带资源的项目的一种方式是将 GenerateResourceCsc 任务放到同一个目标中,如:

<Target Name="Build">
    <GenerateResource
        Sources="alpha.resx; beta.txt"
        <Output
            TaskParameter="OutputResources"
            ItemName="Resources"/>
    </GenerateResource>
    <Csc
        Sources="hello.cs"
        Resources="@(Resources)"
        OutputAssembly="hello.exe"/>
</Target>

使用这种方法,能够按照需要生成项目,但是目标会变得很大而且不够灵活。如果以后要添加在 GenerateResourceCsc 之间运行的其他任务,将这些任务全部放在一个目标中将导致项目文件读起来很困难。此外,编写具有这么多任务的大型目标将加大执行好的增量编译(仅重新生成以前未生成的目标和过期的目标)的难度。大型目标还会导致无法运行目标以执行特定的任务。在上面的示例中,无法在不进行编译的情况下生成资源。

一种更好的编写项目文件的方法是使用多个目标并显式地表达它们之间的依赖关系。使用这种方法,还能够分别运行任何目标,并执行更小的任务组,而不是每次生成时在一个目标中运行一长列任务。在本示例中,各个任务分别位于单独的目标中,且 DependsOnTargets 属性指定必须先运行 Resources 目标,才能运行 Build 目标。

<Target Name="Resources">
    <GenerateResource
        Sources="alpha.resx; beta.txt"
        <Output
            TaskParameter="OutputResources"
            ItemName="Resources"/>
    </GenerateResource>
</Target>

<Target Name="Build" DependsOnTargets="Resources">
    <Csc
        Sources="hello.cs"
        Resources="@(Resources)"
        OutputAssembly="hello.exe"/>
</Target>

请参见

任务

如何:指定首先生成的目标

如何:在多个项目文件中使用同一目标

概念

MSBuild 概述

其他资源

MSBuild 概念