如何編寫基於 Microsoft.NET.Sdk 的跨平臺的 MSBuild Target(附各種自帶的 Task)

我之前寫過一篇 理解 C# 項目 csproj 文件格式的本質和編譯流程,其中,Target 節點就是負責編譯流程的最關鍵的節點。但因爲篇幅限制,那篇文章不便詳說。於是,我在本文說說 Target 節點。


Target 的節點結構

<Target> 內部幾乎有着跟 <Project> 一樣的節點結構,內部也可以放 PropertyGroupItemGroup,不過還能放更加厲害的 Task。按照慣例,我依然用思維導圖將節點結構進行了總結:

在這裏插入圖片描述
▲ 上面有綠線和藍線區分,僅僅是因爲出現了交叉,怕出現理解歧義

<Hash><WriteCodeFragment> 都是 Task。我們可以看到,Task 是多種多樣的,它可以佔用一個 xml 節點。而本例中,WriteCodeFragment Task 就是生成代碼文件,並且將生成的文件作爲一項 Compile 的 Item 和 FileWrites 的 Item。在 理解 C# 項目 csproj 文件格式的本質和編譯流程 中我們提到 ItemGroup 的節點,其作用由 Target 指定。所有 Compile 會在名爲 CoreCompileTarget 中使用,而 FileWrites 在 Microsoft.NET.Sdk 的多處都生成了這樣的節點,不過目前從我查看到的全部 Microsoft.NET.Sdk 中,發現內部並沒有使用它。

Target 執行的時機和先後順序

既然 <Target> 內部節點很大部分跟 <Project> 一樣,那區別在哪裏呢?<Project> 裏的 <PropertyGroup><ItemGroup> 是靜態的狀態,如果使用 Visual Studio 打開項目,那麼所有的狀態將會直接在 Visual Studio 的項目文件列表和項目屬性中顯示;而 <Target> 內部的 <PropertyGroup><ItemGroup> 是在編譯期間動態生成的,不會在 Visual Studio 中顯示;不過,它爲我們提供了一種在編譯期間動態生成文件或屬性的能力。

總結起來就是——Target 是在編譯期間執行的

不過,同樣是編譯期間,那麼多個 Target,它們之間的執行時機是怎麼確定的呢?

一共有五個屬性決定了 Target 之間的執行順序:

  • Project 的屬性
    • InitialTargets 項目初始化的時候應該執行的 Target
    • DefaultTargets 如果沒有指定執行的 Target,那麼這個屬性將指定執行的 Target
  • Target 的屬性
    • DependsOnTargets 在執行此 Target 之前應該執行的另一個或多個 Target
    • BeforeTargets 這是 MSBuild 4.0 新增的,指定應該在另一個或多個 Target 之前執行
    • AfterTargets 這也是 MSBuild 4.0 新增的,指定應該在另一個或多個 Target 之後執行

通過指定這些屬性,我們的 Target 能夠被 MSBuild 自動選擇合適的順序進行執行。例如,當我們希望自定義版本號,那麼就需要趕在我們此前提到的 GenerateAssemblyInfo 之前執行。

Microsoft.NET.Sdk 爲我們提供的現成可用的 Task

有 Microsoft.NET.Sdk 的幫助,我們可以很容易地編寫自己的 Target,因爲很多功能它都幫我們實現好了,我們排列組合一下就好。

提供的 Task 還有更多,如果上面不夠你寫出想要的功能,可以移步至官方文檔翻閱:MSBuild Task Reference - Visual Studio - Microsoft Docs

使用自己寫的 Task

我有另外的一篇文章來介紹如何創建一個基於 MSBuild Task 的跨平臺的 NuGet 工具包 - 呂毅。如果希望自己寫 Ta

差量編譯

如果你認爲自己寫的 Target 執行比較耗時,那麼就可以使用差量編譯。我另寫了一篇文章專門來說 Target 的差量編譯:每次都要重新編譯?太慢!讓跨平臺的 MSBuild/dotnet build 的 Target 支持差量編譯 - 呂毅


參考資料


我的博客會首發於 https://blog.walterlv.com/,而 CSDN 會從其中精選發佈,但是一旦發佈了就很少更新。

如果在博客看到有任何不懂的內容,歡迎交流。我搭建了 dotnet 職業技術學院 歡迎大家加入。

知識共享許可協議

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名呂毅(包含鏈接:https://walterlv.blog.csdn.net/),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫

發佈了420 篇原創文章 · 獲贊 254 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章