多框架NuGet构建带有内部依赖关系管理的符号

Dav*_*ike 20 multiplatform nuget nuget-package

也许我在这里推动信封,但我迫切希望利用NuGet来缓解我发现自己的DLL地狱.

我们有4个主要产品都存在于相互关联的Mercurial存储库中.所有这些都"共享"了3个核心组件,然后其他一切都是针对特定产品的.现在管理变得非常困难,因为一个产品已升级到.NET 4.0并且正在使用需要.NET 4.0的外部依赖项,而另一个产品因为我甚至不想进入的原因而陷入.NET 3.5.

因此,我们失去了合并产品差异的能力.

要修复它,我想取出3个主要程序集,并将它们转换为自己的项目,并使用自己的发布周期,并注意确保它们可以针对.NET 3.5和4.0进行编译,然后将它们转换为NuGet包含多个框架版本.

但是,我也希望开发人员能够浏览这些项目的来源.

所以我设置了一个私有的NuGet服务器和一个私有的SymbolSource服务器.然后我仔细地将所有存储库中的所有更改合并在一起,并丢弃除核心程序集之外的所有内容.然后我精心手工编辑.csproj文件,以便代替AnyCPU平台,每个项目都有3.5和4.0的平台目标,它指定条件常量(控制System.Dynamic等特定于平台的功能)并设置框架版本.

然后我为"3.5 Debug","3.5 Release","4.0 Debug"和"4.0 Release"设置了解决方案配置.每个目标都适用于相应的配置(调试或发布)和平台(3.5或4.0).

我可以在Visual Studio中为任何平台构建一切.现在我遇到NuGet的问题,因为有两种方法可以创建一个包,两者都有一个弱点,除非我遗漏了一些东西:

按项目文件打包

nuget pack MyProject.csproj -Build -Symbols -Version <insert-from-build-server> -Properties "Configuration=Release;Platform=3.5;"
Run Code Online (Sandbox Code Playgroud)

这个问题是:

  • 在构建和打包3.5版本时,输出显示"构建目标框架的项目'.NETFramework,Version = v4.0'."
  • 如果我解压缩生成的包,则程序集lib\net40错误.
  • 我认为没有办法以这种方式打包2个框架目标,你必须用文件夹和约定的另一种方式来做.
  • 我愿意接受你不能将框架打包在一起并制作2个名为MyProject的软件包(我会做4.0)和MyProject.V35 ...但是我无法弄清楚如何拥有相同的项目和nuspec并结束使用不同ID的2个不同结果.

由Nuspec文件打包

使用这种方法,我必须自己完成所有msbuilding,然后进行一堆文件复制来设置文件夹结构

* MyProject.nuspec
* net40
    * MyProject.dll
    * MyProject.pdb
* net35
    * MyProject.dll
    * MyProject.pdb
Run Code Online (Sandbox Code Playgroud)

然后我可以运行nuget pack MyProject.nuspec但是没有源代码可以使用符号,因为没有.csproj文件,NuGet无法弄清楚从哪里获取所有源文件,而且我没有看到任何关于如何做的文档这使用目录约定.

所以我的问题是:

  1. 有没有办法将源文件添加到基于约定的包?
  2. 有没有办法用不同的ID打包基于项目的包两次?
  3. 还有其他途径,也许我没有考虑过吗?

任何想法将不胜感激.

Dav*_*ike 15

Xavier的回答让我朝着正确的方向前进,并且还通知了我的Google搜索.我并不完全了解文件声明,在搜索这些文件时,我找到了Joshua Flanagan 关于构建NuGet包的帖子,这非常棒.泽维尔和约书亚一起教我一些东西:

  1. 您不必为了构建包而组装符合约定的文件树.最好使用file元素来选择文件并将它们定位到组装的NuGet包中的目标目录.
  2. NuGet的-Symbols标志不仅适用于.csproj文件的打包.当你在.csproj文件上使用它时,确定,它是如何计算出如何打包所有源文件的.但您也可以-Symbols.nuspec包含源文件元素的文件上使用.普通的NuGet包不包含src目录,但符号包将包含.

现在,让我描述我在CI服务器上发生的构建过程:

  1. 使用"3.5 Release"解决方案配置构建解决方案.
  2. 使用"4.0 Release"解决方案配置构建解决方案.
  3. 使用ILMerge.exe内化某些程序集.我有这些输出(例如)bin\Release-3.5\merged所以我没有必须在我在合并中使用它之前将目标程序集重命名为temp.dll.
  4. 针对.nuspecPowershell 构建软件包.

这是包命令:

nuget pack src\MyProject\MyProject.nuspec -OutputDirectory .\output -Build -Symbols -Version $Version
Run Code Online (Sandbox Code Playgroud)

请注意,$ Version是从构建服务器传入的,因此我可以使用其构建号作为版本的最后一部分.

这是.nuspec文件:

<?xml version="1.0"?>
<package>
    <metadata>
        <id>MyProject</id>
        <version>0.0.0</version>
        <title>MyProject</title>
        <authors>David Boike</authors>
        <owners>David Boike</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>MyProject</description>
        <releaseNotes></releaseNotes>
        <copyright>Copyright 2012</copyright>
        <tags>my tags</tags>
    </metadata>
    <files>
        <file src="bin\Release-4.0\merged\MyProject.dll" target="lib\net40" />
        <file src="bin\Release-4.0\merged\MyProject.pdb" target="lib\net40" />
        <file src="bin\Release-4.0\MyProject.xml" target="lib\net40" />
        <file src="bin\Release-3.5\merged\MyProject.dll" target="lib\net35" />
        <file src="bin\Release-3.5\merged\MyProject.pdb" target="lib\net35" />
        <file src="bin\Release-3.5\MyProject.xml" target="lib\net35" />
        <file src="**\*.cs" target="src" />
    </files>
</package>
Run Code Online (Sandbox Code Playgroud)

请注意,我已经从我的nuspec中删除了许多更具信息性的元素,因为它对于像这样的内部项目并不重要.

结果是我的私有NuGet服务器的包,其中包含用于.NET 3.5和4.0的程序集的DLL,PDB和XML文档,然后是包含所有上述和源的私有SymbolServer的单独符号包.使用NuGet Package Explorer非常容易查看,我强烈建议您下载.

最后,我测试了所有内容,并使用在symbolsource.org上建议Visual Studio设置(除了我自己的私有符号服务器),我能够调试代码并轻松进入源代码.

再次感谢Xavier带领我走正确的道路!


Xav*_*ter 8

你知道有第三种选择吗?在定位csproj文件时,它还会查找与项目文件同名的nuspec文件(myProject.csproj - > myProject.nuspec).这意味着您可以通过将结果包定义到nuspec文件中,将额外的元数据添加到生成的包中,同时仍然以csproj文件为目标.从本质上讲,您最终会得到一个包含csproj文件和nuspec文件中合并元数据的包.

在您的特定方案中,如果要打包同一项目的多个平台构建,则在使用nuspec打包之前,您确实必须先构建这些项目.

我建议你创建两个项目,一个针对NET35,另一个针对NET40,并将文件作为链接添加到其中一个项目中.因此,您可以构建两个项目,并使用nuspec文件将所有输出打包在一个NuGet包中.

现在对于符号,我认为你可以有第二个nuspec文件(例如myProject.symbols.nuspec),你可以使用通配符添加项目的所有内容(源等),类似于下面所示.

<file src="myProject35\**\*.cs" target="src" />
<file src="myProject40\bin\Release\*.dll" target="lib\net40" />
<file src="myProject40\bin\Release\*.pdb" target="lib\net40" />
<file src="myProject35\bin\Release\*.dll" target="lib\net35" />
<file src="myProject35\bin\Release\*.pdb" target="lib\net35" />
Run Code Online (Sandbox Code Playgroud)

希望这有助于或至少为您提供一些信息,以找到出路:)

干杯,泽维尔

  • 仅供参考 - Control-Shift-Drag'n'Drop将项目之间的文件复制为链接 (2认同)