msbuild icon indicating copy to clipboard operation
msbuild copied to clipboard

Legacy-style project referencing duplicate multi-targetting projects don't set the TF on the reference correctly.

Open dfederm opened this issue 4 years ago • 2 comments

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 ProjectReference did 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 avatar Feb 03 '21 16:02 dfederm

@dfederm try adding <SetTargetFramework>TargetFramework=net472</SetTargetFramework> to your project reference. That solved the issue for me.

daniatic avatar Mar 02 '24 07:03 daniatic

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.

vladimir-bukreev avatar May 01 '24 21:05 vladimir-bukreev