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.
- A is a .NET 4.5 project referencing Newtonsoft.Json(.NET 4.5)
- B is a Portable Class Library referencing Newtonsoft.Json(PCL)
- C is a PCL referencing B
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:
- B is built. B is compiled with a reference to Netwonsoft.Json(PCL), which is copied to OutDir
- A is built and the Newtonsoft.Json(.NET 4.5) that it references is copied along with it to the OutDir, overriding the previous PCL version. Note that B would still be "runnable", because NuGet advises package authors that more specific versions of a library must be API compatible (and carry same assembly name and strong name).
- C is built, however when it resolves the closure of assembly references, it would resolve B's Newtonsoft.Json(PCL) reference to Newtonsoft.Json(.NET 4.5) which in turn references mscorlib 4.0 instead of the retargetable mscorlib required by PCLs. Boom.
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.