Solution Configurations


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:

CSharp Project Debug AnyCPU

CSharp Project Release AnyCPU

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:

Project Type Platforms Configurations
C# / VB .NET AnyCPU Debug / Release
C++ Win32 Debug / Release
Web Application AnyCPU Debug / Release
Website .NET Debug

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:

image

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:

image

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…>:

image

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.


Comments (6)

  1. j.oliver says:

    Aaron – a nice informative post and I have an additional question…

    Is it possible to specify which configuration to use for separate solutions?  For example, we have a large number of solutions to build and many of them contain C++ and .NET projects and so the ‘Mixed Platforms’ platform needs to be built (these solutions also contain platforms for ‘Win32’ and ‘AnyCPU’).  Some of the solutions are C++ only and therefore only have a ‘Win32’ platform; dually, some solutions are .NET only and hence have ‘AnyCPU’ platform only.  In practice – we only develop for Win32.

    I can specify multiple ConfigurationToBuild entries in the team build type, but this would just mean that any projects in solutions with multiple platform configurations get built twice or three times.  I know that I could tidy up all the solutions so that they only have the configuration that needs building, but ultimately, these are solutions used by developers, and things would very quickly get out of shape due to their desktop configuration, or due to Visual Studio deciding to create additional Platform configurations itself.  Any workarounds?  We use V1 but may be upgrading to orcas later this year.

  2. HKG says:

    Aaron

    I am looking into solution for similar issue. We have projects referenced (project reference NOT binary reference)in our solution which actually exists in  different solution of another team project. I could create a team build successfully using the blog http://blogs.vertigosoftware.com/teamsystem/archive/2006/08/22/3403.aspx#3449. Thanks to Jeff Atwood of Vertigo software.

    But the team build results in warnings for all the referenced projects as below:

    E:BuildXYZABCMy.Common.sln(0,0): warning MSB4126: The specified solution configuration "Release|Mixed Platforms" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration.

    My main solution is a Release|Mixed Platforms and other ones are Release|Any CPU.

    Please let me know if there is any solution..

  3. Garry Trinder says:

    There are a couple of potential solutions here.  

    1. You can conditionalize the inclusion of solutions in the SolutionToBuild item group on the Platform.  Something like:

    <SolutionToBuild Include="Solution1.sln" Condition=" ‘$(Platform)’ == ‘Any CPU’ " />

    <SolutionToBuild Include="Solution2.sln" Condition=" ‘$(Platform)’ == ‘Mixed Platforms’ " />

    In this case, you would have both entries in your ConfigurationToBuild item group.

    1. You can create a common configuration across all the solutions.  For example, you can add an Any CPU configuration to your Mixed Platforms solution that is just a copy of the Mixed Platforms configuration.  In this case, you would only have the one entry in your ConfigurationToBuild item group.
  4. Anonymous says:

    I often hear that our customers hit challenges when developing ASP.net applications with VSTS and TFS.

  5. shail_k_patel says:

    I am confused what to set to <ConfigurationToBuild> section in MSBuild "Release|Any CPU" or "Release|Mixed Plateform".  I have a solution that has a web application(VB.NET) and has some class library project (Some of them are in VB.NET and others are in C#  so it’s mixed).  I currently set both "Release|Any CPU" and "Release|Mixed Plateform" in tfsbuild project file.  What it does is It compiles solution first with Any CPU except web application and then it compiles solution with Mixed Plateform with web application so It seems like all the class library project is compiling twice.  Any suggestion on that?

  6. Anonymous says:

    I'm having an issue where I have a SolutionToBuild item that requires specifying a different platform (x86) than other items, but has a project reference to a project that needs to be built in AnyCPU.  If any configuration is passed into the first project, it will use the same configuration when building the referenced projects (this is bad and causes build errors).  The way to get this to work on the command line is to omit specifying a platform at all, but in TeamBuild I have been unable to find a way to avoid passing a platform at all.  I can get teambuild to internally pass the Platform property with an empty value, but I get errors:

    Please check to make sure that you have specified a valid combination of Configuration and Platform for this project.  Configuration='Release'  Platform=''.

    This is the equivalent of:  msbuild assembly.proj /p:Configuration=Release /p:Platform=""  (which is bad)

    I want to emulate this equivalent:  msbuild assembly.proj /p:Configuration=Release

    I appreciate any help!

    Regards,

    Brandon