使用dotnet和MSBuild构建.NET应用程序有什么区别?

57

我刚刚不得不第一次在没有使用Visual Studio的情况下进行一些构建,很明显,关于MSBuild和构建过程,我的知识存在一定的差距。

那么,以下两种构建过程有什么区别呢?


选项1:

dotnet build C:\Dev\trunk\Mvc.sln

这个选项使用“Build Engine version 16.8.3+39993bd9d for .NET” - 我认为这意味着这种方式可以用于.NET Core,因为它没有提到“Framework”?


选项2:

msbuild C:\Dev\trunk\Mvc.sln

此选项使用“Build Engine version 16.8.2+25e4d540b for .NET Framework”。


我的假设是,“dotnet build”命令只是使用MSBuild的简写方式。然而,它们提供的日志记录非常不同,并且它们都会产生不同的结果。


3
同样的编译器,不同的调用方式。编译器本身针对.NET Standard 2.0进行目标设置,并且可以在.NET Framework和.NET Core/5上运行。MSBuild(类似于VS)在.NET Framework上运行,而dotnet build在.NET Core上运行。它们基本上是等效的,尽管存在一些差异(例如,针对.NET Core/5的分析器只能在dotnet build下运行)。MSBuild可以处理非SDK样式的项目,而dotnet build只能处理SDK样式的项目(请记住,编译器本身不解释.csproj文件)。 - canton7
@canton7 感谢您的评论。在使用VS构建时,它是如何实现的呢?.NET Core项目会使用dotnet build,而.NET Framework项目则会使用msbuild吗? - Murphybro2
3
不,使用VS构建项目时,编译器总是运行在.NET Framework之上:VS实际上使用MSBuild。正在编译的应用程序的目标运行时(从技术上讲)完全独立于编译器本身当前所在的运行时:在.NET Framework上运行的Roslyn可以生成由.NET Core执行的IL代码。但是,dotnet build意味着编译器可以在不支持.NET Framework的目标平台上运行(例如Linux),而且它对于命令行使用来说是一个更好的界面。 - canton7
2
好的,非常清楚明白。感谢您花时间解释让我理解它,而不是因为简单就给我点踩! - Murphybro2
2
值得注意的是,编译器随 VS 一起发布,因此其版本与 VS 版本相对应,通过升级 VS 可以获得新的编译器版本。编译器也包含在 .NET SDK 中,dotnet build 从已安装的 SDK 之一加载编译器,因此您可以通过安装较新的 SDK 来升级它。 - canton7
@canton7 你的最后一条评论恰好符合我的想法,再次感谢你提供的信息。如果你愿意将所有这些信息打包成一个漂亮的答案呈现出来,我会很高兴接受它。这是我在其他地方难以找到的信息(至少对我来说易于理解的格式),我发现你的评论非常有帮助。 - Murphybro2
2个回答

88

Roslyn 是 C# 编译器平台,是一个 .NET Standard 2.0 库,这意味着它可以在 .NET Framework 4.6.1+ 和 .NET Core 2.0+ 上运行(1)

Visual Studio 包括 MSBuild,在 .NET Framework 上运行。当您使用 Visual Studio 构建项目(或直接使用 MSBuild),它会在 .NET Framework 上运行 Roslyn。Visual Studio 知道如何处理 SDK 样式 csproj 和传统的非 SDK 样式 csproj,并相应地调用 Roslyn。所使用的 Roslyn 版本与 Visual Studio 版本绑定。

dotnet build 是一个单独的工具,是一个 .NET Core 应用程序。它只知道如何构建 SDK 样式的 csproj,并通过在 .NET Core 上运行 Roslyn 来实现此功能。Roslyn 与 .NET Core SDKs 一起分发,dotnet build 从其中一个已安装的 SDK 版本(通常是最新版)中加载 Roslyn。

这两种构建 C# 项目的方式基本相同,并调用相同的编译器代码。但是,它们在可运行的位置上有所不同(Visual Studio 是 .NET Framework 和仅限于 Windows,dotnet build 是 .NET Core 并且可以在多个平台上运行),以及它们是否可以构建传统的非 SDK 样式 csproj。从命令行使用 dotnet build 也会更加便捷。

请注意,Roslyn所加载的运行时与其可以生成的已编译IL代码无关:在.NET Framework上运行的Roslyn可以生成由.NET Core正常执行的IL代码,反之亦然。
如果您正在使用针对.NET Core目标的分析器(不太可能,因为推荐的是针对.NET Standard 2.0进行分析),则这些仅会从dotnet build中运行。
(1)我使用“ .NET Core”来指代.NET Core和.NET 5+。

5

MSBuild代表“Microsoft Build Engine”,是一个用于构建应用程序的平台。在跨平台的.NET Core出现之前,MSBuild是一种仅限于Windows的工具,并且只能作为Visual Studio许可证的一部分获得。

随着.NET Core的出现,可以通过安装.NET SDK来获取MSBuild,这不受Visual Studio和平台的限制。当使用.NET SDK通过CLI时,运行dotnet build等同于dotnet msbuild --restore。在幕后,后者命令也运行MSBuild,但在这种情况下,它是与.NET SDK一起提供的。

据我所知,在安装了Visual Studio的Windows上才能运行msbuild CLI命令(尚未在安装了VS for Mac的Mac上尝试过)。然而,这个命令等同于在具有.NET SDK的系统上运行dotnet msbuild。因此,在某种程度上,您提到的两个命令本质上是相同的,只是dotnet build在运行dotnet msbuild之前还会静默地调用项目恢复(如上所述,这等同于在安装了Visual Studio的Windows上运行msbuild)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接