Repository navigation
Honor MSBuild -mt in dotnet run preparation - #56837
jonathanpeppers wants to merge 3 commits into
Conversation
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>
|
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. |
There was a problem hiding this comment.
🟡 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-buildbehavior.
| 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
|
@jjonescz sorry, copilot opened this without me doing a full review -- I'll take it to draft, until I finish |
|
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 :) |
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>
Evangelink
left a comment
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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:1exits 0, printsAPP_ARGS=-m:1, and still records a maximum node count of32, not1.dotnet build Program.cs -mt -m:1warns that-m:1is unsupported for the file-based app, falls back to treating the.csfile as an MSBuild project, and fails withMSB4025(exit 1). The same build without-m:1succeeds.-maxCpuCount:1has 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.
There was a problem hiding this comment.
-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.

dotnet run -mtenables multithreading for the main build, but the separate preparation calls usedProjectInstance.Buildwithout applying that setting.Apply the MT setting to
Restore,ComputeAvailableDevices,DeployToDevice, andComputeRunArguments, 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 toCli.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-buildtest that checks MT mode and use of target-produced launch arguments. Document-mtand-mfor file-based MSBuild builds.Validation:
--no-build -mt:falsedid not.