msbuild
msbuild copied to clipboard
Use documented item group in FindInvalidProjectReferences
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.
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 🙂
I assume that this could be a simple copy-paste mistake since
git blameseems to stop atv15!
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.