Question

I have a class library that targets .NET 3.5. Now, I would like to add some features that require .NET 4.0, but I still want to be able to generate a version that targets .NET 3.5 (without these features of course).

Ideally, I would like to target a different framework version based on the configuration:

  • Debug, Release => .NET 3.5
  • Debug 4.0, Release 4.0 => .NET 4.0

Unfortunately it doesn't seem to be possible, as the target framework is global for the whole project...

Is there a way around it? I know I could create a second project that includes the same files, but it's pretty bad for maintainability....

What is the easiest way to do this? If you have ever done something similar, which approach worked best?

Was it helpful?

Solution

First of all, you could start off by creating a conditional compilation symbol that enables you to include or exclude the extra features that are only available for the .NET4.0 framework.

Next to that, I think you'll have to use MSBuild directly, instead of letting VS.NET build your project. I've done something similar once. In short, it comes down to the fact that you'll have to create 2 build tasks within your MSbuild script. One that allows you to build your project for .NET 3.5, and one that allows you to build the project targetting .NET 4.0.

In each build-task, you can define the target framework, and the conditional compilation symbol that you'd want to use.

The build - tasks in your build-script could like like this:

<Target Name="buildall-v4">
    <!-- The following ItemGroup defines all the build-constants that have to be used
         in the build.  
         As can be seen, the DEBUG & RELEASE constants are only included when necessary -->

    <ItemGroup>
      <BuildConstant Include="DEBUG" Condition="'$(buildmode)'=='DEBUG'" />
      <BuildConstant Include="RELEASE" Condition="'$(buildmode)'=='RELEASE'" />
      <BuildConstant Include="NET_FRAMEWORK_4_0" />
    </ItemGroup>

    <PropertyGroup>
      <BuildConstantsToUse>@(BuildConstant)</BuildConstantsToUse>
    </PropertyGroup>

    <MSBuild Projects="$(builddir)\Source\MyProject.sln"
             Properties="OutputPath=$(outputdir)\v4;Configuration=$(buildmode);DefineConstants=$(BuildConstantsToUse);TargetFrameworkVersion=v4.0" />       
  </Target>


<Target Name="buildall-v3.5">
        <!-- The following ItemGroup defines all the build-constants that have to be used
             in the build.  
             As can be seen, the DEBUG & RELEASE constants are only included when necessary -->

        <ItemGroup>
          <BuildConstant Include="DEBUG" Condition="'$(buildmode)'=='DEBUG'" />
          <BuildConstant Include="RELEASE" Condition="'$(buildmode)'=='RELEASE'" />
        </ItemGroup>

        <PropertyGroup>
          <BuildConstantsToUse>@(BuildConstant)</BuildConstantsToUse>
        </PropertyGroup>

        <MSBuild Projects="$(builddir)\Source\MyProject.sln"
                 Properties="OutputPath=$(outputdir)\v3.5\;Configuration=$(buildmode);DefineConstants=$(BuildConstantsToUse);TargetFrameworkVersion=v3.5" />        
      </Target>

Offcourse, when you'd want to build for the 2 versions, you'll have to execute each msbuild command separatly on the command line.

OTHER TIPS

I learned how to do this using:
http://blogs.msdn.com/b/visualstudio/archive/2010/05/14/a-guide-to-vcxproj-and-props-file-structure.aspx
and
http://shazwazza.com/post/multi-targeting-a-single-net-project-to-build-for-different-framework-versions/

Basically, follow these steps:

  1. Open your project file with a text editor so you can view/edit all the XML. Your project file is the ProjectName.vcxproj.
    • Using the Visual Studio text editor
      1. Unload the project you plan to edit. Right-click the project you want to edit and select "Unload Project"; it will turn grey.
      2. Use File->Open->File... Ctrl+O and navigate to the location of the ProjectName.vcxproj file and open it. DO NOT USE File->Open->Project/Solution.
      3. When you're done you'll want to save/close the file and the right-click the project in the solution explorer and select "Reload Project"
    • Or just use a different editor such as Notepad++ or even a new instance of Visual Studio.
  2. Next:

    • Remove

      <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
      
    • from within the

      <PropertyGroup Label="Globals">
      
    • and

      </PropertyGroup> 
      
    • tags.

  3. Now:

    • Paste

      <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> 
      
    • or

      <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
      
    • within the appropriate "Debug"

      <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
      
    • or "Debug 4.0"

      <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 4.0|Win32'" Label="Configuration">
      
      • Since it is no longer in the 'Globals' property group make sure that every configuration has the <TargetFrameworkVersion Blah="blah blah"> tag in its PropertyGroup.
  4. Save the changes (may need to close the file as well if are using the same instance of visual studio where the project will be loaded).

  5. Load or Reload the project in visual studio and verify that individual configurations build with different Frameworks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top