The differences between Solution build configurations and Project build configurations

In VS2012 RC, there is a bug in the Web Publishing feature for WAPs: when a solution build configuration doesn’t match the project build configuration, VS doesn’t correctly find the set of files to be published.  Did that make sense to you?  If so, you’re probably not interested in the rest of this post.  Otherwise, keep reading, and hopefully you’ll learn something new and (remotely) useful.

Project Build Configurations

Each project has 2 parts to it’s build configuration: the platform, which is any of x86/x64/Any CPU; and the configuration, which defaults to one of Debug or Release, but you can create your own with whatever name you’d prefer.

Within the project file, you can specify certain project properties based on the active build configuration.  For example, in the project file, there are several sections defined as follows:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <!-- snip -->
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <!-- snip -->
  </PropertyGroup>

With these different settings (configuration/platform), you can tweak the behavior of your project build to suit different environments.  In the example cited above, you can affect the debug symbols or compiler optimizations applied during build.

Solution Build Configurations

The solution build configuration doesn’t actually affect any property values during build.  Instead, it’s basically just a mapping of each project with its project build configuration.  For example, here’s the contents of a solution file which contains two projects, has two configurations defined (Debug/Release) and two platforms defined (Any CPU/x64):

	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Debug|x64.Build.0 = Debug|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Release|Any CPU.Build.0 = Release|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Release|x64.ActiveCfg = Release|Any CPU
		{0595D46B-8467-42BB-BFB5-F7B38EEA96E5}.Release|x64.Build.0 = Release|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Debug|x64.ActiveCfg = Debug|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Debug|x64.Build.0 = Debug|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Release|Any CPU.Build.0 = Release|Any CPU
		{F564EBE0-B6EB-4277-BC60-15E093B1A3E5}.Release|x64.ActiveCfg = Release|Any CPU
	EndGlobalSection

This is unintuitive at best, so I’ll explain how it works.

The GUIDs each represent one of the projects in the solution.  You can find out which maps to which towards the top of the solution file (that one’s easy enough, since you’re just looking for a match, that I won’t bother to explain it).

Following the GUID is the solution configuration.  So, {GUID}.Debug|x64 means that the active solution configuration is Debug/x64. 

Next comes some project specific properties.  First we see ActiveCfg, which is telling us the active configuration for that project, when the solution configuration is configured as shown.  We can see that when the Solution Configuration is set to Debug|x64, both projects are actually using Debug|Any CPU.  This is often a source of confusion between Solution and Project configurations – they aren’t necessarily the same!

The other property we see is Build.0, which indicates whether the project is included to be built in this solution configuration.  If you notice, for Release|x64, the project GUID starting with F564EBE0 doesn’t have a Build.0 value.  This means that the project is not included in build when the solution is set to Release|x64.

All of these settings can be configured in VS through the Configuration Manager.  For example, here’s a snapshot showing the Release|x64 configuration above, with one project left out of the build:

Configuration Manager

What we’ve learned

From the examples above, I hope it’s now clear what the different roles of Project Configuration and Solution Configuration play in managing your solution’s build process.  We saw that the Project Configuration allowed us to customize the build behavior for specific projects.  The Solution Configuration allows us to configure a batch of projects with their own specific configurations in a single build (for example, if I always wanted to build ClassLibrary1 with Debug settings, I can set that in the Solution’s Release configuration).

Leave a Reply