Context: I'm building a solution on AppHarbor, which invokes msbuild basically like this (docs) :
msbuild solution.sln /p:Configuration=Release /property:OutDir=C:\temp
To simplify the scenario somewhat, say I have these three projects in my solution.
At the point of building C, I'm seeing an MSbuild error:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(1605,5): warning MSB3268: The primary reference "B" could not be resolved because it has an indirect dependency on the framework assembly "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETPortable,Version=v4.0,Profile=Profile47". To resolve this problem, either remove the reference "B" or retarget your application to a framework version which contains "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". [C]
This is what I think happens:
What I'm looking for is a way to work around this problem. I can't change the way AppHarbor builds the solution (so no changes to the msbuild commandline) and B and C must remain portable class libraries. A solution might involve either forcing a fixed build order or preventing the OutDir
to end up in the AssemblySearchPaths
when C is built. I'm open for suggestions though.
Or possibly I could make NuGet install Newtonsoft.Json into A
in a way that uses the PCL version? Not sure if this would break other libraries that A depends on and that depend on Newtonsoft.Json in turn.
I have found a solution (after some digging) for this problem, please note that it requires MSBuild shipped with .NET 4.5 or later.
Microsoft added the property GenerateProjectSpecificOutputFolder, which will add a subdirectory with the project name under OutDir
when set. To solve the problem above, I set the property to True in every PCL project in my solution. Since the plain .NET projects in my solution have project references to those PCLs, they will still be copied to the OutDir during the build, while the PCLs the selves are being built "in isolation".
Here's how to set the property by example (I'm including this project file instead of Microsoft.Portable.CSharp.targets):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--When building in AppHarbor, we need a project specific output folder so the assembly references don't clash with those from the plain .NET projects-->
<GenerateProjectSpecificOutputFolder>true</GenerateProjectSpecificOutputFolder>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
</Project>