With the move from project.json
to the new csproj
format introduced with VS2017, I'm struggling to understand the difference between the dotnet
cli and the new msbuild
and when to use one over the other.
1) To build a new csproj
netstandard library from the command line, should I be calling the dotnet
cli (for example dotnet restore
dotnet build
) or use msbuild
(for example msbuild ExampleNetstandard.sln
).
2) Also, my understanding is that there are two versions of msbuild
, one built on the full framework and another targeting dotnet core
. Is this correct? Should I always use the dotnet version
3) Is dotnet cli
standalone or does it require msbuild
to be installed?. For instance when you install the dotnet SDK does this install msbuild as well? If so is this different to the version that is installed with vs2017?
Description. The dotnet msbuild command allows access to a fully functional MSBuild. The command has the exact same capabilities as the existing MSBuild command-line client for SDK-style projects only. The options are all the same.
NET Core applications are typically built using MSBuild or dotnet.exe . MSBuild and dotnet.exe don't require Visual Studio to be installed, but in order to use them, the following prerequisites are required on a build server: Visual Studio Build Tools installed.
RuntimeIdentifiers. The RuntimeIdentifiers property lets you specify a semicolon-delimited list of runtime identifiers (RIDs) for the project. Use this property if you need to publish for multiple runtimes. RuntimeIdentifiers is used at restore time to ensure the right assets are in the graph.
- To build a new csproj netstandard library from the command line, should I be calling the dotnet cli (for example dotnet restore dotnet build) or use msbuild (for example msbuild ExampleNetstandard.sln).
Both do fine as currently dotnet
is built on top of msbuild
. So it's a matter of taste. You could also call msbuild tasks by using the dotnet CLI. (dotnet msbuild <msbuild_arguments>
)
In the beginning, all the .NET core stuff was only in dotnet
and not in msbuild
. This was cumbersome as a lot of stuff that was already built on msbuild
wasn't working well with dotnet
out of the box (e.g. Xamarin). So they moved the stuff to msbuild
and build dotnet
on top of msbuild
.
dotnet
has some features that aren't in msbuild
, like dotnet new
. In my opinion, dotnet
is easier to use than msbuild
, so I prefer dotnet
.
To make it more clear, I have added a comparison between msbuild
and dotnet
at the end of my post.
- Also, my understanding is that there are two versions of msbuild, one built on the full framework and another targeting dotnet core. Is this correct? Should I always use the dotnet version
There is only one msbuild. dotnet CLI is using msbuild:
Since CLI uses MSBuild as its build engine, we recommend that these parts of the tool be written as custom MSBuild targets and tasks, since they can then take part in the overall build process
https://docs.microsoft.com/en-us/dotnet/articles/core/tools/extensibility
The older version of msbuild
was lacking the .NET Core support. Maybe that's the other version ;)
I agree it's confusing, as it was very different a few months ago.
- Is dotnet cli standalone or does it require msbuild to be installed?. For instance when you install the dotnet SDK does this install msbuild as well? If so is this different to the version that is installed with vs2017?
I wasn't sure about this, but it was easy to test. I have removed all msbuild.exe and it still worked. Found out it's using the msbuild.dll in the SDK folder. e.g. "C:\Program Files\dotnet\sdk\1.0.3\MSBuild.dll"
If you remove that one, there is a proof:
msbuild.dll is actually msbuild.exe, as you can see in the properties:
If you look into the code of the dotnet CLI, you can see it's generating msbuild
commands.
For example dotnet restore
, is created by the RestoreCommand
class inside dotnet CLI.
A stripped version:
public class RestoreCommand : MSBuildForwardingApp { ... public static RestoreCommand FromArgs(string[] args, string msbuildPath = null) { var result = parser.ParseFrom("dotnet restore", args); ... var msbuildArgs = new List<string> { "/NoLogo", "/t:Restore", "/ConsoleLoggerParameters:Verbosity=Minimal" }; ... return new RestoreCommand(msbuildArgs, msbuildPath); } public static int Run(string[] args) { RestoreCommand cmd; try { cmd = FromArgs(args); } catch (CommandCreationException e) { return e.ExitCode; } return cmd.Execute(); } ... }
You can see dotnet restore
is just calling msbuild /NoLogo /t:Restore /ConsoleLoggerParameters:Verbosity=Minimal
If you check RestoreCommand
in the time of dotnet v1.0.0 RC2
, it wasn't using msbuild
but was calling nuget
directly.
return NuGet3.Restore(args, quiet);
dotnet
and msbuild
I made a mapping between dotnet
and msbuild
. It's not complete, but the important commands are there.
Dotnet | Msbuild | Remarks -----------------------|--------------------------------------------|--------------------------------- Add | | -----------------------|--------------------------------------------|--------------------------------- Build | /t:Build | -----------------------|--------------------------------------------|--------------------------------- Build --no-incremental | /t:Rebuild | -----------------------|--------------------------------------------|--------------------------------- Clean | /t:clean | -----------------------|--------------------------------------------|--------------------------------- Complete | | -----------------------|--------------------------------------------|--------------------------------- Help | | Help! -----------------------|--------------------------------------------|--------------------------------- List | | -----------------------|--------------------------------------------|--------------------------------- Migrate | - | -----------------------|--------------------------------------------|--------------------------------- Msbuild | | Forwarding all -----------------------|--------------------------------------------|--------------------------------- New | | -----------------------|--------------------------------------------|--------------------------------- Nuget | | * -----------------------|--------------------------------------------|--------------------------------- Pack | /t:pack | -----------------------|--------------------------------------------|--------------------------------- Publish | /t:publish | -----------------------|--------------------------------------------|--------------------------------- Remove | | -----------------------|--------------------------------------------|--------------------------------- Restore | /NoLogo /t:Restore | | /ConsoleLoggerParameters:Verbosity=Minimal | -----------------------|--------------------------------------------|--------------------------------- Run | /nologo /verbosity:quiet | | /p:Configuration= /p:TargetFramework | -----------------------|--------------------------------------------|--------------------------------- Sln | | Not in msbuild -----------------------|--------------------------------------------|--------------------------------- Store | /t:ComposeStore | -----------------------|--------------------------------------------|--------------------------------- Test | /t:VSTest /v:quiet /nologo | -----------------------|--------------------------------------------|--------------------------------- Vstest | | Forwarding to vstest.console.dll
*
dotnet nuget: Adding/removing packages to csproj, also limited set of nuget.exe, see comparison
PS no markdown tables in SO :(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With