Skip to content

Commit 042d060

Browse files
authored
Merge pull request #12207 from lukas-lansky/runtime-id-cherry-pick
Preview 7: Work around for runtime pack profiles with differing runtime IDs
2 parents cb57053 + 94f0c0a commit 042d060

File tree

2 files changed

+94
-51
lines changed

2 files changed

+94
-51
lines changed

src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.IO;
77
using System.Linq;
88
using System.Runtime.InteropServices;
9-
using System.Text.RegularExpressions;
109
using Microsoft.Build.Framework;
1110
using Microsoft.Build.Utilities;
1211
using Newtonsoft.Json;
@@ -230,58 +229,74 @@ protected override void ExecuteCore()
230229
isTrimmable = selectedRuntimePack?.IsTrimmable;
231230
}
232231

233-
// Only add runtime packs where the framework reference name matches the RuntimeFrameworkName
234-
// Framework references for "profiles" will use the runtime pack from the corresponding non-profile framework
232+
bool includeInPackageDownload;
233+
KnownRuntimePack runtimePackForRuntimeIDProcessing;
235234
if (knownFrameworkReference.Name.Equals(knownFrameworkReference.RuntimeFrameworkName, StringComparison.OrdinalIgnoreCase))
236235
{
237-
bool processedPrimaryRuntimeIdentifier = false;
236+
// Only add runtime packs where the framework reference name matches the RuntimeFrameworkName
237+
// Framework references for "profiles" will use the runtime pack from the corresponding non-profile framework
238+
runtimePackForRuntimeIDProcessing = selectedRuntimePack.Value;
239+
includeInPackageDownload = true;
240+
}
241+
else if (!knownFrameworkReference.RuntimePackRuntimeIdentifiers.Equals(selectedRuntimePack?.RuntimePackRuntimeIdentifiers))
242+
{
243+
// If the profile has a different set of runtime identifiers than the runtime pack, use the profile.
244+
runtimePackForRuntimeIDProcessing = knownFrameworkReference.ToKnownRuntimePack();
245+
includeInPackageDownload = true;
246+
}
247+
else
248+
{
249+
// For the remaining profiles, don't include them in package download but add them to unavaliable if necessary.
250+
runtimePackForRuntimeIDProcessing = knownFrameworkReference.ToKnownRuntimePack();
251+
includeInPackageDownload = false;
252+
}
238253

239-
if ((SelfContained || ReadyToRunEnabled) &&
240-
!string.IsNullOrEmpty(RuntimeIdentifier) &&
241-
selectedRuntimePack != null &&
242-
!string.IsNullOrEmpty(selectedRuntimePack?.RuntimePackNamePatterns))
243-
{
254+
bool processedPrimaryRuntimeIdentifier = false;
244255

245-
// Find other KnownFrameworkReferences that map to the same runtime pack, if any
246-
List<string> additionalFrameworkReferencesForRuntimePack = null;
247-
foreach (var additionalKnownFrameworkReference in knownFrameworkReferencesForTargetFramework)
256+
if ((SelfContained || ReadyToRunEnabled) &&
257+
!string.IsNullOrEmpty(RuntimeIdentifier) &&
258+
selectedRuntimePack != null &&
259+
!string.IsNullOrEmpty(selectedRuntimePack?.RuntimePackNamePatterns))
260+
{
261+
262+
// Find other KnownFrameworkReferences that map to the same runtime pack, if any
263+
List<string> additionalFrameworkReferencesForRuntimePack = null;
264+
foreach (var additionalKnownFrameworkReference in knownFrameworkReferencesForTargetFramework)
265+
{
266+
if (additionalKnownFrameworkReference.RuntimeFrameworkName.Equals(knownFrameworkReference.RuntimeFrameworkName, StringComparison.OrdinalIgnoreCase) &&
267+
!additionalKnownFrameworkReference.RuntimeFrameworkName.Equals(additionalKnownFrameworkReference.Name, StringComparison.OrdinalIgnoreCase))
248268
{
249-
if (additionalKnownFrameworkReference.RuntimeFrameworkName.Equals(knownFrameworkReference.RuntimeFrameworkName, StringComparison.OrdinalIgnoreCase) &&
250-
!additionalKnownFrameworkReference.RuntimeFrameworkName.Equals(additionalKnownFrameworkReference.Name, StringComparison.OrdinalIgnoreCase))
269+
if (additionalFrameworkReferencesForRuntimePack == null)
251270
{
252-
if (additionalFrameworkReferencesForRuntimePack == null)
253-
{
254-
additionalFrameworkReferencesForRuntimePack = new List<string>();
255-
}
256-
additionalFrameworkReferencesForRuntimePack.Add(additionalKnownFrameworkReference.Name);
271+
additionalFrameworkReferencesForRuntimePack = new List<string>();
257272
}
273+
additionalFrameworkReferencesForRuntimePack.Add(additionalKnownFrameworkReference.Name);
258274
}
275+
}
259276

260-
ProcessRuntimeIdentifier(RuntimeIdentifier, selectedRuntimePack.Value, runtimePackVersion, additionalFrameworkReferencesForRuntimePack,
261-
unrecognizedRuntimeIdentifiers, unavailableRuntimePacks, runtimePacks, packagesToDownload, isTrimmable);
277+
ProcessRuntimeIdentifier(RuntimeIdentifier, runtimePackForRuntimeIDProcessing, runtimePackVersion, additionalFrameworkReferencesForRuntimePack,
278+
unrecognizedRuntimeIdentifiers, unavailableRuntimePacks, runtimePacks, packagesToDownload, isTrimmable, includeInPackageDownload);
262279

263-
processedPrimaryRuntimeIdentifier = true;
264-
}
280+
processedPrimaryRuntimeIdentifier = true;
281+
}
265282

266-
if (RuntimeIdentifiers != null)
283+
if (RuntimeIdentifiers != null)
284+
{
285+
foreach (var runtimeIdentifier in RuntimeIdentifiers)
267286
{
268-
foreach (var runtimeIdentifier in RuntimeIdentifiers)
287+
if (processedPrimaryRuntimeIdentifier && runtimeIdentifier == this.RuntimeIdentifier)
269288
{
270-
if (processedPrimaryRuntimeIdentifier && runtimeIdentifier == this.RuntimeIdentifier)
271-
{
272-
// We've already processed this RID
273-
continue;
274-
}
275-
276-
// Pass in null for the runtimePacks list, as for these runtime identifiers we only want to
277-
// download the runtime packs, but not use the assets from them
278-
ProcessRuntimeIdentifier(runtimeIdentifier, selectedRuntimePack.Value, runtimePackVersion, additionalFrameworkReferencesForRuntimePack: null,
279-
unrecognizedRuntimeIdentifiers, unavailableRuntimePacks, runtimePacks: null, packagesToDownload, isTrimmable);
289+
// We've already processed this RID
290+
continue;
280291
}
292+
293+
// Pass in null for the runtimePacks list, as for these runtime identifiers we only want to
294+
// download the runtime packs, but not use the assets from them
295+
ProcessRuntimeIdentifier(runtimeIdentifier, runtimePackForRuntimeIDProcessing, runtimePackVersion, additionalFrameworkReferencesForRuntimePack: null,
296+
unrecognizedRuntimeIdentifiers, unavailableRuntimePacks, runtimePacks: null, packagesToDownload, isTrimmable, includeInPackageDownload);
281297
}
282298
}
283299

284-
285300
if (!string.IsNullOrEmpty(knownFrameworkReference.RuntimeFrameworkName))
286301
{
287302
TaskItem runtimeFramework = new TaskItem(knownFrameworkReference.RuntimeFrameworkName);
@@ -370,7 +385,7 @@ protected override void ExecuteCore()
370385
{
371386
string runtimePackDescriptionForErrorMessage = knownFrameworkReference.RuntimeFrameworkName +
372387
(requiredLabelsMetadata == string.Empty ? string.Empty : ":" + requiredLabelsMetadata);
373-
388+
374389
Log.LogError(Strings.ConflictingRuntimePackInformation, runtimePackDescriptionForErrorMessage,
375390
string.Join(Environment.NewLine, matchingRuntimePacks.Select(rp => rp.RuntimePackNamePatterns)));
376391

@@ -387,7 +402,8 @@ private void ProcessRuntimeIdentifier(
387402
List<ITaskItem> unavailableRuntimePacks,
388403
List<ITaskItem> runtimePacks,
389404
List<ITaskItem> packagesToDownload,
390-
string isTrimmable)
405+
string isTrimmable,
406+
bool addToPackageDownload)
391407
{
392408
var runtimeGraph = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath);
393409
var knownFrameworkReferenceRuntimePackRuntimeIdentifiers = selectedRuntimePack.RuntimePackRuntimeIdentifiers.Split(';');
@@ -418,7 +434,7 @@ private void ProcessRuntimeIdentifier(
418434
unrecognizedRuntimeIdentifiers.Add(runtimeIdentifier);
419435
}
420436
}
421-
else
437+
else if (addToPackageDownload)
422438
{
423439
foreach (var runtimePackNamePattern in selectedRuntimePack.RuntimePackNamePatterns.Split(';'))
424440
{
@@ -620,18 +636,13 @@ public KnownFrameworkReference(ITaskItem item)
620636
// The framework name to write to the runtimeconfig file (and the name of the folder under dotnet/shared)
621637
public string RuntimeFrameworkName => _item.GetMetadata(MetadataKeys.RuntimeFrameworkName);
622638
public string DefaultRuntimeFrameworkVersion => _item.GetMetadata("DefaultRuntimeFrameworkVersion");
623-
//public string LatestRuntimeFrameworkVersion => _item.GetMetadata("LatestRuntimeFrameworkVersion");
624639

625640
// The ID of the targeting pack NuGet package to reference
626641
public string TargetingPackName => _item.GetMetadata("TargetingPackName");
627642
public string TargetingPackVersion => _item.GetMetadata("TargetingPackVersion");
628643
public string TargetingPackFormat => _item.GetMetadata("TargetingPackFormat");
629644

630-
//public string RuntimePackNamePatterns => _item.GetMetadata("RuntimePackNamePatterns");
631-
632-
//public string RuntimePackRuntimeIdentifiers => _item.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);
633-
634-
//public string IsTrimmable => _item.GetMetadata(MetadataKeys.IsTrimmable);
645+
public string RuntimePackRuntimeIdentifiers => _item.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers);
635646

636647
public bool IsWindowsOnly => _item.HasMetadataValue("IsWindowsOnly", "true");
637648

@@ -668,8 +679,6 @@ public KnownRuntimePack(ITaskItem item)
668679
public string Name => _item.ItemSpec;
669680

670681
//// The framework name to write to the runtimeconfig file (and the name of the folder under dotnet/shared)
671-
//public string RuntimeFrameworkName => _item.GetMetadata(MetadataKeys.RuntimeFrameworkName);
672-
//public string DefaultRuntimeFrameworkVersion => _item.GetMetadata("DefaultRuntimeFrameworkVersion");
673682
public string LatestRuntimeFrameworkVersion => _item.GetMetadata("LatestRuntimeFrameworkVersion");
674683

675684
public string RuntimePackNamePatterns => _item.GetMetadata("RuntimePackNamePatterns");

src/Tests/Microsoft.NET.Build.Tests/KnownRuntimePackTests.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.IO;
32
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
63
using System.Xml.Linq;
74
using FluentAssertions;
85
using Microsoft.NET.TestFramework;
@@ -139,5 +136,42 @@ private void AddItem(TestAsset testAsset, XElement item)
139136
itemGroup.Add(item);
140137
});
141138
}
139+
140+
[WindowsOnlyFact]
141+
public void ItCanPublishArm64Winforms()
142+
{
143+
var testDirectory = _testAssetsManager.CreateTestDirectory().Path;
144+
145+
var newCommand = new DotnetCommand(Log, "new", "winforms", "--no-restore");
146+
newCommand.WorkingDirectory = testDirectory;
147+
newCommand.Execute().Should().Pass();
148+
149+
new PublishCommand(Log, testDirectory)
150+
.Execute("/p:RuntimeIdentifier=win-arm64")
151+
.Should()
152+
.Pass();
153+
154+
var selfContainedPublishDir = new DirectoryInfo(testDirectory)
155+
.Sub("bin").Sub("Debug").GetDirectories().FirstOrDefault()
156+
.Sub("win-arm64").Sub("publish");
157+
158+
selfContainedPublishDir.Should().HaveFilesMatching("System.Windows.Forms.dll", SearchOption.TopDirectoryOnly);
159+
selfContainedPublishDir.Should().HaveFilesMatching($"{new DirectoryInfo(testDirectory).Name}.dll", SearchOption.TopDirectoryOnly);
160+
}
161+
162+
[WindowsOnlyFact]
163+
public void ItCantPublishArm64Wpf()
164+
{
165+
var testDirectory = _testAssetsManager.CreateTestDirectory().Path;
166+
167+
var newCommand = new DotnetCommand(Log, "new", "wpf", "--no-restore");
168+
newCommand.WorkingDirectory = testDirectory;
169+
newCommand.Execute().Should().Pass();
170+
171+
new PublishCommand(Log, testDirectory)
172+
.Execute("/p:RuntimeIdentifier=win-arm64")
173+
.Should()
174+
.Fail();
175+
}
142176
}
143177
}

0 commit comments

Comments
 (0)