Team Build (v1 and Orcas) typically deals with solution configurations, which many people (including me circa 2005) don’t understand. So – I figured I’d post a quick tutorial here on solution configurations vs. project configurations…
Project-Level Platforms / Configurations
There are many types of Visual Studio projects, with each type having various different available platforms and configurations. For example, C# / VB .NET projects typically have a single available platform (“Any CPU”) and two available configurations (“Debug” / “Release”). These project-level platforms and configurations are really just named collections of project settings – compiler options, output directories, etc. In the IDE, for example, we see the following options for a C# project:
These same options can also be seen by viewing the project file as an XML document:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> </Project>
So – project-level platforms and configurations == named collections of project settings. Simple enough. When we build an individual project, we can just specify the project-level platform and configuration we want to build and all the associated settings will be used. For example, to build the above project from the command-line we might do something like:
> msbuild.exe CSharpProject.csproj /p:Platform=AnyCPU /p:Configuration=Debug
Things get a bit more complicated when we want to build multiple projects at the same time, however. First of all, different project types often have different available platforms / configurations. Here’s a quick list of some common project types and their default platform / configuration availability:
|C# / VB .NET||AnyCPU||Debug / Release|
|C++||Win32||Debug / Release|
|Web Application||AnyCPU||Debug / Release|
Another issue when building multiple projects is that for certain configurations, we may just not want to build certain projects. For example, we might only want to build a test project when building the Debug configuration (and not when building Release).
Solution-Level Platforms / Configurations
Visual Studio’s solution-level platforms and configurations help with both these issues. A solution-level platform / configuration is really just a named collection of project-level platforms and configurations.
For example, if you create a solution that contains one project of each of the above types, Visual Studio will automatically create a solution-level platform called “Mixed Platforms”. To see the definition of this platform, we can look at the Configuration Manager, which is accessible in the IDE through the Build menu:
Note that the solution-level Mixed Platforms platform is just a collection of project-level platforms – .NET for the website, Win32 for the C++ project, and Any CPU for the C# and Web Application projects. If we instead select one of the other platforms we see that only a subset of the projects will be built at all:
So – solution-level platforms / configurations == named collections of project-level platforms / configurations. When we build a solution, we can just specify the solution-level platform and configuration we want to build and all the appropriate project-level platforms and configurations will be used. For example, to build the above solutions from the command-line we might do something like:
> msbuild.exe MixedProjects.sln /p:”Platform=Mixed Platforms” /p:Configuration=Debug
Note that there is nothing magic about the “Mixed Platforms” platform – you can create your own custom solution-level platforms / configurations with whatever names you choose. In the Configuration Manager, just select the Active solution platform combo box and select <New…>:
Implications for Team Build
Team Build v1 was fairly tightly coupled with the building of solutions. As such, the platforms / configurations selected for the ConfigurationsToBuild item group really needed to be solution-level platforms / configurations. (Note: if you have never seen this XML before, you probably just specified these values through the Team Build build type creation wizard. See here for instructions on editing a build type in v1.)
<ItemGroup> <!-- CONFIGURATIONS The list of configurations to build. To add/delete configurations, edit this value. For example, to add a new configuration, add following lines - <ConfigurationToBuild Include="Debug|x86"> <FlavorToBuild>Debug</FlavorToBuild> <PlatformToBuild>x86</PlatformToBuild> </ConfigurationToBuild> The Include attribute value should be unique for each ConfigurationToBuild node. --> <ConfigurationToBuild Include="Debug|Mixed Platforms"> <FlavorToBuild>Debug</FlavorToBuild> <PlatformToBuild>Mixed Platforms</PlatformToBuild> </ConfigurationToBuild> </ItemGroup>
In Orcas, Team Build is much less tightly coupled with the building of solutions, so the platforms / configurations selected for the ConfigurationToBuild item group will depend on the contents of the SolutionToBuild item group. That is, if SolutionToBuild items are in fact solutions, the ConfigurationToBuild item group should still specify solution-level platforms / configurations. If, on the other hand, the SolutionToBuild item group contains projects, the ConfigurationToBuild item group should contain project-level platforms / configurations.
In any case, behind the scenes Team Build will invoke MSBuild on each item in the SolutionToBuild item group once for each item in the ConfigurationToBuild item group, and will pass in values for the $(Platform) and $(Configuration) properties corresponding to the PlatformToBuild and FlavorToBuild values from the ConfigurationToBuild item group.
Hopefully this will clarify this subject a bit. Please post additional comments/questions if you have them, or feedback if you think I could do something else to clarify this topic even more.