Skip to content

Conversation

@MichalPavlik
Copy link
Member

@MichalPavlik MichalPavlik commented Nov 26, 2025

Fixes #839

Context

In some cases dotnet needs to process MSBuild command line switches including response files (.rsp).

Changes Made

FEATURE_GET_COMMANDLINE workaround is no longer needed and it was removed. Parsing methods are now using IEnumerable<string> instead of string. Parsing logic was extracted from XMake to CommandLineParser class.

Testing

All existing tests are passing.
TODO: VMR check is required

Notes

MSBuildClient shouldn't be used outside MSBuild.

OutOfProcServerNode.BuildCallback delegate shouldn't be used anywhere. This delegate (and whole type) are public just because we are not able to expose internal types with MSBuild project due to shared sources in both projects. We had to use Experimental namespace instead.

How to review

All commits except the last one was a preparation - removing FEATURE_GET_COMMANDLINE constant and migration to vector of strings in our implementations. Last commit extracts the parsing logic to CommandLineParser class.

Copilot AI review requested due to automatic review settings November 26, 2025 14:13
Copilot finished reviewing on behalf of MichalPavlik November 26, 2025 14:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the FEATURE_GET_COMMANDLINE conditional compilation constant, standardizing the codebase to consistently use string[] for command line arguments across both .NET Framework and .NET (Core). The change simplifies the codebase by eliminating platform-specific code paths that are no longer necessary since .NET supports string[] entry points directly.

Key changes:

  • Added BuildEnvironmentHelper.IsRunningOnCoreClr property to distinguish runtime types
  • Updated all public and internal APIs to accept string[] instead of conditionally using string or string[]
  • Modernized test code to use C# collection expressions ([] instead of new[])
  • Added API compatibility suppressions for experimental APIs that changed signatures

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Shared/BuildEnvironmentHelper.cs Added IsRunningOnCoreClr property to detect .NET vs .NET Framework runtime
src/MSBuild/XMake.cs Removed conditional compilation, standardized to string[] parameters, prepends executable path on CoreCLR
src/MSBuild/MSBuildClientApp.cs Updated method signatures to consistently use string[] parameters
src/MSBuild.UnitTests/XMake_Tests.cs Modernized tests to use collection expressions
src/MSBuild.UnitTests/ProjectSchemaValidationHandler_Tests.cs Modernized tests to use collection expressions (with one interpolation bug)
src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs Modernized tests to use collection expressions
src/Directory.BeforeCommon.targets Removed FEATURE_GET_COMMANDLINE constant definition
src/Build/CompatibilitySuppressions.xml Added suppressions for breaking changes in experimental APIs
src/Build/BackEnd/Node/ServerNodeBuildCommand.cs Updated command line field and constructor to use string[]
src/Build/BackEnd/Node/OutOfProcServerNode.cs Updated BuildCallback delegate signature to accept string[]
src/Build/BackEnd/Client/MSBuildClient.cs Updated constructor and internal logic to use string[]
src/Build.UnitTests/Utilities_Tests.cs Modernized test to use collection expressions

@MichalPavlik MichalPavlik changed the title *DO NOT MERGE* Removing FEATURE_GET_COMMANDLINE constant *DO NOT MERGE* CmdLine parsing was extracted from XMake and the implementation is visible to dotnet (attempt 2) Dec 4, 2025

private static readonly char[] s_commaSemicolon = { ',', ';' };

private static CommandLineParser commandLineParser;
Copy link
Member Author

Choose a reason for hiding this comment

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

CommandLineParser can be instantiated, but XMake originally relied on static methods instead.

public static int Main(string[] args)
{
// When running on CoreCLR(.NET), insert the command executable path as the first element of the args array.
args = BuildEnvironmentHelper.IsRunningOnCoreClr ?
Copy link
Member Author

Choose a reason for hiding this comment

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

I retained the original logic that distinguishes between .NET and .NET Framework. Using Environment.CommandLine for both could produce unexpected results because of argument preprocessing in the SDK/CLI.

In the future, we can verify whether the .NET branch here is also applicable to .NET Framework.


internal IReadOnlyList<string> IncludedResponseFiles => includedResponseFiles ?? (IReadOnlyList<string>)Array.Empty<string>();

public (CommandLineSwitches commandLineSwitches, CommandLineSwitches responseFileSwitches) Parse(IEnumerable<string> commandLineArgs)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a convenient method for external clients (like CLI) that do not need to handle fullCommandLine or exeName.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Simplify back to Environment.GetCommandLineArgs

2 participants