Project
node starts to support the Sdk
attribute since MSBuild release the 15.0 version which is embedded in Visual Studio 2017. For the Sdk
attribute, the C# project file whose file extension is csproj becomes much more powerful and extensible.
We’ll try to read the source code of Microsoft.NET.Sdk
which is the default Sdk value of C#.NET project and try to write some creative extension of compiling.
This post is written in multiple languages. Please select yours:
Where to find the source code of Microsoft.NET.Sdk
Search Microsoft.NET.Sdk
using Everything or Wox, I find that multiple versions are installed in my computer. As I’ve installed the .NET Core 2.1, the location of my latest version is C:\Program Files\dotnet\sdk\3.0.100-preview6-012264
. The official document How to: Reference an MSBuild Project SDK says that if you implement your own Sdk, you can also push it to
▲ Search Microsoft.NET.Sdk
▲ The Sdk folder on my computer
The NuGet part of Microsoft.NET.Sdk
is on GitHub:
The folder structure of Microsoft.NET.Sdk
When clicking into the Microsoft.NET.Sdk
folder, we can find that the folder structure is very similar to the NuGet folder structure.
I’ve written some posts talking about the NuGet folder structure but unfortunately they are all not in English:
- How to Write a Cross-Platform NuGet Tool Package Base on MSBuild Task
- How to Write a Cross-Platform NuGet Tool Package Base on Command Line Application
Microsoft have some official document talking about the NuGet folder structure How to create a NuGet package from a convention-based working directory.
But there exists an extra Sdk
folder for the Sdk
kind of NuGet package.
The Sdk.props
file and the Sdj.targets
file will be imported by default and Microsoft’s official document also mentions it here: How to: Reference an MSBuild Project SDK - Visual Studio. It says that the two code blocks are actually the same:
1 2 3 4 5 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net46</TargetFramework> </PropertyGroup> </Project>
1 2 3 4 5 6 7 8 9 10 11 <Project> <!-- Implicit top import --> <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> <PropertyGroup> <TargetFramework>net46</TargetFramework> </PropertyGroup> <!-- Implicit bottom import --> <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> </Project>
Because of the default importation behavior, Sdk can do variaty of tasks when MSBuild or Roslyn build the .NET projects. The default Sdk Microsoft.NET.Sdk
is very extensible so that we can easily use it to customize out compiling behavior and I’ve mentioned these in the two non-English posts above.
The major targets of Microsoft.NET.Sdk
I try to search Target
node in the whole Sdk
folder and find out 174 Target
s. Don’t worry about the huge Target
amount because most of them are private by indicating the name with a _
prefix and some of them have the same name to override and wait to be overridden.
So the core compiling Target
is not so many and I pick up some core Target
here:
CollectPackageReferences
: Collect thePackageReference
items to resolve the package dependencies of the project.CoreCompile
The core compilingTarget
.GenerateAssemblyInfo
: Generate theAssemblyInfo.cs
file which is usually written by developers manually before .NET Core published.Pack
: Pack current project into a NuGet package file whose extension is nupkg.GenerateNuspec
: Generate the nuspec file which is the meta info of the NuGet package.
Write creative extensions of compiling
I also find some creative Target
that inspires me:
1
2
3
<Target Name="DontRestore" BeforeTargets="Restore">
<Error Text="This project should not be restored" />
</Target>
▲ If a Restore
target exists, then report a compiling error.
1
2
3
4
5
6
<Target Name="ReferenceStaticLegacyPackage" BeforeTargets="CollectPackageReferences">
<ItemGroup>
<PackageReference Remove="LiteDB" />
<PackageReference Include="LiteDB" Version="2.0.2" />
</ItemGroup>
</Target>
▲ This is written by me to prevent a specific package named LiteDB
to be upgrade. I post this method in my another non-English post.
References
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/read-microsoft-net-sdk-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。