让你发布的nuget包支持源代码调试
前情概要
在不久的从前(也还是要以年为单位哈), 我们如果需要调试第三方代码, 或者框架代码很麻烦. 需要配置symbols, 匹配原始代码路径等.
为此, MS推出了 Source Link 功能, 详细的介绍请查看官方repo 的 readme.
Copy+google翻译过来的介绍:
Source Link 是一个与语言和源代码控制无关的系统,用于为二进制文件提供一流的源代码调试体验。该项目的目标是让任何构建NuGet 库的人都能够毫不费力地为其用户提供源代码调试。Microsoft 库(例如 .NET Core 和 Roslyn)已启用 Source Link。Microsoft 支持源链接。
Source Link 是一组包和规范,用于描述可以嵌入到符号、二进制文件和包中的源代码控制元数据。
Visual Studio 15.3+ 支持在调试时从符号读取源链接信息。它为用户下载并显示适当的特定于提交的源,例如来自raw.githubusercontent,启用断点和对任意 NuGet 依赖项的所有其他源调试体验。Visual Studio 15.7+ 支持从需要身份验证的私有 GitHub 和 Azure DevOps(以前的 VSTS)存储库下载源文件。
在最初的来源链接的实现是通过提供@ctaggart。谢谢!.NET 团队和 Cameron 共同努力使此实现在 .NET Foundation 中可用。
如果您是从原始 Source Link 文档到达这里的 - 您不需要使用SourceLink.Create.CommandLine. 您只需要安装下面列出的软件包。
到目前为止, 主流的nuget package 都已经支持了. 例如MS官方的包, protobuf-net, Newtonsoft.Json 等.
首先, 先介绍如何源代码调试支持Sourcelink的包.
我们仅需要修改vs的配置.
- 首先, 禁用
Just My Code功能 - 然后, 启用
Source Server Support和Source Link Support

我们就可以 F11 进入源代码了
就是这么简单, 就是这么顺滑.

然后, 本文的重点来了, 让我们自己的nuget包也支持这么棒的功能!!!
为我们的项目添加SourceLink支持
<Project>
<PropertyGroup>
<DebugType>embedded</DebugType>
<DebugSymbols>true</DebugSymbols>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
<!--<PropertyGroup Condition="'$(GITLAB_CI)' == 'true'">-->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<Deterministic>true</Deterministic>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
</Project>
这些代码可以添加的项目的.csproj文件中, 也可以为整个solution的所有project添加.
为整个solution添加, 我们可以在.sln文件的同级目录下增加文件 Directory.Build.props, 然后把上面代码copy进行就可以了.

接下来简单解释一下这些改动都是啥意思, 其实在Source Link解释的非常清楚了. 强烈建议看官方文档.
- DebugType 为啥用 embedded呢? 首先它的意思是把pdb的信息直接打包到dll文件中.
- 它的好处
- 一个
.dll文件就够了, 不在要生成.dll和.pdb2个文件. - 在目前阶段, 不同的框架(nfx, netcore 2.x, 3.x, 5.x),不同的vs(msbuild)版本下, 对pdb文件的处理各不相同. 比如vs 16.10 和netcore 2.x 它在build或者release的时候就不copy nuget packages 里面的pdb文件. 当然这个问题官方也在解决,但是比较缓慢, 反正我知道这个问题就已经好几年了, 到目前位置github上的issue还在讨论来讨论去...
- 一个
- 坏处
- 比较明显的增加的文件的体积.
- 它的好处
- DebugSymbols 我想应该不用解释
- PublishRepositoryUrl 将源代码的git信息编译到dll和打包到nuget package 上.
- ContinuousIntegrationBuild 和 Deterministic 表示确定性编译. 具体解释请查看Here
- EmbedUntrackedSources 跟踪build生成的代码文件. 比如我有模板代码在build时生成, 或者由PublishRepositoryUrl生成的比如assemble attribute文件等.
没有设置的时候

设置好了的时候

- 添加
Microsoft.SourceLink.[your git repo]包, 比如我DEMO这个项目用的是gitlab, 那我添加的就是Microsoft.SourceLink.GitLab. 目前SouceLink支持github,gitlab,azure,bitbucket,gitweb,gitea.- PrivateAssets设置为All的意思是:这个包只有在编译调试的时候使用, 打包到nuget的时候它不会添加进去.
验证我们的dll或者pdb已经支持SourceLink了
首先我们先安装sourcelink工具.
dotnet tool install -g sourcelink
接着测试一下我们的dll是否已经支持了
sourcelink print-json .\protobuf-net.Core.dll
sourcelink print-urls .\protobuf-net.Core.dll

当然也可以用
sourcelink test .\protobuf-net.Core.dll

到这里就基本完成了, 把包发布到nuget package上就可以, 可以是nuget.org, 也可以是myget, 更可以你公司内部的私有nuget package 服务器.
如果你和我一样, 用的是gitlab的私有git repo, 那可以继续看下去.
为gitlab的私有源代码项目提供支持.
如果是gitlab的私有git repo. 在sourcelink test的时候会收到类似下面的错误
https://gitlab.com/myproject/mysourcecode.cs
error: url failed ServiceUnavailable: Service Temporarily Unavailable
sourcelink test failed
这是因为gitlab目前为止不支持基本身份验证, 另外对于如果你是github的私有repo不用担心. 只需要把Enable Source Link Support的下面的Fall back to GCM 选项勾起就可以了(参考我们仅需要修改vs的配置小节的截图).
具体的issue可以参考:
Add support for Git Credential Manager on Windows
Support private GitLab repositories
如果要解决这个问题 可以参考 https://github.com/rgl/gitlab-source-link-proxy 的解决方案.
如果只是临时的调试一下源代码可以有更简单粗暴的方法, 在vs中用Web Browesr 登录一下gitlab就完事了.

哈!, 就是这么简单粗暴.

最后, 一些有用的Links
- Producing Packages with Source Link
- How to debug NuGet packages using SourceLink
- Source Link MS官方文档
- Exploring .NET Core's SourceLink - Stepping into the Source Code of NuGet packages you don't own
让你发布的nuget包支持源代码调试的更多相关文章
- nuget服务器搭建,以及如何发布一个Nuget包
本文章主要介绍如何将本地dll打包成为一个Nuget包,并如何发布到自己的nuget服务器.章节如下 1. 本地dll如何打包,以及版本的更新 2. 在linux上搭建nuget.server 3. ...
- 在 VS 2013/2015 中禁用 nuget 包的源代码管理
对于加入源代码管理如TFS的解决方案,当使用nuget获取包时,下载的包并没有自动从源代码管理中排除,导致包(packages文件夹)会一同上传到服务器. 若要排除nuget包的源代码管理,须在 解决 ...
- NetCore偶尔有用篇:NetCore项目发布为Nuget包
一.简介 1.nuget大家已经不陌生. 2.netcore默认引用便是nuget,并处理了嵌套关系. 3.netcore已经支持直接编译生成nuget包. 4.本文介绍如何把自己建立的项目发布为nu ...
- .Net Framwork /.Net Core 发布为NuGet包
一.使用NuGet发布包 下载NuGet命令行工具: https://dist.nuget.org/win-x86-commandline/v5.8.0/nuget.exe 下载NuGet Packa ...
- 从一次解决Nancy参数绑定“bug”开始发布自己的第一个nuget包(上篇)
起因 最近,同事跟我说,他们负责的一个Api程序出现了一些很奇怪的事情.这个Api是为环保局做的一个扬尘质控大屏提供数据的,底层是基于Nancy做的.因为发现有些接口的数据出现异常,他就去调试了一下, ...
- 如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)
最近我将项目格式进行了升级,从旧的 csproj 升级成了新的 csproj:NuGet 包管理的方式也从 packages.config 升级成了 PackageReference.然而迁移完才发现 ...
- NEsper Nuget包
Esper是专门进行复杂事件处理(CEP)的流处理平台,Java版本为Esper,.Net版本为NEsper.Esper & NEsper可以方便开发者快速开发部署处理大容量消息和事件的应用系 ...
- .NET Core中创建和使用NuGet包
在.NET Core的项目中,如果我们要在项目中引用其它DLL文件,不应该直接在项目引用中添加DLL文件(虽然在.NET Core项目中也可以这么做),建议是去直接下载DLL文件所属的NuGet包.这 ...
- 使用批处理根据项目工程文件生成Nuget包并发布(支持.NET Core)
最近在使用之前自己编写的批处理给.NET Core项目打包时出问题了,发现之前的脚本根本不适用了,折腾了半天,总算解决了.因此在这里分享下经验,并且奉上整理好的脚本. Nuget包这里就不多介绍了,需 ...
随机推荐
- Docker Swarm(六)Label 节点标签与服务约束
前言 多节点 Swarm 集群下,可能节点的配置不同(比如 CPU.内存等),部署着不同类型的服务(比如 Web服务.Job服务等),当这些服务以 Service 或者 Stack 的形式部署到集群, ...
- libvirtd 启动成功,但却没有监听
现象: 执行 systemctl start libvirtd在其它机器上进行测试是否监听:virsh -c qemu+tcp://host/system libvirtd启动成功,没有报错,但却没有 ...
- 自动做bond的脚本
#!/bin/bash # 先备份原来的网卡配置文件 find /etc/sysconfig/network-scripts/ -type f -name "ifcfg*"|xar ...
- CentOS7安装vncserver(启动失败及连接黑屏解决办法)
CentOS7安装vncserver(启动失败及连接黑屏解决办法) 转载weixin_34167043 最后发布于2017-11-09 15:11:00 阅读数 42 收藏 展开 AutoSAR入门 ...
- Python 简单的龟鱼游戏
游戏编程:按一下要求定义一个乌龟类和鱼类并尝试编程 假设游戏场景为范围(x,y)为 0<=x<=10,0<=y<=10 游戏生成1只乌龟和10条鱼 他们的移动方向均随机 乌龟的 ...
- linux进阶之yum管理
一.部署私有repo源 1.官网下载需要的仓库: rsync -avrt --delete rsync://mirrors.ustc.edu.cn/centos/7/cloud/x86_64/open ...
- mysql基础之mariadb库管理和表管理语句
一.数据库管理语句 1.Syntax: CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [create_specification] ... cr ...
- Linux系统函数read()/write()/pread()/pwrite()的区别-(转自CSDN网络)
在Linux和UNIX中有很多的输入输出函数,有时真是让想跟它攀点关系的菜鸟们束手无策.先来看看都有哪些函数,通过解析与总结,看看能不能让大家能这些函数有个理性的认识,哦,原来是这么回事,也就算我没白 ...
- Flink-cdc实时读postgresql
由于公司业务需要,需要实时同步pgsql数据,我们选择使用flink-cdc方式进行 架构图: 前提步骤: 1,更改配置文件postgresql.conf # 更改wal日志方式为logicalwal ...
- TheSuperego 实验五 团队作业2:毕业设计选题系统
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs.com/nwnu-dai ...