dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.72k stars 1.07k forks source link

How to make `dotnet run` invoke an MSBuild target? #31253

Closed jonathanpeppers closed 1 month ago

jonathanpeppers commented 1 year ago

Is your feature request related to a problem? Please describe.

In .NET 7, the ability to pass MSBuild properties was added to dotnet run.

Unfortunately, this does not work for .NET MAUI projects, as we actually need an MSBuild target to run in order to deploy and launch an application on a mobile device.

To get an idea of our implementation currently:

https://github.com/xamarin/xamarin-android/blob/0e4c29aabb2af023d3ff66f02d42c2b487575d85/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Application.targets#L15-L16

We set $(RunCommand) and $(RunArguments) to launch a new process that runs dotnet build -t:Run. At this point we don't know what MSBuild properties were passed to dotnet run, so we don't have a way to pass them along.

Describe the solution you'd like

If optional workloads could opt into a new setting like $(UseTargetForRun) (or choose a better name), it feels like the dotnet CLI should be able to invoke a Run target directly instead of using $(RunCommand) and $(RunArguments).

This would allow the MSBuild properties to pass through, and we aren't starting an unnecessary dotnet process.

Additional context

This is important for CLI scenarios for .NET MAUI.

rolfbjarne commented 1 year ago

See also https://github.com/dotnet/sdk/issues/18436.

marcpopMSFT commented 1 year ago

The options are either to do as suggested which would result in msbuild launching the process or we could run an additional target that returns the Command and Arguments that others could depend on to trigger their own targets. CC @rainersigwald for an opinion on having msbuild launching the process and what impact there might be.

Hiding these behind a property makes sense to limit performance impact.

Moving to 8.0.1xx for now as we've gotten more requests for this.

rainersigwald commented 1 year ago

No objection to having MSBuild invoke the thing directly (that's what's happening in the current implementation anyway, just through an additional process).

KalleOlaviNiemitalo commented 1 year ago

Command & arguments seems a bit more extensible, in that the caller could run the command in a debugger or a syscall tracer, without needing each project to support those. Might need the ability for the project to specify environment variables for the process though.

KalleOlaviNiemitalo commented 1 year ago

In the command & arguments implementation, if the developer wants to run some MSBuild targets rather than a built executable, then they can return "dotnet msbuild $(MSBuildProjectFullPath) -t:sometarget" as the command & arguments. Although it's not clear to me how the arguments should be quoted then; are the arguments are going to be just one string, or each argument as an item?

jonathanpeppers commented 1 year ago

Didn’t know this one had meme potential:

image

maddymontaquila commented 1 year ago

This would really help both C#DK and MAUI in VS Code - simplifies quite a bit of the user experience if they choose to use CLI to build

baronfel commented 1 year ago

Additional use cases that came up during discussion with @danroth27 that we need to consider here:

In all of these cases running a particular project also requires starting/coordinating some number of other projects/processes. MSBuild doesn't have great support for this kind of lifecycle management (correct me if I'm wrong @rainersigwald), so spawning these kind of daemonized processes could be complex to orchestrate - you can't just Exec task them in a Target because that Target won't complete.

So a full solution should cover:

Perhaps some kind of protocol is relevant here - the CLI could call some kind of target that would return MSBuild ITaskItems that described what processes to run, targets to run, etc, then the CLI could orchestrate

baronfel commented 1 year ago

Alternatives here might be to go the route that Android-on-Rust has and make a separate .NET Tool that MAUI users might use that could do whatever orchestration you needed: dotnet maui run instead of dotnet run. That raises questions about how MAUI users would acquire that tool - we might need to investigate Workloads providing .NET Tools for example - but would free individual teams to satisfy whatever use cases they needed without being dependent on the core SDK. However, that could weaken the nice SDK-driven workflow that we've gotten users to buy into over the lifetime of .NET.

baronfel commented 1 year ago

Quick GitHub search query for folks that have overridden/actually used the Run target is here.

I'm broadly seeing two categories:

baronfel commented 1 year ago

One other thing to consider - VS/VSCode/CLI also use Launch Profiles to impact how the application is run. Anything we do here might impact them and we need to take that into account.

danroth27 commented 1 year ago

@javiercn

baronfel commented 1 month ago

Closing this as we implemented it in #42155!