-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Double Evaluation Fix #2595
Double Evaluation Fix #2595
Changes from 9 commits
ba8fca1
ff79ea2
8729689
984f381
c36bfb3
bb44739
f066173
caf92b2
62094fd
21b9a95
15afc90
00e2059
e3ee36f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1516,17 +1516,26 @@ Copyright (C) Microsoft Corporation. All rights reserved. | |
==================================================================================== | ||
_GetProjectReferenceTargetFrameworkProperties | ||
|
||
Builds the GetTargetFrameworkProperties target of all existent project references, | ||
passing $(TargetFrameworkMoniker) as $(ReferringTargetFramework) and sets the | ||
SetTargetFramework metadata of the project reference to the value that is returned. | ||
|
||
This allows a cross-targeting project to select how it should be configured to | ||
build against the most appropriate target for the referring target framework. | ||
Builds the GetTargetFrameworks target of all existent project references to get a list | ||
of all supported TargetFrameworks of the referenced projects. For each project, call | ||
GetReferenceNearestTargetFrameworkTask to determine the closest match. This allows a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reword this to say "Call GetReferenceNearestTargetFrameworkTask to determine the closest match for each project." This way it won't imply that the task is called once for project. |
||
cross-targeting project to select how it should be configured to build against the | ||
most appropriate target for the referring target framework. | ||
|
||
====================================================================================== | ||
--> | ||
<Target Name="_GetProjectReferenceTargetFrameworkProperties" | ||
Outputs="%(_MSBuildProjectReferenceExistent.Identity)"> | ||
<Target Name="_GetProjectReferenceTargetFrameworkProperties"> | ||
<!-- | ||
Select the moniker to send to each project reference if not already set. NugetTargetMoniker (NTM) is preferred by default over | ||
TargetFrameworkMoniker (TFM) because it is required to disambiguate the UWP case where TFM is fixed at .NETCore,Version=v5.0 and | ||
has floating NTM=UAP,Version=vX.Y.Z. However, in other cases (classic PCLs), NTM contains multiple values and that will cause the MSBuild | ||
invocation below to fail by passing invalid properties. Therefore we do not use the NTM if it contains a semicolon. | ||
--> | ||
<PropertyGroup Condition="'$(ReferringTargetFrameworkForProjectReferences)' == ''"> | ||
<ReferringTargetFrameworkForProjectReferences Condition="'$(NugetTargetMoniker)' != '' and !$(NuGetTargetMoniker.Contains(';'))">$(NugetTargetMoniker)</ReferringTargetFrameworkForProjectReferences> | ||
<ReferringTargetFrameworkForProjectReferences Condition="'$(NugetTargetMoniker)' == ''">$(TargetFrameworkMoniker)</ReferringTargetFrameworkForProjectReferences> | ||
</PropertyGroup> | ||
|
||
<!-- | ||
Honor SkipGetTargetFrameworkProperties=true metadata on project references | ||
to mean that the project reference is known not to target multiple frameworks | ||
|
@@ -1558,50 +1567,64 @@ Copyright (C) Microsoft Corporation. All rights reserved. | |
</_MSBuildProjectReferenceExistent> | ||
</ItemGroup> | ||
|
||
<!-- | ||
Select the moniker to send to each project reference if not already set. NugetTargetMoniker (NTM) is preferred by default over | ||
TargetFrameworkMoniker (TFM) because it is required to disambiguate the UWP case where TFM is fixed at .NETCore,Version=v5.0 and | ||
has floating NTM=UAP,Version=vX.Y.Z. However, in other cases (classic PCLs), NTM contains multiple values and that will cause the MSBuild | ||
invocation below to fail by passing invalid properties. Therefore we do not use the NTM if it contains a semicolon. | ||
--> | ||
<PropertyGroup Condition="'$(ReferringTargetFrameworkForProjectReferences)' == ''"> | ||
<ReferringTargetFrameworkForProjectReferences Condition="'$(NugetTargetMoniker)' != '' and !$(NuGetTargetMoniker.Contains(';'))">$(NugetTargetMoniker)</ReferringTargetFrameworkForProjectReferences> | ||
<ReferringTargetFrameworkForProjectReferences Condition="'$(NugetTargetMoniker)' == ''">$(TargetFrameworkMoniker)</ReferringTargetFrameworkForProjectReferences> | ||
</PropertyGroup> | ||
|
||
<!-- Get reference target framework lists --> | ||
<MSBuild | ||
Projects="%(_MSBuildProjectReferenceExistent.Identity)" | ||
Targets="GetTargetFrameworkProperties" | ||
Projects="@(_MSBuildProjectReferenceExistent)" | ||
Targets="GetTargetFrameworks" | ||
BuildInParallel="$(BuildInParallel)" | ||
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform); ReferringTargetFramework=$(ReferringTargetFrameworkForProjectReferences)" | ||
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform)" | ||
ContinueOnError="!$(BuildingProject)" | ||
RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove);TargetFramework;RuntimeIdentifier" | ||
Condition="'%(_MSBuildProjectReferenceExistent.SkipGetTargetFrameworkProperties)' != 'true'"> | ||
|
||
<Output TaskParameter="TargetOutputs" PropertyName="_ProjectReferenceTargetFrameworkProperties" /> | ||
Condition="'%(_MSBuildProjectReferenceExistent.SkipGetTargetFrameworkProperties)' != 'true'" | ||
SkipNonexistentTargets="true"> | ||
<Output TaskParameter="TargetOutputs" ItemName="_ProjectReferenceTargetFrameworkPossibilities" /> | ||
</MSBuild> | ||
|
||
<ItemGroup> | ||
<_MSBuildProjectReferenceExistent Condition="'%(_MSBuildProjectReferenceExistent.Identity)' == '%(Identity)' and '$(_ProjectReferenceTargetFrameworkProperties)' != ''"> | ||
<SetTargetFramework>$(_ProjectReferenceTargetFrameworkProperties)</SetTargetFramework> | ||
<!-- For each reference, get closest match --> | ||
<GetReferenceNearestTargetFrameworkTask AnnotatedProjectReferences="@(_ProjectReferenceTargetFrameworkPossibilities)" | ||
CurrentProjectTargetFramework="$(ReferringTargetFrameworkForProjectReferences)" | ||
CurrentProjectName="$(MSBuildProjectName)" | ||
Condition="'@(_ProjectReferenceTargetFrameworkPossibilities->Count())' != '0' and '$(ReferringTargetFrameworkForProjectReferences)' != ''"> | ||
<Output ItemName="AnnotatedProjects" TaskParameter="AssignedProjects" /> | ||
</GetReferenceNearestTargetFrameworkTask> | ||
|
||
<UndefineProperties Condition="$(_ProjectReferenceTargetFrameworkProperties.Contains(`ProjectHasSingleTargetFramework=true`))">%(_MSBuildProjectReferenceExistent.UndefineProperties);TargetFramework;ProjectHasSingleTargetFramework</UndefineProperties> | ||
<!-- Unconditionally remove the property that was set as a marker to indicate that for this call we should remove TargetFramework --> | ||
<UndefineProperties Condition="!$(_ProjectReferenceTargetFrameworkProperties.Contains(`ProjectHasSingleTargetFramework=true`))">%(_MSBuildProjectReferenceExistent.UndefineProperties);ProjectHasSingleTargetFramework</UndefineProperties> | ||
</_MSBuildProjectReferenceExistent> | ||
<ItemGroup> | ||
<AnnotatedProjects Include="@(_ProjectReferenceTargetFrameworkPossibilities)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest adding a comment here explaining this logic (possibly linking to dotnet/sdk#416) |
||
Condition="'$(ReferringTargetFrameworkForProjectReferences)' == ''" /> | ||
<!-- If the NearestTargetFramework property was set and the project multi-targets, SetTargetFramework must be set. --> | ||
<AnnotatedProjects Condition="'@(AnnotatedProjects)' == '%(Identity)' and '%(AnnotatedProjects.NearestTargetFramework)' != '' and '%(AnnotatedProjects.HasSingleTargetFramework)' != 'true'"> | ||
<SetTargetFramework>TargetFramework=%(AnnotatedProjects.NearestTargetFramework)</SetTargetFramework> | ||
</AnnotatedProjects> | ||
|
||
<!-- If the NearestTargetFramework property was not set or the project has a single TargetFramework, we need to Undefine | ||
TargetFramework to avoid another project evaluation. --> | ||
<AnnotatedProjects Condition="'@(AnnotatedProjects)' == '%(Identity)' and ('%(AnnotatedProjects.NearestTargetFramework)' == '' or '%(AnnotatedProjects.HasSingleTargetFramework)' == 'true')"> | ||
<UndefineProperties>%(AnnotatedProjects.UndefineProperties);TargetFramework</UndefineProperties> | ||
</AnnotatedProjects> | ||
|
||
<!-- If the project is RID agnostic, undefine the RuntimeIdentifier property to avoid another evaluation. --> | ||
<AnnotatedProjects Condition="'@(AnnotatedProjects)' == '%(Identity)' and '%(AnnotatedProjects.IsRidAgnostic)' == 'true'"> | ||
<UndefineProperties>%(AnnotatedProjects.UndefineProperties);RuntimeIdentifier</UndefineProperties> | ||
</AnnotatedProjects> | ||
|
||
<_MSBuildProjectReferenceExistent Remove="@(_MSBuildProjectReferenceExistent)" /> | ||
<_MSBuildProjectReferenceExistent Include="@(AnnotatedProjects)" /> | ||
</ItemGroup> | ||
</Target> | ||
|
||
<Target Name="GetTargetFrameworks" | ||
Returns="@(_ThisProjectBuildMetadata)"> | ||
<ItemGroup> | ||
<_MSBuildProjectReferenceExistent Condition="'%(_MSBuildProjectReferenceExistent.Identity)' == '%(Identity)' and '$(_ProjectReferenceTargetFrameworkProperties)' != ''"> | ||
<UndefineProperties Condition="$(_ProjectReferenceTargetFrameworkProperties.Contains(`ProjectIsRidAgnostic=true`))">%(_MSBuildProjectReferenceExistent.UndefineProperties);RuntimeIdentifier;ProjectIsRidAgnostic</UndefineProperties> | ||
<!-- Unconditionally remove the property that was set as a marker to indicate that for this call we should remove RuntimeIdentifier --> | ||
<UndefineProperties Condition="!$(_ProjectReferenceTargetFrameworkProperties.Contains(`ProjectIsRidAgnostic=true`))">%(_MSBuildProjectReferenceExistent.UndefineProperties);ProjectIsRidAgnostic</UndefineProperties> | ||
</_MSBuildProjectReferenceExistent> | ||
<_ThisProjectBuildMetadata Include="$(MSBuildProjectFullPath)"> | ||
<TargetFrameworks Condition="'$(TargetFrameworks)' != ''">$(TargetFrameworks)</TargetFrameworks> | ||
<TargetFrameworks Condition="'$(TargetFrameworks)' == ''">$(TargetFramework)</TargetFrameworks> | ||
<HasSingleTargetFramework>true</HasSingleTargetFramework> | ||
<HasSingleTargetFramework Condition="'$(IsCrossTargetingBuild)' == 'true'">false</HasSingleTargetFramework> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is always going to be false when we land in the non-cross-targeting version of GetTargetFrameworks. |
||
<!-- indicate to caller that project is RID agnostic so that a global property RuntimeIdentifier value can be removed --> | ||
<IsRidAgnostic>false</IsRidAgnostic> | ||
<IsRidAgnostic Condition=" '$(RuntimeIdentifier)' == '' and '$(RuntimeIdentifiers)' == '' ">true</IsRidAgnostic> | ||
</_ThisProjectBuildMetadata> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<_ProjectReferenceTargetFrameworkProperties /> | ||
</PropertyGroup> | ||
</Target> | ||
|
||
<!-- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the changes to this file up-to-date after the changes to the protocol and interface with NuGet that were made in this PR?