Using MSBuild to Target Specific .NET Framework Versions
Visual Studio 2008 and MSBuild 3.5 let you target multiple versions of the .NET Framework (versions 2.0, 3.0, and 3.5) when you create or build projects. This feature is called multi-targeting. In MSBuild, multi-targeting is accomplished by using a new attribute, which is named ToolsVersion, on the Project Element (MSBuild).
Toolsets, Target Frameworks, and ToolsVersion
To understand how MSBuild works with Visual Studio 2008, you must know the difference between a Toolset and a Target Framework, and how each relates to the new ToolsVersion attribute. These are all used to determine how MSBuild 3.5 builds your projects.
A Toolset is a matched set of MSBuild tasks, MSBuild targets, and tools that installs with MSBuild and the .NET Framework. A Toolset includes compilers such as csc.exe and vbc.exe, the common targets file (microsoft.common.targets), and the common tasks file (microsoft.common.tasks). The 3.5 Toolset can be used with target .NET Framework versions 2.0 and 3.0. The 2.0 Toolset, however, can be used only with target .NET Framework version 2.0.
Visual Studio 2008 installs .NET Framework 3.5, which includes two predefined Toolsets: one for .NET Framework 2.0 and one for .NET Framework 3.5. No Toolset is defined for .NET Framework 3.0 which is included with Windows Vista. The .NET Framework 2.0 Toolset can only target .NET Framework 2.0, but the .NET Framework 3.5 Toolset can target .NET Framework versions 2.0, 3.0, or 3.5.
You can also create your own custom Toolsets. For more information, see Standard and Custom Toolset Configurations.
A Target Framework is the particular version of the .NET Framework that your project is built to run on. It is necessary because it enables compiler features that are exclusive to that version of the .NET Framework 2.0, or references to assemblies that ship only in that version of the framework.
Currently, there are three .NET Framework versions available for use in Visual Studio 2008:
.NET Framework 2.0 (included with Visual Studio).
.NET Framework 3.0 (included with Windows Vista).
.NET Framework 3.5 (included with Visual Studio 2008).
Although there are three different .NET Framework versions, all the versions are based on the same underlying common language runtime (CLR) version 2.0 that was included in Visual Studio 2005.
The Target Framework version is specified in your project file through the TargetFrameworkVersion property. Visual Studio sets this value when you switch the target framework version through the integrated development environment (IDE). (For more information, see How to: Target a Specific .NET Framework.) The possible values for TargetFrameworkVersion are v2.0, v3.0 and v3.5. It is specified as an MSBuild property, such as:
The Toolset version can be specified by the ToolsVersion attribute on the Project Element (MSBuild) in the project file. The following example indicates that the project should be built using the .NET Framework 2.0 2.0 toolset:
<Project ToolsVersion="2.0" ... </Project>
When you build a solution or project on the command line, specifying a ToolsVersion for msbuild.exe causes all projects and their project-to-project dependencies to be built according to that ToolsVersion, even if each project in the solution specifies its own ToolsVersion in its Project Element (MSBuild).
Differences Between .NET Framework Versions
All three versions of the .NET Framework are based on version 2.0 of the CLR. The versions of the .NET Framework differ from each other in the list of assemblies that each makes available for you to reference in your projects. For example, LINQ is a new technology that is included in Visual Studio 2008. .NET Framework 3.5 is the only version of the .NET Framework that has LINQ-related assemblies. Therefore, you cannot use LINQ unless your project specifically targets .NET Framework 3.5. Similarly, Windows Presentation Foundation (WPF) is included in Windows Vista. You cannot build WPF applications unless your project targets .NET Framework 3.0 and later versions of the .NET Framework.
For more information, see Standard and Custom Toolset Configurations.
How Projects Locate Toolsets
To create a project, Visual Studio 2008 requires a Toolset. MSBuild locates targets and tasks using the $(MSBuildToolsPath) property. For example, MSBuild finds the Microsoft.CSharp.targets file by using the following XML element:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Microsoft.CSharp.targets is an example of a language-specific build process used by Visual Studio 2008 for building Visual C# projects. $(MSBuildToolsPath) resolves to the path of the appropriate version of the .NET Framework where Microsoft.CSharp.targets is installed (for example, C:\Windows\Microsoft.Net\Framework\v2.0.50727).
Before the MSBuild 3.5 Toolset can build this project, it must resolve $(MSBuildToolsPath) to the installation location of MSBuild 3.5 so that the Toolset imports the Visual Studio 2008 version of Microsoft.CSharp.targets.
Depending on the ToolsVersion, $(MSBuildToolsPath) gets a different value, causing it to import a different ToolSet based on the ToolsVersion value. This flexible system lets the project, MSBuild host, or user specify the Toolset that a project should be built with, and also specify a way for MSBuild to use the location information to pick the correct Toolset.
How the ToolsVersion Attribute Works
When you create a new project, or upgrade an existing project in Visual Studio 2008, an attribute named ToolsVersion is automatically included in the project file and set to a default value of "3.5". For more information, see Targeting a Specific .NET Framework.
When a ToolsVersion value is defined in a project file, MSBuild uses it to determine the values for $(MSBuildToolsPath) (or $(MSBuildBinPath)), which is the path of the MSBuild tools. If a ToolsVersion value is not defined, MSBuild continues to use the old Toolset path because it assumes that the project is a Visual Studio 2005 project.
If you open an existing Visual Studio 2005 project in Visual Studio 2008, the project is physically "upgraded" to include "ToolsVersion=3.5" since Visual Studio 2008 only supports building with the 3.5 toolset. As a result, when you build the project in Visual Studio 2008, it will use the Visual Studio 2008 Toolset (3.5) instead of the Visual Studio Toolset (2.0).
Projects created by using the 2.0 Toolset can target the .NET Framework 2.0, and projects created by using the 3.5 Toolset can target versions 2.0, 3.0, or 3.5 of the .NET Framework. Even if a Visual Studio project has been migrated to Visual Studio 2008 and upgraded to use the 3.5 Toolset, the Target Framework for the project will continue to be .NET Framework 2.0. This design guarantees that when you migrate your project to Visual Studio 2008, it will not introduce new dependencies. The project continues to build exactly as it did in Visual Studio.
If ToolsVersion is already defined in a project, Visual Studio 2008 will not change its value. The ToolsVersion value can be overridden. For more information, see Overriding ToolsVersion Settings.
Visual Studio 2005 and MSBuild 3.5 Compatibility
Visual Studio 2005 cannot open or build Visual Studio 2008 projects, or projects upgraded to Visual Studio 2008. But the MSBuild 2.0 toolset may be able to build your Visual Studio 2008 projects if you have not used any new functionality that is specific to Visual Studio 2008 Toolset such as LINQ, new Visual C# 2008 or Visual Basic 2008 syntax features, and so forth.