前情概要
在不久的從前(也還是要以年為單位哈), 我們如果需要除錯第三方程式碼, 或者框架程式碼很麻煩. 需要配置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
和.pdb
2個檔案. - 在目前階段, 不同的框架(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就完事了.
哈!, 就是這麼簡單粗暴.