R – Targetting different Frameworks using MSBuild gives problems with dependencies

cruisecontrol.netmsbuildmsbuild-task

I have a little project, and I want to have 2 compiled versions of that project:

  • one that is targetting the .NET 2.0 framework
  • one that is targetting the .NET 3.5 framework

All is going well; I've put my project under continuous integration (using CC.NET), and I've created 2 CC.NET 'projects'. One project for each target-framework.

I won't go too much in (irrelevant) details, but my solution is set up to target the .NET 3.5 framework in VS.NET.

I have 2 msbuild-tasks:

  • one task that builds the solution for
    .NET 3.5 (simple and easy)
  • one task that builds the solution for
    .NET 2.0

    In this Task, I call MSBuild, and I specify that the TargetFrameworkVersion should be v2.0. I also define some additional build-conditions (so that .NET3.5 specific code is not built in the assembly targetting .NET2.0).

So far, so good. Everything works fine.
Now, the problem however is this:

My solution has a few dependencies (references to 3rd party assemblies). In VS.NET, I've set 'copy local' to true for these dependencies.
When CC.NET builds my .NET3.5 version of the assembly, the 3rd party dependencies are indeed copied to my output-directory.

However, when CC.NET builds my .NET2.0 version of the assembly, the dependencies are not copied to my output-directory. (Then, this causes my unit-tests to fail).

My question now is:
How can I say to msbuild that certain of the 3rd party references have to be copied local when building my .NET2.0 version of my project ?
Or, is there any other way to achieve this, since, I wouldn't like to specify every dependency once again in my build-script. This would quickly become a maintenance nightmare, I guess.

Best Answer

I've been revisiting this problem again, since I do not like to have to manually change the csproj file. (When I change my reference, I must not forget to adapt the csproj file again, to set the Private node to true again).

So, I've been digging into MSDN, and I stumbled upon this:

ResolveAssemblyReference.TargetFrameworkDirectories Property

Remarks This property is required to determine the CopyLocal status for resulting items.

If this property is not specified, no resulting items will be have a CopyLocal value of true unless they explicitly have a Private metadata value of true on their source item.

So, this means that there is yet another possibility, and that is to set the TargetFrameworkDirectories of the ResolveAssemblyReference task. However, is there anybody out there who knows how to do this ?
I've been trying different things, but nothing seems to be working ...

I've tried this:

<ItemGroup>
    <TargetFrameworkDir Include="$(SystemRoot)\Microsoft.NET\Framework\v2.0.50727" />
</ItemGroup>

<PropertyGroup>
   <TargetDirsToUse>@(TargetFrameworkDir)</TargetDirsToUse>
</PropertyGroup>

<ResolveAssemblyReference TargetFrameworkDirectories="$(TargetDirsToUse)" />

But to no avail ... Maybe someone else knows how to do this, or has a golden tip. (I've been spending way to much time on this f*cking issue).