增量生成
生成一个大项目时,不重新生成以前生成过但仍然为最新状态的组件十分重要。 如果每次都生成所有目标,则每次生成都需要很长时间才能完成。 为了启用增量生成(这类生成仅重新生成以前未生成过或已过期的目标),Microsoft 生成引擎 (MSBuild) 可以对输入文件的时间戳和输出文件的时间戳进行比较,并确定是跳过、生成还是部分重新生成某个目标。 但是,在输入和输出之间必须存在一对一映射。 可以使用转换来使目标能够识别此直接映射。 有关转换的详细信息,请参阅转换。
指定输入和输出
如果项目文件中指定了输入和输出,可以增量生成目标。
指定目标的输入和输出
使用
Target
元素的Inputs
和Outputs
属性。 例如:<Target Name="Build" Inputs="@(CSFile)" Outputs="hello.exe">
MSBuild 可将输入文件的时间戳和输出文件的时间戳进行比较,并确定是跳过、生成还是部分重新生成某个目标。 在下面的示例中,如果 @(CSFile)
项列表中有任何文件比 hello.exe 文件新,则 MSBuild 将运行该目标;否则将跳过它:
<Target Name="Build"
Inputs="@(CSFile)"
Outputs="hello.exe">
<Csc
Sources="@(CSFile)"
OutputAssembly="hello.exe"/>
</Target>
当目标中指定了输入和输出时,要么每个输出只能映射到一个输入,要么在输出和输入之间不能有任何直接映射。 例如,在前面的 Csc 任务中,输出 hello.exe 不能映射到任何单一输入,因为它依赖于所有输入。
注意
对于输入和输出之间不存在直接映射的目标,它的生成频率总是比每个输出只能映射到一个输入的目标高,因为如果某些输入发生了更改,MSBuild 无法确定需要重新生成哪些输出。
输出和输入之间存在直接映射的任务(如 LC 任务)最适合增量生成;而 Csc 和 Vbc 等任务则与上述任务存在差异,对于此类任务,多个输入才能产生一个输出程序集。
示例
以下示例使用的项目为假设的帮助系统生成帮助文件。 执行该项目时,会将 .txt 源文件转换为 .content 中间文件,随后,.content 中间文件与 XML 元数据文件合并,生成帮助系统使用的 .help 最终文件。 该项目使用以下假设任务:
GenerateContentFiles
:将 .txt 文件转换成 .content 文件。BuildHelp
:将 .content 文件与 XML 元数据文件合并,生成 .help 最终文件。
该项目通过转换过程来建立 GenerateContentFiles
任务中输入和输出之间的一一映射。 有关详细信息,请参阅转换。 此外,设置了 Output
元素,以便自动将 GenerateContentFiles
任务的输出用作 BuildHelp
任务的输入。
此项目文件包含 Convert
和 Build
目标。 GenerateContentFiles
和 BuildHelp
任务分别位于 Convert
和 Build
目标中,以便可以增量生成每个目标。 通过使用 Output
元素,将 GenerateContentFiles
任务的输出放入 ContentFile
项列表中,这样,就可以将这些输出用作 BuildHelp
任务的输入。 通过按此方法使用 Output
元素,可自动将一个任务的输出作为另一个任务的输入,这样就不必在每个任务中手动列出各个项或项列表。
注意
尽管可增量生成 Convert
目标,但该目标的所有输出始终都需要作为 Build
目标的输入。 使用 Output
元素时,MSBuild 会自动将一个目标中的所有输出作为另一个目标的输入提供。
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup>
<TXTFile Include="*.txt"/>
<XMLFiles Include="\metadata\*.xml"/>
</ItemGroup>
<Target Name = "Convert"
Inputs="@(TXTFile)"
Outputs="@(TXTFile->'%(Filename).content')">
<GenerateContentFiles
Sources = "@(TXTFile)">
<Output TaskParameter = "OutputContentFiles"
ItemName = "ContentFiles"/>
</GenerateContentFiles>
</Target>
<Target Name = "Build" DependsOnTargets = "Convert"
Inputs="@(ContentFiles);@(XMLFiles)"
Outputs="$(MSBuildProjectName).help">
<BuildHelp
ContentFiles = "@(ContentFiles)"
MetadataFiles = "@(XMLFiles)"
OutputFileName = "$(MSBuildProjectName).help"/>
</Target>
</Project>