From 1954bb49c111b726c68fafac4511c3dd4a502ba7 Mon Sep 17 00:00:00 2001 From: Forgind Date: Fri, 13 Nov 2020 09:22:38 -0800 Subject: [PATCH] Fix double build Fixes #5830 (#5838) * Undefine TargetFramework if skipping TargetFramework Fixes #5830. See explanation there. --- .../Microsoft.Common.CurrentVersion.targets | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index d2d202bfea7..296d9036f1c 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -1605,11 +1605,33 @@ Copyright (C) Microsoft Corporation. All rights reserved. and the mechanism here for selecting the best one can be skipped as an optimization. We give this treatment to .vcxproj by default since no .vcxproj can target more - than one framework. + than one framework currently. The user must specify exactly one TargetFramework. + + vcxproj files compile down to OS-specific binaries, either native or .NET. In the + _GetProjectReferenceTargetFrameworkProperties target of Microsoft.Common.CurrentVersion.targets, + SkipTargetFrameworkProperties is set to true for vcxproj to account for that. + + This means we do not fill the Item _ProjectReferenceTargetFrameworkPossibilities or, by extension, + the AnnotatedProjects Item. + + For single-targeted projects, we normally decorate the AnnotatedProjects Item with + UndefineProperties metadata specifying that TargetFramework should be undefined. Because it + isn't defined properly at that stage, however, this does not happen, and TargetFramework is + defined at this point in addition to having been defined globally. Currently, this is always + true for vcxproj. + + MSBuild permits building the same project twice as long as it has different sets of global properties. + Because the TargetFramework global property is not being removed as expected by the multitargeting + part of MSBuild, the engine recognizes that there are differences and builds it twice. This can + become more noticeable if the projects build in parallel, since they could try to access the same + resources and conflict, failing the build. Note, however, that building the same project twice in + this way is always wrong even if it seems minor because they do not conflict, and the second build is + relatively fast. --> <_MSBuildProjectReferenceExistent Condition="'%(_MSBuildProjectReferenceExistent.SkipGetTargetFrameworkProperties)' == '' and ('%(Extension)' == '.vcxproj' or '%(Extension)' == '.nativeproj')"> true + %(_MSBuildProjectReferenceExistent.UndefineProperties);TargetFramework