Nuget的最佳实践:调试还是发布?

时间:2012-11-21 07:26:33

标签: visual-studio debugging release nuget

目前,我使用Nuget将发布版本打包为nuget.org的官方版本,但是我使用Nuget将调试版本打包为符号源推送到symbolsource.org。

编辑:(Jon Skeet,Noda Time开发有一些偏见)

NuGet现在支持推送到NuGet gallery symbolsource.org(或类似服务器)as documented。不幸的是,这里有两个相互矛盾的要求:

  • 使用库而不需要调试时,你真的想要一个发布版本。毕竟,那就是发布版本。
  • 在调试库以进行诊断时,您确实需要一个禁用所有相应优化的调试版本。毕竟,这就是调试构建的目的。

那没关系,但是NuGet没有(据我所知)允许在同一个包中以有用的方式发布发布和调试版本。

所以,选择是:

  • 将调试版本分发给每个人(如文档中的示例所示),并且可以使用任何大小和性能命中。
  • 将发布版本分发给每个人,并且稍微有点受损的调试经验。
  • 寻找一个非常复杂的分发策略,可能会提供单独的发布和调试包。

前两个真正归结为调试和发布版本之间差异的影响......虽然值得注意的是,想要进入库代码之间也存在很大差异,因为你想要检查一些行为,并且想要调试库的代码,因为您认为自己发现了一个错误。在第二种情况下,最好将库的代码作为Visual Studio解决方案并以这种方式进行调试,因此我不会过多关注这种情况。

我的诱惑是继续发布版本,期望相对很少有人需要调试,而那些不会受到影响的人很多通过发布版本中的优化。 (无论如何,JIT编译器完成了大部分优化。)

那么,我们还没有考虑其他选择吗?是否有其他考虑因素可以达到平衡?是否将NuGet包推向SymbolSource足够新,以至于“最佳实践”还没有建立?

4 个答案:

答案 0 :(得分:27)

对于SymbolSource,我认为最佳做法是:

  1. 仅将二进制+内容包发布到nuget.org(或任何其他生产Feed)
  2. 将调试二进制+内容包推送到开发Feed:
      预置
    • on myget.org
    • 在nuget.org上作为预发布包。
  3. 将release和调试二进制+符号包推送到symbolsource.org或任何其他符号存储区。
  4. 虽然我们正处于这种状态,但是一种常见的误解是,.NET中的发布和调试版本确实存在很大差异,但我假设差异化在这里是因为各种代码可能包含或可能不包含在任何一个版本中,如Debug.Asserts。

    也就是说,将这两种配置推送到SymbolSource是非常值得的,因为您根本不知道何时需要调试生产代码。远程生产使其更难。当发生这种情况时,您将需要从工具中获得的帮助。我显然不希望任何人。

    关于版本控制还有一个问题需要考虑:在2个不同的软件包(内置调试和发布版本)中共享1个版本号是否正确? SymbolSource会接受这一点,因为它在单独的构建模式分支中提取包并存储二进制文件,因此只允许NuGet相应地标记包。目前无法确定包是调试还是释放模式。

答案 1 :(得分:4)

我完全赞同你的结论。 NuGet使用RELEASE和SymbolSource打包并进行调试。直接进入软件包似乎非常罕见,并且启用优化的偶尔调试失误可能是可以接受的。

如果确实存在问题,我认为理想的解决方案是让NuGet支持它。例如,假设在调试时,它可以使用SymbolSource包中包含的版本替换版本DLL。

理想情况下,会发生的情况是nuget pack SomePackage -Symbols针对发布版本会创建一个发布nuget包,而是一个调试符号包。并且VS插件将被更新为足够智能,以便在调试器中运行时查看关联并引入Debug程序集并加载它们。有点疯狂,但会很有趣。

然而,我只是没有看到有足够的人抱怨这一点,目前它是值得的。

NuGet团队接受拉取请求。 :)

答案 2 :(得分:2)

自从OP发布以来已经有8年了,因此,我将与现在使用的内容一脉相承。

有两种方法“进入 ” NuGet程序包:

1。 PDB的分布

.symbols.nupkg符号包是considered as legacy,并已被发布到Symbol Server.snupkg包所取代。大多数供应商都支持此功能, Azure DevOps feature request仍在“审核中”的最大局外人(感谢@alv提供链接)。

这里是official instructions。只需将这两行添加到csproj文件中:

<PropertyGroup>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

在使用者方面,请确保已为NuGet.org(或Azure等)Symbol Server配置了IDE,以便在调试时允许stepping into package code

2。源链接。链接实际代码

在某些情况下,由于MSIL / JIT的优化,PDB可能会隐藏源代码的某些细节。因此,在调试时,有一种“ 逐步进入” NuGet实际来源的方法。它在.NET Foundation中称为Source Link,“ 一种语言和源代码控制不可知系统,可为二进制文件提供源代码调试体验”。

Visual Studio 15.3+和所有主要供应商都支持它(也支持私有存储库)。

设置(official docs)很简单–只需向项目文件添加开发依赖项(取决于您的仓库的类型)以及一些标志即可:

<PropertyGroup>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

在“ 5 steps to better NuGet package”中进一步了解此主题。

答案 3 :(得分:1)

调试目录中Creating and Publishing A Symbol Package引用文件中的示例作为dll和pdb文件的源。

  

指定符号包内容

     

符号包可以按约定,按照上一节中描述的方式构建的文件夹构建,也可以使用files部分指定其内容。如果您想构建前面描述的示例包,可以将它放入您的nuspec文件中:

<files>
  <file src="Full\bin\Debug\*.dll" target="lib\net40" /> 
  <file src="Full\bin\Debug\*.pdb" target="lib\net40" /> 
  <file src="Silverlight\bin\Debug\*.dll" target="lib\sl40" /> 
  <file src="Silverlight\bin\Debug\*.pdb" target="lib\sl40" /> 
  <file src="**\*.cs" target="src" />
</files>

由于发布符号的目的是允许其他人在调试时逐步执行代码,因此发布用于调试的代码版本似乎最为谨慎,而不会进行可能影响代码步骤的优化。