Legacy-style project referencing duplicate multi-targetting projects don't set the TF on the reference correctly.
Issue Description
In certain scenarios, we get a error MSB4057: The target "GetTargetPath" does not exist in the project. due to the TF not properly being set on a project reference.
Steps to Reproduce
Proj1\Proj1.csproj:
<Project>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\proj2\proj2.csproj" />
<ProjectReference Include="..\Proj2\Proj2.csproj" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
(Note the project references are differently-cased)
Proj2\Proj2.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
</PropertyGroup>
</Project>
Commands:
msbuild /t:Restore Proj1\Proj1.csproj
msbuild Proj1\Proj1.csproj /p:BuildProjectReferences=false /bl
Expected Behavior
The build succeeds.
Actual Behavior
The build fails with proj2\proj2.csproj : error MSB4057: The target "GetTargetPath" does not exist in the project.
Analysis
The specific piece of logic which is failing to run is:
<AnnotatedProjects Condition="'@(AnnotatedProjects)' == '%(Identity)' and '%(AnnotatedProjects.NearestTargetFramework)' != '' and '%(AnnotatedProjects.HasSingleTargetFramework)' != 'true'">
<SetTargetFramework>TargetFramework=%(AnnotatedProjects.NearestTargetFramework)</SetTargetFramework>
</AnnotatedProjects>
That translates the NearestTargetFramework computed by GetReferenceNearestTargetFrameworkTask to SetTargetFramework, which is used when executing on project references.
Oddly, I couldn't seem to get this to repro if:
- Proj1 is an SDK-style project
- The duplicated
ProjectReferencedid not differ in case (I guess there's some case-sensitive deduplication somewhere?)
Also note that the /p:BuildProjectReferences=false just helps show off the error more easily. Without it, the TF is still not properly set so the project refernce is "fully" built instead of building only 1 TF. Furthermore, I believe in this case the referenced project's assembly isn't returned so isn't actually given to the referencing project's compiler, an obvious downstream problem.
Versions & Configurations
16.9.0-preview-21076-21+8ed151254 (but it repros for earlier versions too.)
@dfederm try adding <SetTargetFramework>TargetFramework=net472</SetTargetFramework> to your project reference. That solved the issue for me.
I have a repro when Proj1 is an SDK-style project. And I didn't need case differences in Proj2 references, two duplicate entries was enough to reproduce the bug.