Build Incrementally

When you build a large project, it is important that components that have been built previously, and that are still up-to-date, are not rebuilt. If all targets are built every time, each build will take a long time to complete. To enable incremental builds (builds in which only those targets that have not been built before or targets that are out of date are rebuilt), MSBuild can compare the timestamps of the input files with the timestamps of the output files and determine whether to skip, build, or partially rebuild a target. However, there must be a one-to-one mapping between inputs and outputs. You can use transforms to enable targets to identify this direct mapping.
In this example, the "Hello" project uses transforms to create a one-to-one mapping between inputs and outputs in the Resgen task. Also, the Output element is set to automatically use the outputs from the Resgen task as the inputs for the Csc task.

Inputs and Outputs

A target can be built incrementally if the inputs and outputs are specified in the project file. MSBuild can compare the timestamps of the input files with the timestamps of the output files and determine whether to skip, build, or partially rebuild a target. In the following example, if any file in the @(CSFile) item lists is newer than hello.exe, MSBuild will run the target, otherwise it will be skipped:

<Target
Name="Build"
Inputs="@(CSFile)"
Outputs="hello.exe">

<Csc
Sources="@(CSFile)"
OutputAssembly="hello.exe"/>

</Target>

When inputs and outputs are specified in a target, either each output can map to only one input or there can be no direct mapping between the outputs and inputs. In the Csc task above, for example, the output, hello.exe, cannot be mapped to any single input – it depends on all of them.

A target in which there is no direct mapping between the outputs and inputs will always build more often than a target in which each output can map to only one input because MSBuild cannot determine which outputs need to be rebuilt if some of the inputs have changed.

Item List Transforms

To enable a target to identify a direct mapping between its inputs and outputs, MSBuild provides transforms. A transform is a one-to-one conversion of one item list into another. These conversions are not arbitrary, but are limited by special syntax in which all transform modifiers contain the percent symbol followed by a letter, for example %(Filename) and %(Directory). In the following example, a list of .resx files is transformed into a list of .resources files. The %(Filename) transform modifier specifies that each .resources file has the same file name as the corresponding .resx file.

@(RESXFile->'%(Filename).resources')

If, for example, the inputs in the @(RESXFile) list are Form1.resx, Form2.resx, and Form3.resx, the outputs in the transformed list will be Form1.resources, Form2.resources, and Form3.resources.

See the detailed information on transforms in the following MSDN article

Transform Modifiers

MSBuild provides the following transform modifiers (also frequently referred to as Well-known Item Metadata):
* %(RootDir) – the root directory
* %(FullPath) – the full path from the root directory, including the file name and file extension
* %(RelativeDir) - the path specified in item's Include attribute
* %(Identity) - the actual item specified in the Include attribute
* %(Filename) – the file name without the file extension
* %(Directory)– the directory path from, but not including, the root directory
* %(RelativeDir) – the relative directory path
* %(Extension) – the file extension
* %(ReciursiveDir) - the recursive directory (for items specified using ** wildcard, beginning with the wildcard)

See the detailed explanation of well-known metadata in the following MSDN article

A transform can contain multiple modifiers, which can be combined in any order, and modifiers can be repeated in a transform expression. In this example, the name of the directory that contains the files is changed but the files retain the original name (%Filename) and file extension (%Extension). For example, if @(RESXFile) is the item list Project1\Form1.resx, Project1\Form2.resx, and Project1\Form3.resx, the transformed list will be Toolset\Form1.resx, Toolset\Form2.resx, and Toolset\Form3.resx.

@(RESXFile->'Toolset\%(Filename)%(Extension)')

If a target creates outputs that are transforms of the inputs, MSBuild can automatically correlate the inputs and outputs because transforms guarantee a one-to-one mapping between the transformed item list and the original item list. In the Resgen task in the following example, each .resources file maps to the .resx file with the corresponding file name so if any of the .resx files change, the Resgen task will be run only for the changed files and all other files will be skipped.

<Target
Name="Resources"
Inputs="@(RESXFile)"
Outputs="@(RESXFile->'%(Filename).resources')">

<Resgen
Sources="@(RESXFile)" />

</Target>

The Resgen task and other tasks in which you can identify a direct mapping between the outputs and inputs are most suitable for incremental builds, unlike tasks such as Csc and Vbc, which produces one output assembly from a number of inputs.

Building the Project

To build one of these projects from the command line, navigate to the directory that contains the project file and type:

msbuild <file name>.proj

If the directory contains only one file and that file has an extension that ends in "proj", you can type only msbuild because the project file is used automatically by the .NET Build Engine.

Project Files

Download code
These project files contain both the Resources and Build targets. The Resgen and Csc tasks are placed in the Resources and Build targets respectively so that each target can be built incrementally. Using the Output element, the outputs of the Resgen task are identified as Resources, and they are then used as inputs for the Csc task (Inputs="@(*CSFiles*); @(Resources)"). Using the Output element, you can automatically use the outputs from one task as the inputs for another task; you do not have to list the individual items or groups of items in each task.

Although the Resources target can build incrementally, all the outputs from that target are always required as inputs for the Build target. MSBuild automatically provides all the outputs from one target as inputs for another target when you use the Output element. This method can be used with other tasks; it is not only for the Resgen and Csc tasks.

Visual C# example

		    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	

<ItemGroup>
<RESXFile Include="*.resx" />
<TXTFile Include="*.txt" />
		 		    [<CSFile] Include="*.cs" />
	
</ItemGroup>

<Target
		                Name="Resources"
	
Inputs="@(RESXFile); @(TXTFile)"
Outputs="@(RESXFile->'%(Filename).resources'); @(TXTFile->'%(Filename).resources')">

<GenerateResource
Sources="@(RESXFile); @(TXTFile)">
<Output TaskParameter="OutputResources" ItemName="Resources" />
</GenerateResource>

</Target>

<Target
		                Name="Build" DependsOnTargets="Resources"
	
Inputs="@(CSFile); @(Resources)"
Outputs="$(MSBuildProjectName).exe">

<Csc
Sources="@(CSFile)"
Resources="@(Resources)"
OutputAssembly="$(MSBuildProjectName).exe"/>

</Target>

		    </Project>
	
Microsoft Communities