Skip to content

Honor MSBuild -mt in dotnet run preparation - #56837

Open
jonathanpeppers wants to merge 3 commits into
mainfrom
jonathanpeppers-run-pipeline-mt-propagation
Open

jonathanpeppers wants to merge 3 commits into
mainfrom
jonathanpeppers-run-pipeline-mt-propagation

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

dotnet run -mt enables multithreading for the main build, but the separate preparation calls used ProjectInstance.Build without applying that setting.

Apply the MT setting to Restore, ComputeAvailableDevices, DeployToDevice, and ComputeRunArguments, including file-based runs that need to evaluate run arguments with --no-build. Keep the existing single-node limit, build lifetimes, logging, and target-produced project state.

Parse explicit MT switches in MSBuildArgs, reusing the switch helper moved to Cli.CoreUtils. Preserve boolean values, duplicate-switch precedence, and environment defaults without invoking the full MSBuild parser for preparation calls. Automatic response-file discovery is not added to those calls; the existing file-based build parser is unchanged.

Add focused parser and preparation tests, including a file-based --no-build test that checks MT mode and use of target-produced launch arguments. Document -mt and -m for file-based MSBuild builds.

Validation:

  • CLI, CLI utilities (including .NET Framework), and dotnet watch builds passed.
  • 154 selected CLI tests, 47 watch argument tests, and four file-based run-argument cases passed.
  • Android incremental build, deployment, and launch passed on Pixel 10 with the changed CLI. Both binlogs recorded strict MT; --no-build -mt:false did not.

Apply the parsed -mt setting to restore, device discovery, deployment, and run-argument target calls. Preserve the existing single-node and per-call build behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers requested a review from a team as a code owner October 29, 2026 15:15
Copilot AI balanced review requested due to automatic review settings October 29, 2026 15:15
@azure-pipelines

azure-pipelines Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Tests do not verify project preparation build modes under response files, explicit overrides, and environment settings, or file-based --no-build evaluation modes and resulting launch properties.

2 open issues
What changed in this PR

This PR makes dotnet run preparation targets honor the parsed MSBuild -mt setting while retaining their single-node limit.

Changes:

  • Shares the existing file-based concurrency parser across run preparation paths.
  • Uses an explicit build helper to apply multithreading to preparation targets.
  • Adds regression cases for enabled, disabled, default, and --no-build behavior.
File Description
test/​dotnet.Tests/​CommandTests/​Run/​GivenDotnetRunSelectsDevice.cs Adds binlog assertions for preparation targets’ multithreading mode.
src/​Cli/​dotnet/​Commands/​Run/​VirtualProjectBuildingCommand.cs Reuses the extracted concurrency parser.
src/​Cli/​dotnet/​Commands/​Run/​RunCommandSelector.cs Applies parsed multithreading to restore and device targets.
src/​Cli/​dotnet/​Commands/​Run/​RunCommand.cs Applies parsed multithreading to ComputeRunArguments.
src/​Cli/​dotnet/​Commands/​Run/​CommonRunHelpers.cs Hosts shared concurrency parsing and single-node build execution.

Review effort: Balanced

@jonathanpeppers

Copy link
Copy Markdown
Member Author

@jjonescz sorry, copilot opened this without me doing a full review -- I'll take it to draft, until I finish

@jonathanpeppers
jonathanpeppers marked this pull request as draft October 29, 2026 15:54
@jjonescz

jjonescz commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

FWIW, it seems my questions apply to code that was merely moved, not added, but I don't think I have reviewed the code previously, so I still have those questions :)

jonathanpeppers and others added 2 commits October 29, 2026 11:28
Reuse the switch helper from CoreUtils instead of running the full MSBuild parser for preparation calls. Leave file-based build parsing unchanged and cover file-based no-build target execution.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers marked this pull request as ready for review October 30, 2026 20:57
@jonathanpeppers
jonathanpeppers requested a review from a team as a code owner October 30, 2026 20:57
@jonathanpeppers jonathanpeppers changed the title Honor -mt in dotnet run preparation targets Honor MSBuild -mt in dotnet run preparation Oct 30, 2026

@Evangelink Evangelink left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One documentation issue: the advertised -m / -maxCpuCount CLI support does not match file-based command routing.

Note

This review was generated with AI assistance.

File-based builds that use MSBuild support these execution switches:

- `-mt` / `-multiThreaded`: enable multi-threaded MSBuild execution. Use `-mt:false` to disable it.
- `-m` / `-maxCpuCount`: set the maximum node count. This setting applies only when multi-threaded execution is enabled;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This advertises -m / -maxCpuCount as file-based CLI switches, but they don't currently reach the file-based builder. I rechecked this PR head (12.0.100-dev, MSBuild 18.13.0-1.26523.103) with an app printing its arguments and a target recording $(MSBuildNodeCount):

  • dotnet run Program.cs --no-cache --no-launch-profile -mt -m:1 exits 0, prints APP_ARGS=-m:1, and still records a maximum node count of 32, not 1.
  • dotnet build Program.cs -mt -m:1 warns that -m:1 is unsupported for the file-based app, falls back to treating the .cs file as an MSBuild project, and fails with MSB4025 (exit 1). The same build without -m:1 succeeds.
  • -maxCpuCount:1 has the same behavior in both commands.

LoggerUtility.TryGetMSBuildArgument recognizes -mt, but not these aliases, so run leaves them as application arguments and build no longer sees a single source-file argument after extraction.

Could we remove or qualify this bullet until the forwarding is implemented? If direct CLI support is intended, an end-to-end case should assert the node limit and that the switch is not passed to the app.

@JanProvaznik JanProvaznik Nov 2, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • -m / -maxCpuCount: set the maximum node count. This setting applies only when multi-threaded execution is enabled

-m and -mt should not be related this way. Run should support both independently, unless there is a good reason that blocks it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants