Roslyn -- the C# compiler platform -- is a .NET Standard 2.0 library, meaning that it can run on both .NET Framework 4.6.1+ and .NET Core 2.0+(1).
Visual Studio, which includes MSBuild, runs on .NET Framework. When you build a project using Visual Studio (or directly using MSBuild), it runs Roslyn on .NET Framework. Visual Studio knows how to process both SDK-style csprojs and the legacy non-SDK-style csprojs, and invoke Roslyn accordingly. The version of Roslyn which is used is tied to the Visual Studio version.
dotnet build
is a separate tool, and is a .NET Core application. It knows how to build SDK-style csprojs only, and it does this by running Roslyn on .NET Core. Roslyn is distributed with the .NET Core SDKs, and dotnet build
loads Roslyn from one of these installed SDK versions (normally the latest).
These two ways of building a C# project are more-or-less equivalent, and they invoke the same compiler code. However, they differ on where they can run (Visual Studio is .NET Framework and Windows-only, dotnet build
is .NET Core and can run on multiple platforms), and whether they can build legacy non-SDK-style csprojs. dotnet build
is also a bit nicer to use from the command-line.
Note that the runtime which Roslyn is loaded into has no bearing on the compiled IL which Roslyn can emit: Roslyn running on .NET Framework can emit IL which is executed by .NET Core just fine, and vice versa.
If you are using analyzers which target .NET Core (unlikely, as Analyzers are encouraged to target .NET Standard 2.0), these will only run from dotnet build
.
(1) I'm using ".NET Core" to refer to both .NET Core and .NET 5+.
dotnet build
runs on .NET Core. They are by-and-large equivalent, although there are differences (e.g. Analyzers which target .NET Core/5 will only run underdotnet build
). MSBuild can handle non-SDK-style projects, whereasdotnet build
can only handle SDK-style projects (remember that the compiler itself doesn't interpret .csproj files) – Henriondotnet build
does however mean that the compiler can be run on targets which don't support .NET Framework (e.g. Linux), and it's a much nicer interface overall for command-line use – Henriondotnet build
loads the compiler from one of the installed SDKs, so you can upgrade it by installing a later SDK – Henrion