dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.2k stars 1.35k forks source link

[Bug]: Defining a project configuration for one project disables project negotiation for the whole solution graph #8854

Open MIchaelRShea opened 1 year ago

MIchaelRShea commented 1 year ago

Issue Description

Defining a project configuration for one project in a solution turns off dynamic platform negotiation for all projects in the solution graph.

This is because the conditional to turn off dynamic platform negotiation is <Target Name="_GetProjectReferencePlatformProperties" Condition="'$(EnableDynamicPlatformResolution)' == 'true' and '$(CurrentSolutionConfigurationContents)' == '' and '@(_MSBuildProjectReferenceExistent)' != ''">

'$(CurrentSolutionConfigurationContents)' == '' turns off negotiation on to broad of a level and this should instead be done on a per project basis.

Steps to Reproduce

Create a solution that references projects outside of that solution. define a configuration for all projects in the solution Make sure there is a need for negotiation in the inside to outside solution reference IE x64->AnyCPU Build said solution.

the inner to outer solution dependency will not do negotiation and therefore not build as AnyCPU

Expected Behavior

If a project does not have a configuration in a solution, platform negotiation should take place regardless of other projects configuration.

Actual Behavior

If a project does not have a configuration in a solution, but other projects do, platform negotiation will not take place for the project without a configuration.

Analysis

<Target Name="_GetProjectReferencePlatformProperties" Condition="'$(EnableDynamicPlatformResolution)' == 'true' and '$(CurrentSolutionConfigurationContents)' == '' and '@(_MSBuildProjectReferenceExistent)' != ''">

I believe '$(CurrentSolutionConfigurationContents)' == '' can be removed from this conditional since we already check for setplatforms on the individual project level

Versions & Configurations

No response

AR-May commented 1 year ago

@YuliiaKovalova Team triage: we need an initial investigation done on this issue.

JaynieBai commented 11 months ago

@MIchaelRShea I try to repro your issues with the sample solution I created. sample.zip

  1. ClassLibrary1.sln includes project ClassLibrary1, which has solution platform configuration AnyCPU. ClassLibrary1 project references one out of solution project ClassLibrary2.
  2. Set project ClassLibrary2 platform as x64.
  3. In the binlog, didn't find the [SetPlatform Negotiation] (https://github.com/dotnet/msbuild/blob/main/documentation/ProjectReference-Protocol.md#setplatform-negotiation) related task executed.

Could you have a look if there are any differences between your repro steps and mine?

JaynieBai commented 11 months ago

@JanKrivanek Could you help me take a look if there is something I misunderstood in the repro steps?

JanKrivanek commented 11 months ago

@JaynieBai - I haven't look deeper (as I'm not profficient in this area and would need to swap-in more context) - but first thing I see is that I'm not seeing the dynamic resolution opt-in (EnableDynamicPlatformResolution) in your projects (nor binlog) - could you add that and see?

@MIchaelRShea - since you flashed out the proposal for fix - would you be interested in creating a PR (or draft proposal PR) so that we can run it through our infra tests?