Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix VS complaining about missing projects in slns (continued) #68543

Merged
merged 9 commits into from
Apr 27, 2022

Conversation

ViktorHofer
Copy link
Member

@ViktorHofer ViktorHofer commented Apr 26, 2022

Contributes to #65552
Continuation of #68488

This PR updates the remaining out-of-band projects to fix the broken Visual Studio experience by making sure that the projects correctly build on-top of the targeting pack.

The changes are grouped by commits:

  1. Infra clean-up to simplify auto references and general clean-up in generators.targets
  2. Ref project file updates
  3. Src project file updates
  4. Test project file updates (2 projects were unnecessarily manually referencing targeting pack assemblies)

Remaining changes that will be submitted via separate pull requests:

  1. Minimizing projects' dependency graph. There are tons of unnecessary Reference and ProjectReference items which aren't required anymore as the referenced projects became full facade assemblies. Removing those from a leaf's graph makes the graph smaller and therefore the project's evaluation and build faster.
  2. Update all solution files to finally fix Visual Studio restore is broken as projects are missing from the dependency closure #65552

cc @ericstj (just FYI)

@ghost
Copy link

ghost commented Apr 26, 2022

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

Issue Details

Contributes to #65552
Continuation of #68488

This PR updates the remaining out-of-band projects that need to be updated to fix the broken Visual Studio experience by making sure that the projects correctly build on-top of the targeting pack.

The changes are grouped by commits:

  1. Infra clean-up to simplify auto references and general clean-up in generators.targets
  2. Ref project file updates
  3. Src project file updates
  4. Test project file updates (2 projects were unnecessarily manually referencing targeting pack assemblies)

Remaining changes that will be submitted via separate pull requests are:

  1. Minimizing projects' dependency graph. There are tons of unnecessary Reference and ProjectReference items which aren't required anymore as the referenced projects became full facade assemblies. Removing those from a leaf's graph makes the build faster.
  2. Update all solution files to finally fix Visual Studio restore is broken as projects are missing from the dependency closure #65552

cc @ericstj (just FYI)

Author: ViktorHofer
Assignees: ViktorHofer
Labels:

area-Infrastructure

Milestone: -

Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
<!-- Point MicrosoftNetCoreAppRefPackRefDir to the acquired targeting pack to use it later for AssemblySearchPaths resolution. -->
<PropertyGroup Condition="'$(TargetFrameworkVersion)' != 'v$(NetCoreAppCurrentVersion)'">
<MicrosoftNetCoreAppRefPackRefDir>%(ResolvedFrameworkReference.TargetingPackPath)\ref\net$(TargetFrameworkVersion.TrimStart('v'))\</MicrosoftNetCoreAppRefPackRefDir>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work now without this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That property was previously set for older .NETCoreApp tfms but that isn't necessary anymore as these now just use the targeting pack's references.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what if an OOB that targets say net6.0 references another OOB that also targets net6.0? Wouldn't you want to build against the live version of it?

Copy link
Member Author

@ViktorHofer ViktorHofer Apr 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In such cases you use ProjectReferences which is the current behavior in main already. Conflict resolution (an SDK task) makes sure that ProjectReferences are preferred over targeting pack assets.

You only use <Reference /> items for NetCoreAppCurrent to reference inbox assets. Everything else is accomplished via ProjectReferences. Eventually the inbox references will be converted to ProjectReferences as well but that's not possible yet without regressing the local innerloop perf.

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
</ItemGroup>
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'netstandard2.1'))">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being removed? I would think we only want the dependency on netstandard2.0 and netfx.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project doesn't target netstandard2.1, therefore this condition can be merged with the "TFI != .NetCoreApp" condition above.

@ericstj ericstj requested review from a team and joperezr April 26, 2022 16:56
@@ -16,17 +16,12 @@
and '$(IsSourceProject)' == 'true'
and '$(MSBuildProjectExtension)' == '.csproj'
and (
('@(Reference)' != ''
'$(TargetFrameworkMoniker)' != '$(NetCoreAppCurrentTargetFrameworkMoniker)'
or '$(DisableImplicitFrameworkReferences)' != 'true'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: can we please update the comment above to explain the condition in more detail given it is a complex one?

Copy link
Member Author

@ViktorHofer ViktorHofer Apr 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simplify these conditions vastly and I originally had that change in this PR but then moved it out as it's unrelated to my change. I will submit a follow-up PR that does the clean-up and update the comment.

<ItemGroup>
<Compile Include="System.ComponentModel.Composition.cs" />
<Compile Include="System.ComponentModel.Composition.Forwards.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Linq.Expressions\ref\System.Linq.Expressions.csproj" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are removing P2Ps from netcoreappcurrent build, how are we supposed to consume the live build of S.L.Expressions?

Copy link
Member Author

@ViktorHofer ViktorHofer Apr 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The targeting pack that is resolved is the actual live built one (for NetCoreAppCurrent) which resides under artifacts\bin\microsoft.netcore.app.ref\.

Copy link
Member Author

@ViktorHofer ViktorHofer Apr 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already the current behavior in main. Let me explain it in more details:

  1. The shared framework libraries (both ref and src) get built as part of the libs.sfx subset.
  2. These projects binplace their built assets into the live targeting pack and runtime pack folders.
  3. NetCoreAppCurrent out-of-band libraries build on top of the live targeting pack and/or runtime pack and receive that pack's references.

ProjectReference items are used to reference live built assets that aren't part of the targeting pack (OOBs) or when the library is available in the targeting pack but ships via a package as well, i.e. System.Text.Json. In the case of such special libraries like STJ, we reference them via ProjectReferences so that the library has a package dependency on STJ.

@ViktorHofer
Copy link
Member Author

Logging off now. Would be fantastic to get an approval so that I can continue my work tomorrow, on top of these changes. Thanks everyone.

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<Compile Include="Polyfills\System.Numerics.BitOperations.netstandard20.cs" />
<Compile Include="Polyfills\System.Text.Rune.netstandard20.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', '$(NetCoreAppCurrent)'))">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way that it'd be compatible with NetCoreAppCurrent without actually being NetCoreAppCurrent? It feels like the compare-to-current is usually an ==...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eerhardt was asking the same question previously. Today these are the possible ways to condition on NetCoreAppCurrent (both platform agnostic and platform specific) that I know of:

  • '$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(TargetFrameworkVersion)' == 'v$(NetCoreAppCurrentVersion)'
  • '$(TargetFrameworkVersion)' == 'v$(NetCoreAppCurrentVersion)'
  • '$(TargetFrameworkMoniker)' == '$(NetCoreAppCurrentTargetFrameworkMoniker)'
  • $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', '$(NetCoreAppCurrent)')) <-- that one works on properties as well
  • $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '$(NETCoreAppCurrentVersion)'))

I chose the TargetFrameworkCompatible function as it works on both properties and items. In the two projects that I updated to use that function, a simple equality check couldn't be performed as the TargetFramework property doesn't evaluate to net7.0 but to net7.0-platform, i.e. in the case of System.Text.Encodings.Web net7.0-Browser.

<ItemGroup>
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections.Immutable\src\System.Collections.Immutable.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">

<ItemGroup Condition="'$(TargetFrameworkVersion)' == 'v$(NetCoreAppCurrentVersion)'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be

'$(TargetFramework)' == '$(NetCoreAppCurrent)'

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Let me update that line a follow-up PR.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last minor comment. Other than that, LGTM.

@ViktorHofer ViktorHofer merged commit b54561a into dotnet:main Apr 27, 2022
@ViktorHofer ViktorHofer deleted the AutoReferencesContinued branch April 27, 2022 15:28
@ghost ghost locked as resolved and limited conversation to collaborators May 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Visual Studio restore is broken as projects are missing from the dependency closure
4 participants