ToolsVersion metadata for items used in MSBuild task's

Greetings MSBuilders!

In Visual Studio 2005 you could only target the 2.0 Framework tools. MSBuild targets files which define the build process and MSBuild tasks to use the 1.1 framework tools were not supported . With the help of our CPX team we released MSBee to provide support for .NET 1.1.

With the release of MSBuild Orcas we’ve taken this a step further and made multi-targeting a full-fledged feature. For an overview of this feature check out the blog post Multi-Targeting how does it work

In order to make it easier for our customers to use the Multi-Targeting feature specifically when building multiple projects with different Tools version - in Orcas MSBuild we have introduced a new reserved metadata “ToolsVersion” on items which will be used in the Projects attribute of the MSBuild task. This new metadata is only applicable to items passed in the Projects attribute of the MSBuild task. The purpose of this is to provide our customers a flexible way to pass different ToolsVersion for different projects being built using the MSBuild task. If you use the ToolsVersion attribute of the MSBuild task then it will be applied to all the projects being built using the MSBuild task.

For instance if you are building multiple projects using the MSBuild task where most of them needs to be built with 2.0 framework and tools (compilers) but 1 has to be built using 3.5 because it uses the Windows Presentation Foundation framework your project file would look something like this -

(… represents additional project files)

a.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >

<Target Name=”Build”>

<MSBuild Projects=”a1.proj…” ToolsVersion=”2.0” />

<MSBuild Projects=”a2.proj” ToolsVersion=”3.5” />

</Target>

</Project>

By using the ToolsVersion metadata you can simplify the above to use a single MSBuild task by writing the project file as following:

a.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >

<ItemGroup>

<ProjectToBuild Include=”a1.proj…”>

<ToolsVersion>2.0</ToolsVersion>

</ProjectToBuild>

<ProjectToBuild Include=”a2.proj”>

<ToolsVersion>3.5</ToolsVersion>

</ProjectToBuild>

</ItemGroup>

<Target Name=”Build”>

<MSBuild Projects=”@(ProjectToBuild)” />

</Target>

</Project>

OR

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >

<ItemGroup>

<ProjectToBuild Include=”a1.proj…” />

<ProjectToBuild Include=”a2.proj”>

<ToolsVersion>3.5</ToolsVersion>

</ProjectToBuild>

</ItemGroup>

<Target Name=”Build”>

<MSBuild Projects=”@(ProjectToBuild)” ToolsVersion=”2.0”/>

</Target>

</Project>

One of the benefit we get from these new sets of metadata is to be able to consolidate all projects into a single MSBuild task invocation and not have to do any batching or conditional MSBuild tasks. In doing so it also allows us to parallelize all the projects listed (contained in an item) in the Projects attribute if “BuildInParallel=true” attribute is present in the MSBuild task as we can only parallelize projects within a single invocation of MSBuild task. For additional details on build parallelization you can check out the blog post: Building Projects in parallel.

[ Author: Jay Shrestha, MSBuild Software Engineer ]