From 0fe1d68cc7e1bb30bffbe273bc744f3d5959808a Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 17 Sep 2024 19:39:06 -0400 Subject: [PATCH 1/2] Add test for runtime pack profiles Repro for https://github.com/dotnet/sdk/issues/43461 --- ...ThatWeWantToBuildAWindowsDesktopProject.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs index f7ba44ce3bc4..6c3dac9ca3f5 100644 --- a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs +++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs @@ -591,6 +591,33 @@ public void ItBuildsWhenReferencingWindowsUIXamlTypesWithUseUwpProperty() .Pass(); } + [WindowsOnlyFact] + public void ItHandlesProfilesWithSelfContained() + { + TestProject testProject = new() + { + TargetFrameworks = $"{ToolsetInfo.CurrentTargetFramework}-windows", + IsExe = true, + SelfContained = "true", + RuntimeIdentifier = "win-x64" + }; + // Setting both UseWpf and UseWindowsForms to true will add a FrameworkReference to Microsoft.WindowsDesktop.App + testProject.AdditionalProperties["UseWpf"] = "true"; + testProject.AdditionalProperties["UseWindowsForms"] = "true"; + + // Add reference to Windows Forms, which is a profile of Microsoft.WindowsDesktop.App + testProject.AddItem("FrameworkReference", "Include", "Microsoft.WindowsDesktop.App.WindowsForms"); + + var testAsset = _testAssetsManager.CreateTestProject(testProject); + + var buildCommand = new BuildCommand(testAsset); + buildCommand.Execute().Should().Pass(); + + // PresentationFramework should be included in output, even though it's not in the WindowsForms profile, + // it should be included because of the Microsoft.WindowsDesktop.App FrameworkReference + buildCommand.GetOutputDirectory().Should().HaveFile("PresentationFramework.dll"); + } + private string GetReferencedWindowsSdkVersion(TestAsset testAsset) { var getValueCommand = new GetValuesCommand(testAsset, "PackageDownload", GetValuesCommand.ValueType.Item) From 09e72ea288072ccefaf2b9ec2f2a6d4dffc1e8fb Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 17 Sep 2024 22:36:25 -0400 Subject: [PATCH 2/2] Fix runtime pack handling of profiles combined with no profiles Fixes https://github.com/dotnet/sdk/issues/43461 --- .../ResolveRuntimePackAssets.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs index 8b356984db81..82bd3af81998 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs @@ -31,14 +31,13 @@ protected override void ExecuteCore() // Find any RuntimeFrameworks that matches with FrameworkReferences, so that we can apply that RuntimeFrameworks profile to the corresponding RuntimePack. // This is done in 2 parts, First part (see comments for 2nd part further below), we match the RuntimeFramework with the FrameworkReference by using the following metadata. - // RuntimeFrameworks.GetMetadata("FrameworkName")==FrameworkReferences.ItemSpec AND RuntimeFrameworks.GetMetadata("Profile") is not empty + // RuntimeFrameworks.GetMetadata("FrameworkName")==FrameworkReferences.ItemSpec // For example, A WinForms app that uses useWindowsForms (and useWPF will be set to false) has the following values that will result in a match of the below RuntimeFramework. // FrameworkReferences with an ItemSpec "Microsoft.WindowsDesktop.App.WindowsForms" will match with // RuntimeFramework with an ItemSpec => "Microsoft.WindowsDesktop.App", GetMetadata("FrameworkName") => "Microsoft.WindowsDesktop.App.WindowsForms", GetMetadata("Profile") => "WindowsForms" List matchingRuntimeFrameworks = RuntimeFrameworks != null ? FrameworkReferences .SelectMany(fxReference => RuntimeFrameworks.Where(rtFx => - fxReference.ItemSpec.Equals(rtFx.GetMetadata(MetadataKeys.FrameworkName), StringComparison.OrdinalIgnoreCase) && - !string.IsNullOrEmpty(rtFx.GetMetadata("Profile")))) + fxReference.ItemSpec.Equals(rtFx.GetMetadata(MetadataKeys.FrameworkName), StringComparison.OrdinalIgnoreCase))) .ToList() : null; HashSet frameworkReferenceNames = new(FrameworkReferences.Select(item => item.ItemSpec), StringComparer.OrdinalIgnoreCase); @@ -93,6 +92,13 @@ protected override void ExecuteCore() } } + // If we have a runtime framework with an empty profile, it means that we should use all of the contents of the runtime pack, + // so we can clear the profile list + if (profiles.Contains(string.Empty)) + { + profiles.Clear(); + } + string runtimePackRoot = runtimePack.GetMetadata(MetadataKeys.PackageDirectory); if (string.IsNullOrEmpty(runtimePackRoot) || !Directory.Exists(runtimePackRoot))