I'm opening this issue to gather feedback about our team renaming the MSBuild.exe assembly for .NET Core to MSBuild.dll. Full framework/net46 will not change.
Normally when building with xproj or project.json, applications are compiled as .dll files. MSBuild is not using this so our assembly is output as a .exe. I'd like update our build to emit a .dll instead. This does break some of our build scripts and unit tests which I'll be fixing in the same commit. However, we'd really like to communicate that this change is happening and get a better idea of who is affected. Also, please comment on the following questions if you have an opinion:
MSBuild.exe isn't really an EXE, it's a DLL that needs to run under dotnet.exe. Also, on other platforms, it doesn't make sense to ship an .exe.dotnet.exe?MSBuild.exe? Build scripts, code, other?Related to #1098 Target .NETCoreApp1.0 for MSBuild on .NET Core
FYI @AndyGerlicher, @rainersigwald, @eerhardt, @ericstj, @natemcmaster, @DustinCampbell, @nguerrera, @jaredpar. Please expand this as you see fit or ignore if you have no opinion. I'm not entirely sure who to loop in.
My two cents, in decreasing order of importance:
.dll instead of .exe. If we're going to use file extensions, I think we should stick with the existing convention.There is another convention to consider: consumers will expect a ".exe" file to be runnable. That's not the case with a .NET Core entrypoint assembly as you still need the dotnet.exe muxer to bootstrap the shared fx. If you try to execute MSBuild.exe standalone, the program dies because it can't find System.Runtime.
I could believe that I'm too influenced by cross-platform concerns and not giving enough weight to people double-clicking random stuff.
So is the .Net Core convention for runnable apps that the CoreCLR (CoreRun or dotnet?) is copied over and renamed to MyApp.exe, and that one loads the "true" executable, MyApp.dll?
If yes, is there some automated build task for this that the MSBuild repo can use?
@eerhardt
So is the .Net Core convention for runnable apps that the CoreCLR (CoreRun or dotnet?) is copied over and renamed to MyApp.exe, and that one loads the "true" executable, MyApp.dll?
Yes, this is a copy of "corehost.exe". Checkout https://github.com/dotnet/cli/blob/bbf9fe92cf9313f2b413a485ded73baf8637f3c0/Documentation/specs/runtime-configuration-file.md#what-produces-the-files-and-where-are-they for more details.
FWIW it's more than just a matter of copying corehost.exe. .NET Core apps are either framework-dependent or self-contained. At the moment, "dotnet-publish" automates putting all the files into the right place depending on which app model you're using.
For now, our NuGet package will contain a "framework-dependent/portable" application meaning it will only have our dependencies and a file telling the CLR what other dependencies should be loaded from a shared framework. A user will have to have the same version 1.0.X installed in order to run MSBuild.exe/MSBuild.dll.
As for convention, the current xproj/project.json always compile a .dll and only if you specify will it copy corerunhost.exe as MyApp.exe. So I don't think .NET Core developers will ever expect anything different. Only the people new to .NET Core could be confused but it will be more than just MSBuild. And I think it would be more confusing for the cross platform users to run MSBuild.exe.
@natemcmaster in your experience, has it been confusing to people that running apps means always executing them under dotnet.exe? Or do customers always execute dotnet run and don't think about it? Or has .NET Core been around long enough that everyone is used to this concept?
So, the intention is that users can download/extract this nupkg and run MSBuild directly from the command line?
For now, our NuGet package will contain a "framework-dependent/portable" application
In that case, MSBuild.dll is probably the right answer. Assuming you also include "MSBuild.runtimeconfig.json" and "MSBuild.deps.json", experienced users will know dotnet.exe MSBuild.dll is the right syntax. I doubt even experienced users would figure out that dotnet.exe MSBuild.exe is the right thing to do.
has it been confusing to people that running apps means always executing them under dotnet.exe?
I don't have enough data or experience to give a good answer. Maybe @brthor @eerhardt can share more insight?
has it been confusing to people that running apps means always executing them under dotnet.exe?
I haven't heard/read any confusion from users, but I also haven't been looking for it.
@blackdwarf ?
So, the intention is that users can download/extract this nupkg and run MSBuild directly from the command line?
App developers will reference this package so that their app can use the OM _or_ shell out to MSBuild.exe. We won't really be distributing MSBuild this way since this package is missing a bunch of stuff that you need in order to actually build. This is really just a base package containing the stuff that we own.
And yes, we will include a MSBuild.deps.json and an MSBuild.runtimeconfig.json to point to the shared framework and declare dependencies. https://github.com/Microsoft/msbuild/pull/1137/files#diff-5ad4d83ef32c236c8cad4b7b564e5d54
Any reason why you want the deps.json included in the nupkg @jeffkl ? Usually for tools this is generated from the tool lock file in the tool. In general there's not currently a way to guarantee that after the package is restored, the deps.json will be the same as when it was packed.
I was under the impression that we needed to include it because when you shell out to a new process, the CLR will look for a deps.json for the new executable. @eerhardt: Is the following true if I set it up where:
MSBuild.runtimeconfig.jsonMyApp with a reference to Microsoft.Build.Runtimedotnet run and their app shells out to dotnet MSBuild.dllWhich deps.json is loaded? I'm assuming since it's a new process, it will try to use MSBuild.deps.json which will fail. Hence the reason we need to include a deps.json.
@eerhardt no, there is no confusion around running apps this way that I'm aware of.
@jeffkl In that scenario, since msbuild.dll has a unified graph with the project, you would usually do dotnet --depsfile myproject.deps.json MSBuild.dll (prior to setting up the redist, this is how cli invoked msbuild)
It's also especially true in that case that the shipped deps file won't be the same as the "correct" one since the project can override whatever dependencies it wants. Shipping deps files isn't a thing that has been done AFAIK.
@brthor that will actually make it a lot easier for me if I don't have to include the deps.json. @eerhardt can you confirm, I can leave out the deps.json and users can use their own deps.json like Brian said:
In that scenario, since msbuild.dll has a unified graph with the project, you would usually do dotnet --depsfile myproject.deps.json MSBuild.dll (prior to setting up the redist, this is how cli invoked msbuild)
@jeffkl @eerhardt This is also how dotnet-test-xunit works, it uses the apps deps file.
Just an FYI - Users who are spawning a new process to invoke MSBuild will have to understand this. They will have to know to invoke dotnet --depsfile myproject.deps.json MSBuild.dll. They can't just say dotnet MSBuild.dll.
Is this something you would say is commonly understood by .NET Core developers? Is anything set in their process so they would know the name of their deps flie?
@jeffkl I wouldn't say it's common, it's ususally hidden by some abstraction
We've decided to go ahead with this change. Any dependency that uses MSBuild will need to update their logic when they take the newest version of the Microsoft.Build.Runtime NuGet package.
Apps will also need to specify their own deps.json file when shelling out to MSBuild ie dotnet --depsfile myproject.deps.json MSBuild.dll.
Thanks for everyone's feedback.
Most helpful comment
I could believe that I'm too influenced by cross-platform concerns and not giving enough weight to people double-clicking random stuff.