From 166e3e1e0aa267d8b9d08be523d8f052b7c429f6 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 16 Aug 2022 15:46:02 -0400 Subject: [PATCH 1/3] Support multiple Windows SDK versions for different TFMs --- ...reateWindowsSdkKnownFrameworkReferences.cs | 26 ++++++++- ...ThatWeWantToBuildAWindowsDesktopProject.cs | 57 ++++++++++++++++--- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/CreateWindowsSdkKnownFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/CreateWindowsSdkKnownFrameworkReferences.cs index 94a65656ee68..e40ac7f63451 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/CreateWindowsSdkKnownFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/CreateWindowsSdkKnownFrameworkReferences.cs @@ -55,6 +55,9 @@ protected override void ExecuteCore() else { var normalizedTargetFrameworkVersion = ProcessFrameworkReferences.NormalizeVersion(new Version(TargetFrameworkVersion)); + + var knownFrameworkReferencesByWindowsSdkVersion = new Dictionary>(); + foreach (var supportedWindowsVersion in WindowsSdkSupportedTargetPlatformVersions) { var windowsSdkPackageVersion = supportedWindowsVersion.GetMetadata("WindowsSdkPackageVersion"); @@ -62,18 +65,37 @@ protected override void ExecuteCore() if (!string.IsNullOrEmpty(windowsSdkPackageVersion)) { var minimumNETVersion = supportedWindowsVersion.GetMetadata("MinimumNETVersion"); + Version normalizedMinimumVersion = new Version(0, 0, 0); if (!string.IsNullOrEmpty(minimumNETVersion)) { - var normalizedMinimumVersion = ProcessFrameworkReferences.NormalizeVersion(new Version(minimumNETVersion)); + normalizedMinimumVersion = ProcessFrameworkReferences.NormalizeVersion(new Version(minimumNETVersion)); if (normalizedMinimumVersion > normalizedTargetFrameworkVersion) { continue; } } - knownFrameworkReferences.Add(CreateKnownFrameworkReference(windowsSdkPackageVersion, TargetFrameworkVersion, supportedWindowsVersion.ItemSpec)); + if (!Version.TryParse(supportedWindowsVersion.ItemSpec, out var windowsSdkVersionParsed)) + { + continue; + } + + if (!knownFrameworkReferencesByWindowsSdkVersion.ContainsKey(windowsSdkVersionParsed)) + { + knownFrameworkReferencesByWindowsSdkVersion[windowsSdkVersionParsed] = new(); + } + + knownFrameworkReferencesByWindowsSdkVersion[windowsSdkVersionParsed].Add((normalizedMinimumVersion, CreateKnownFrameworkReference(windowsSdkPackageVersion, TargetFrameworkVersion, supportedWindowsVersion.ItemSpec))); } } + + foreach (var knownFrameworkReferencesForSdkVersion in knownFrameworkReferencesByWindowsSdkVersion.Values) + { + // If there are multiple WindowsSdkSupportedTargetPlatformVersion items for the same Windows SDK version, choose the one with the highest minimum version. + // That way it is possible to use older packages when targeting older versions of .NET, and newer packages for newer versions of .NET + var highestMinimumVersion = knownFrameworkReferencesForSdkVersion.Max(t => t.minimumNetVersion); + knownFrameworkReferences.AddRange(knownFrameworkReferencesForSdkVersion.Where(t => t.minimumNetVersion == highestMinimumVersion).Select(t => t.knownFrameworkReference)); + } } KnownFrameworkReferences = knownFrameworkReferences.ToArray(); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs index 8590ce66db9b..90203f5735a1 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs @@ -403,6 +403,53 @@ public void ItUsesCorrectWindowsSdkPackVersion(string targetFramework, bool? use var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework + useWindowsSDKPreview + windowsSdkPackageVersion); + string referencedWindowsSdkVersion = GetReferencedWindowsSdkVersion(testAsset); + + // The patch version of the Windows SDK Ref pack will change over time, so we use a '*' in the expected version to indicate that and replace it with + // the 4th part of the version number of the resolved package. + if (expectedWindowsSdkPackageVersion.Contains('*')) + { + expectedWindowsSdkPackageVersion = expectedWindowsSdkPackageVersion.Replace("*", new Version(referencedWindowsSdkVersion).Revision.ToString()); + } + + referencedWindowsSdkVersion.Should().Be(expectedWindowsSdkPackageVersion); + } + + [WindowsOnlyTheory] + [InlineData("net5.0-windows10.0.22000.0", "10.0.22000.25")] + [InlineData("net6.0-windows10.0.22000.0", "10.0.22000.26")] + [InlineData("net6.0-windows10.0.19041.0", "10.0.19041.25")] + public void ItUsesTheHighestMatchingWindowsSdkPackageVersion(string targetFramework, string expectedWindowsSdkPackageVersion) + { + var testProject = new TestProject() + { + TargetFrameworks = targetFramework + }; + + var testAsset = _testAssetsManager.CreateTestProject(testProject) + .WithProjectChanges(project => + { + // Add items for available SDK versions for test + var testItems = XElement.Parse(@" + + + + +j0shuams marked this conversation as resolved. + + + "); + + project.Root.Add(testItems); + }); + + string referencedWindowsSdkVersion = GetReferencedWindowsSdkVersion(testAsset); + referencedWindowsSdkVersion.Should().Be(expectedWindowsSdkPackageVersion); + + } + + private string GetReferencedWindowsSdkVersion(TestAsset testAsset) + { var getValueCommand = new GetValuesCommand(testAsset, "PackageDownload", GetValuesCommand.ValueType.Item); getValueCommand.ShouldRestore = false; getValueCommand.DependsOnTargets = "_CheckForInvalidConfigurationAndPlatform;CollectPackageDownloads"; @@ -419,15 +466,7 @@ public void ItUsesCorrectWindowsSdkPackVersion(string targetFramework, bool? use packageDownloadVersion[0].Should().Be('['); packageDownloadVersion.Last().Should().Be(']'); - // The patch version of the Windows SDK Ref pack will change over time, so we use a '*' in the expected version to indicate that and replace it with - // the 4th part of the version number of the resolved package. - var trimmedPackageDownloadVersion = packageDownloadVersion.Substring(1, packageDownloadVersion.Length - 2); - if (expectedWindowsSdkPackageVersion.Contains('*')) - { - expectedWindowsSdkPackageVersion = expectedWindowsSdkPackageVersion.Replace("*", new Version(trimmedPackageDownloadVersion).Revision.ToString()); - } - - trimmedPackageDownloadVersion.Should().Be(expectedWindowsSdkPackageVersion); + return packageDownloadVersion.Substring(1, packageDownloadVersion.Length - 2); } private string GetPropertyValue(TestAsset testAsset, string propertyName) From 45415e680260290d02a6f7c0158726e6a98478c8 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 16 Aug 2022 16:38:57 -0400 Subject: [PATCH 2/3] Fix test --- .../GivenThatWeWantToBuildAWindowsDesktopProject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs index 90203f5735a1..e464e428b451 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs @@ -426,7 +426,7 @@ public void ItUsesTheHighestMatchingWindowsSdkPackageVersion(string targetFramew TargetFrameworks = targetFramework }; - var testAsset = _testAssetsManager.CreateTestProject(testProject) + var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework) .WithProjectChanges(project => { // Add items for available SDK versions for test From 3368bb6c6f0a1372c9dcb7edc2bb3344f2511a9f Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 16 Aug 2022 17:36:12 -0400 Subject: [PATCH 3/3] Junk --- .../GivenThatWeWantToBuildAWindowsDesktopProject.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs index e464e428b451..9928c721a422 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs @@ -435,7 +435,6 @@ public void ItUsesTheHighestMatchingWindowsSdkPackageVersion(string targetFramew -j0shuams marked this conversation as resolved. ");