使用msbuild / p:OutDir与引用同一库(PCL)的不同版本的项目

时间:2014-04-28 14:41:15

标签: msbuild nuget portable-class-library

上下文:我正在AppHarbor上构建一个解决方案,它基本上像这样调用msbuild(docs):

msbuild solution.sln /p:Configuration=Release /property:OutDir=C:\temp

为了简化场景,请说我的解决方案中有这三个项目。

  • A 是引用Newtonsoft.Json(.NET 4.5)的.NET 4.5项目
  • B 是引用Newtonsoft.Json(PCL)的可移植类库
  • C 是引用 B
  • 的PCL

在构建C时,我看到了MSbuild错误:

  

C:\的Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Microsoft.Common.targets(1605,5):   警告MSB3268:无法解析主要参考“B”   因为它对框架程序集有间接依赖性   “mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089“无法解决的问题   目前的目标框架。   ” .NETPortable,版本= V4.0,外形= Profile47" 。要解决这个问题   问题,要么删除引用“B”或重新定位您的应用程序   到框架版本,其中包含“mscorlib,Version = 4.0.0.0,   Culture = neutral,PublicKeyToken = b77a5c561934e089“。[C]

这就是我认为发生的事情:

  • B 已建成。 B编译时引用了Netwonsoft.Json(PCL),复制到OutDir
  • 构建,并将它引用的Newtonsoft.Json(.NET 4.5)与其一起复制到OutDir,从而覆盖以前的PCL版本。请注意,B仍然是“可运行的”,因为NuGet建议软件包作者,库的更具体版本必须与API兼容(并且具有相同的程序集名称和强名称)。
  • C 是构建的,但是当它解析程序集引用的关闭时,它将解析 B 的Newtonsoft.Json(PCL)对Newtonsoft.Json的引用(。 NET 4.5)反过来引用mscorlib 4.0而不是PCL所需的可重定向的mscorlib。吊杆。

我正在寻找的是一种解决这个问题的方法。我无法改变AppHarbor构建解决方案的方式(因此对msbuild命令行没有任何更改), B C 必须保持可移植类库。解决方案可能涉及强制修复构建订单或阻止OutDir在构建 C AssemblySearchPaths结束。我虽然愿意接受建议。

或者我可以让NuGet以一种使用PCL版本的方式将Newtonsoft.Json安装到A中?不确定这是否会破坏A所依赖的其他库并依次依赖于Newtonsoft.Json。

1 个答案:

答案 0 :(得分:1)

我已找到解决此问题的解决方案(经过一些挖掘),请注意它需要随.NET 4.5或更高版本附带的MSBuild。

Microsoft添加了属性GenerateProjectSpecificOutputFolder,该属性将在设置时添加项目名称在OutDir下的子目录。为解决上述问题,我在我的解决方案中的每个PCL项目中将该属性设置为True。由于我的解决方案中的普通.NET项目具有对这些PCL的项目引用,因此在构建期间它们仍将被复制到OutDir,而PCL则是“孤立地”构建的。

以下是如何通过示例设置属性(我包含此项目文件而不是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>