V3 Documentation
Search

Project Build Platform And Configuration

Description

While NCrunch's build environment is designed to be similar to the build process used by Visual Studio, there are differences around the behaviour of the $(Configuration) and $(Platform) build properties that are used by the build process. Visual Studio will normally set the values of these properties according to the build configuration selected within the IDE, though NCrunch will use the default values for these properties as specified in the .proj file.

It could thus be stated that NCrunch's build more closely resembles that of a command-line invocation of MSBuild against the .proj file, where Visual Studio's build is heavily reliant on injected properties.

Possible Problems

This difference in build behaviour can cause problems for solutions that have only ever been built by Visual Studio, and are reliant on the injected $(Configuration) and $(Platform) build properties being consistent with the values required in the project files.

For example, consider a project file with the following XML content (important code is shown in pink):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Alternative</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProjectGuid>{FD5A8DEF-2066-49A7-BE5D-BE0125B4DD1D}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MyLibrary</RootNamespace>
    <AssemblyName>MyLibrary</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <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>

The code above will likely build without problems in Visual Studio, but will fail when built by NCrunch or a command-line invocation of MSBuild. Note that the <Configuration> and <Platform> declarations near the top of the file are not consistent with the conditions attached to the <PropertyGroup> sections. This indicates that the project file is totally reliant on the $(Configuration) and $(Platform) properties being injected into the build by Visual Studio.

This problem can manifest itself not just in build failures, but also in platform related issues that will only surface at test run-time.

Solutions

Avoid Erroneous Defaults In Project Files

By far the best way to solve this problem is to fix up the project files themselves so that their defaults are consistent with the build platforms and configurations that they support. This will not only resolve the problem for NCrunch, but also for other build tools such as continuous integration servers.

A corrected version of the above project file is shown below (with modified parts of the file shown in purple):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{FD5A8DEF-2066-49A7-BE5D-BE0125B4DD1D}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MyLibrary</RootNamespace>
    <AssemblyName>MyLibrary</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <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>

Inject The Configuration And/Or Platform Using NCrunch

For situations where adjusting the project files is not feasible, NCrunch has two configuration settings that can be used to inject values for the $(Platform) and $(Configuration) properties in the same manner as Visual Studio. These configuration settings are Use Build Configuration and Use Build Platform respectively.

Note that the NCrunch configuration pane allows application of settings across multiple projects through multiple-selection, which can be very useful for the above two settings.