dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.96k stars 4.02k forks source link

Duplicated project when reading sln when multiple TargetPlatforms are specified #56806

Open iamKunal opened 3 years ago

iamKunal commented 3 years ago

Version Used:

      <PackageReference Include="Microsoft.Build" Version="16.11.0" />
      <PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />
      <PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.11.0" />
      <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
      <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" />
      <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.11.0" />

Running on linux:

Linux 5.11.0-36-generic #40~20.04.1-Ubuntu SMP Sat Sep 18 02:14:19 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Steps to Reproduce:

  1. Cloned the repo https://github.com/structurizr/dotnet/tree/29f94266dfb0c4d876221e837c2f0443cc86bef6
  2. Run the following code for the Structurizr.sln present at the root of the repo:
    MSBuildLocator.RegisterDefaults();
    var workspace = MSBuildWorkspace.Create();
    var solutionFile = await workspace.OpenSolutionAsync(solutionPath);
    var projectsList = solutionFile.Projects.ToList();
  3. Also run the following (after step 2):
    var dependencySets = solutionFile.GetProjectDependencyGraph().GetDependencySets().ToList()

Expected Behavior:

  1. I should have received 5 projects in projectsList in step 2:
    [0]: {Structurizr.Core(netstandard2.0, net45)}
    [3]: {Structurizr.Client(netstandard2.0, net45)}

Actual Behavior:

  1. Instead I received 7 projects projectsList in total in step 2:

    Note that index 0,1 and 4,5 simply have two target platforms.

Secondly upon running step 3, I received 2 dependency sets: A.

  dependencySets[0].ToList()
  {Count = 6}
    [0]: {(ProjectId, #084645c9-2741-4b23-9d6d-009a989db8dc - /tmp/code/structurizr-dotnet/Structurizr.Core/Structurizr.Core.csproj)}
    [1]: {(ProjectId, #f169e5f6-3ef2-4311-b585-444ab8ed4e7c - /tmp/code/structurizr-dotnet/Structurizr.Core.Tests/Structurizr.Core.Tests.csproj)}
    [2]: {(ProjectId, #dca51dae-5f2a-4c65-a564-84a106fadf3c - /tmp/code/structurizr-dotnet/Structurizr.Client/Structurizr.Client.csproj)}
    [3]: {(ProjectId, #b6a44263-558d-4968-aeaa-a2c2b188a153 - /tmp/code/structurizr-dotnet/Structurizr.Client/Structurizr.Client.csproj)}
    [4]: {(ProjectId, #8bf0e88d-e7d5-49f3-88e2-be60c1425769 - /tmp/code/structurizr-dotnet/Structurizr.Client.Tests/Structurizr.Client.Tests.csproj)}
    [5]: {(ProjectId, #a6bdf8b0-41d5-4ada-840c-fc08c4b0b73c - /tmp/code/structurizr-dotnet/Structurizr.Examples/Structurizr.Examples.csproj)}

B.

  dependencySets[1].ToList()
  {Count = 1}
    [0]: {(ProjectId, #97b4a23e-00e5-4c51-9e45-4ea882bb16e3 - /tmp/code/structurizr-dotnet/Structurizr.Core/Structurizr.Core.csproj)}

Q1. Why am I receiving 7 projects instead of 5 in step 2, just by targetting 2 platforms and why is the split 5 and 2.

Q2. Another issue is, doing the same under Windows (VS Version 17.0.0 Preview 4.0) I get 5 and 2 dependency sets instead, index 2 or 3 from A moves to B. Why this different behavior across different OS?

jmarolf commented 3 years ago

First remove these nuget packages:

<PackageReference Include="Microsoft.Build" Version="16.11.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.11.0" />

you do not want to both use the msbuild locator and then load your own version of msbuild assemblies.

Why am I receiving 7 projects instead of 5 in step 2, just by targetting 2 platforms and why is the split 5 and 2.

each TFM is represented as a separate project by MSBuild. This has always been the case. For every separate TFM your project is built an additional time. These projects are built twice.

Another issue is, doing the same under Windows (VS Version 17.0.0 Preview 4.0) I get 5 and 2 dependency sets instead, index 2 or 3 from A moves to B. Why this different behavior across different OS?

I will need to check but are there no errors or warnings written out by the workspace in either case? Have you done the following to your workspace?

workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);
iamKunal commented 3 years ago

I will need to check but are there no errors or warnings written out by the workspace in either case? Have you done the following to your workspace?

workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);

I get the following warnings:

Windows:

[19:46:10 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"ProjectId": {"Id": "596fd731-b340-44d3-b176-ebde27abd9ba", "$type": "ProjectId"}, "Kind": "Warning", "Message": "Found project reference without a matching metadata reference: H:\\dev\\structurizr\\Structurizr.Client\\Structurizr.Client.csproj", "$type": "ProjectDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}

Linux:

[23:03:52 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"Kind": "Failure", "Message": "Msbuild failed when processing the file '/tmp/code/structurizr-dotnet/Structurizr.Core/Structurizr.Core.csproj' with message: /usr/share/dotnet/sdk/5.0.101/Microsoft.Common.CurrentVersion.targets: (1180, 5): The reference assemblies for .NETFramework,Version=v4.5 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks", "$type": "WorkspaceDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}
[23:03:52 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"Kind": "Failure", "Message": "Msbuild failed when processing the file '/tmp/code/structurizr-dotnet/Structurizr.Core/Structurizr.Core.csproj' with message: /usr/share/dotnet/sdk/5.0.101/Microsoft.Common.CurrentVersion.targets: (1180, 5): The reference assemblies for .NETFramework,Version=v4.5 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks", "$type": "WorkspaceDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}
[23:03:54 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"Kind": "Failure", "Message": "Msbuild failed when processing the file '/tmp/code/structurizr-dotnet/Structurizr.Client/Structurizr.Client.csproj' with message: /usr/share/dotnet/sdk/5.0.101/Microsoft.Common.CurrentVersion.targets: (1180, 5): The reference assemblies for .NETFramework,Version=v4.5 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks", "$type": "WorkspaceDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}
[23:03:54 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"Kind": "Failure", "Message": "Msbuild failed when processing the file '/tmp/code/structurizr-dotnet/Structurizr.Client/Structurizr.Client.csproj' with message: /usr/share/dotnet/sdk/5.0.101/Microsoft.Common.CurrentVersion.targets: (1180, 5): The reference assemblies for .NETFramework,Version=v4.5 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks", "$type": "WorkspaceDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}
[23:03:54 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"ProjectId": {"Id": "f4951a2c-8fcf-4841-94e7-8962622ee1a3", "$type": "ProjectId"}, "Kind": "Warning", "Message": "Found project reference without a matching metadata reference: /tmp/code/structurizr-dotnet/Structurizr.Core/Structurizr.Core.csproj", "$type": "ProjectDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}
[23:03:54 WRN] MSBuild Diagnostic Warning: Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace, {"Diagnostic": {"ProjectId": {"Id": "5e774eae-50f2-4ad3-aec9-b38c47ac273c", "$type": "ProjectId"}, "Kind": "Warning", "Message": "Found project reference without a matching metadata reference: /tmp/code/structurizr-dotnet/Structurizr.Client/Structurizr.Client.csproj", "$type": "ProjectDiagnostic"}, "$type": "WorkspaceDiagnosticEventArgs"}

On linux 4/6 warnings were due to .NET v4.5, 1 for Structurizr.Client.csproj was common across linux and windows, but Structurizr.Core.csproj was extra.

jmarolf commented 3 years ago

Do those linux build warnings show up of you do dotnet build? MSBuildWorkspace needs the project to be buildable, and have dotnet restore run on it.