msbuild icon indicating copy to clipboard operation
msbuild copied to clipboard

Use documented item group in FindInvalidProjectReferences

Open jkoritzinsky opened this issue 1 year ago • 1 comments

Context

Today, GetReferenceTargetPlatformMonikers and FindInvalidProjectReferences use TargetPathWithTargetPlatformMoniker instead of the documented _ProjectReferenceTargetPlatformMonikers item group for the project reference gathering/validation.

This causes a violation in the ProjectReference protocol, leading to multiple items being returned from GetTargetPath and the default (Build) target. Returning multiple items from these targets can cause usability problems and unexpected behaviors.

Below is a simplified use case of the one that hit this bug:

A/A.csproj:

<Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
          <TargetFramework>net8.0</TargetFramework>
      </PropertyGroup>
</Project>

B/B.csproj:

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
       <FindInvalidProjectReferences>true</FindInvalidProjectReferences>
       <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
       <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    </PropertyGroup>
   <ItemGroup>
       <ProjectReference Include="../A/A.csproj" />
   </ItemGroup>
</Project>

C/C.csproj

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
       <OutputType>Exe</OutputType>
       <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
       <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    </PropertyGroup>
   <ItemGroup>
       <ProjectReference Include="../A/A.csproj" Aliases="A" />
       <ProjectReference Include="../B/B.csproj" Aliases="B" />
   </ItemGroup>
</Project>

C/Program.cs

extern alias A; // Csc errors here with "alias not found"
                       // because the reference to B.csproj added items for A.dll and B.dll with the B alias metadata
                       // which overrode the item returned by A.csproj, the A.dll with the A alias metadata
Console.WriteLine("Hello world");

Changes Made

Use the documented item group instead of reusing TargetPathWithTargetPlatformMoniker.

Testing

Local hacking. I'd like to add an end-to-end test, but I'm not sure where is the best place to do so here.

Notes

This was discovered in a project that uses the Microsoft.WindowsAppSdk, which sets FindInvalidProjectReferences to true in some scenarios.

The user was able to work around this bug by changing the order of the ProjectReference items in their equivalent of C.csproj.

jkoritzinsky avatar Jun 10 '24 23:06 jkoritzinsky

For context, I hit this in https://github.com/Sergio0694/ComputeSharp/pull/813, and it completely broke my build due to multiple projects failing due to this issue (in one case due to missing/incorrect reference aliases, in another case because ReferenceOutputAssembly was being ignored). Special thanks to Jeremy for investigating this and both figuring out a workaround as well as creating this PR 🙂

Sergio0694 avatar Jun 12 '24 04:06 Sergio0694

I assume that this could be a simple copy-paste mistake since git blame seems to stop at v15!

Internal link to change from (exactly!) 11 years ago: https://vstfdevdiv.corp.microsoft.com/DevDiv2/DevDiv/_versionControl/changeset/1033157

Add designtime or buildtime warning when referencing Dev12/WinBlue projects from Dev11/Win8 C++ projects

No details in the changeset to indicate that this was intentional.

rainersigwald avatar Jul 31 '24 22:07 rainersigwald