From 905f8ec53fd5678b7094249a109cea8c20814892 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Mon, 12 Jan 2026 17:03:47 +0100 Subject: [PATCH 1/3] ProcessFrameworkReferences: use portable ILCompiler when RuntimeIdentifier is null. --- .../Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index 7b5b7bc0da15..a277dc873705 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -835,7 +835,6 @@ private ToolPackSupport AddToolPack( string? supportedPortableTargetRid = NuGetUtils.GetBestMatchingRid(runtimeGraph, runtimeIdentifier, packSupportedPortableRuntimeIdentifiers, out _); bool usePortable = !string.IsNullOrEmpty(NETCoreSdkPortableRuntimeIdentifier) - && supportedTargetRid is not null && supportedPortableTargetRid is not null && supportedTargetRid == supportedPortableTargetRid; // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture From 167283af0c0a70cab603e7504f5ca4a35312c3aa Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Mon, 12 Jan 2026 18:28:35 +0100 Subject: [PATCH 2/3] Add test. --- .../ProcessFrameworkReferencesTests.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs index 50b1b9c8df00..e4f298db6844 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs @@ -76,6 +76,30 @@ public class ProcessFrameworkReferencesTests } """; + private const string NonPortableRid = "fedora.42-x64"; + + private static readonly string NonPortableRuntimeGraph = $$""" + { + "runtimes": { + "base": { + "#import": [] + }, + "any": { + "#import": ["base"] + }, + "linux": { + "#import": ["any"] + }, + "linux-x64": { + "#import": ["linux"] + }, + "{{NonPortableRid}}": { + "#import": ["linux-x64"] + } + } + } + """; + // Shared known framework references private readonly MockTaskItem _validWindowsSDKKnownFrameworkReference = CreateKnownFrameworkReference( "Microsoft.Windows.SDK.NET.Ref", "net5.0-windows10.0.18362", "10.0.18362.1-preview", @@ -491,6 +515,7 @@ public void It_handles_real_world_ridless_scenario_with_aot_and_trimming() ["TargetFramework"] = "net10.0", ["ILCompilerPackNamePattern"] = "runtime.**RID**.Microsoft.DotNet.ILCompiler", ["ILCompilerPackVersion"] = "10.0.0-rc.2.25457.102", + ["ILCompilerPortableRuntimeIdentifiers"] = "osx-x64;osx-arm64;win-x64;linux-x64", ["ILCompilerRuntimeIdentifiers"] = "osx-x64;osx-arm64;win-x64;linux-x64" }); @@ -766,5 +791,52 @@ public void It_handles_complex_cross_compilation_RuntimeIdentifiers() $"Should include runtime pack for supported RID: {rid}"); } } + + [Theory] + [InlineData(null, "linux-x64")] + [InlineData("linux-x64", "linux-x64")] + [InlineData(NonPortableRid, NonPortableRid)] + public void It_selects_correct_ILCompiler_based_on_RuntimeIdentifier(string? runtimeIdentifier, string expectedILCompilerRid) + { + var netCoreAppRef = CreateKnownFrameworkReference("Microsoft.NETCore.App", "net10.0", "10.0.1", + "Microsoft.NETCore.App.Runtime.**RID**", + "linux-x64;" + NonPortableRid); + + var ilCompilerPack = new MockTaskItem("Microsoft.DotNet.ILCompiler", new Dictionary + { + ["TargetFramework"] = "net10.0", + ["ILCompilerPackNamePattern"] = "runtime.**RID**.Microsoft.DotNet.ILCompiler", + ["ILCompilerPackVersion"] = "10.0.1", + ["ILCompilerPortableRuntimeIdentifiers"] = "linux-x64", + ["ILCompilerRuntimeIdentifiers"] = "linux-x64;" + NonPortableRid + }); + + var config = new TaskConfiguration + { + TargetFrameworkVersion = "10.0", + EnableRuntimePackDownload = true, + PublishAot = true, + NETCoreSdkRuntimeIdentifier = NonPortableRid, + NETCoreSdkPortableRuntimeIdentifier = "linux-x64", + RuntimeIdentifier = runtimeIdentifier, + RuntimeGraphPath = CreateRuntimeGraphFile(NonPortableRuntimeGraph), + FrameworkReferences = new[] { new MockTaskItem("Microsoft.NETCore.App", new Dictionary()) }, + KnownFrameworkReferences = new[] { netCoreAppRef }, + KnownILCompilerPacks = new[] { ilCompilerPack } + }; + + var task = CreateTask(config); + task.Execute().Should().BeTrue("Task should succeed"); + + // Validate that the expected ILCompiler pack is used + task.PackagesToDownload.Should().NotBeNull(); + task.PackagesToDownload.Should().Contain(p => p.ItemSpec.Contains("Microsoft.DotNet.ILCompiler"), + "Should include ILCompiler pack when PublishAot is true"); + + var ilCompilerPackage = task.PackagesToDownload.FirstOrDefault(p => p.ItemSpec.Contains("Microsoft.DotNet.ILCompiler")); + ilCompilerPackage.Should().NotBeNull(); + ilCompilerPackage!.ItemSpec.Should().Contain(expectedILCompilerRid, + $"Should use {expectedILCompilerRid} ILCompiler pack"); + } } } From 453cd1803b0a918e5b3cdda152bd9ac6263adbfb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:48:50 +0100 Subject: [PATCH 3/3] [release/11.0.1xx-preview1] Don't use the portable RIDs for older runtimes if it's empty (#52685) Co-authored-by: Marc Paine --- .../ProcessFrameworkReferences.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index a277dc873705..fcc306fd454c 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -816,8 +816,10 @@ private ToolPackSupport AddToolPack( if (toolPackType is ToolPackType.Crossgen2 or ToolPackType.ILCompiler) { var packNamePattern = knownPack.GetMetadata(packName + "PackNamePattern"); - var packSupportedRuntimeIdentifiers = knownPack.GetMetadata(packName + "RuntimeIdentifiers").Split(';'); - var packSupportedPortableRuntimeIdentifiers = knownPack.GetMetadata(packName + "PortableRuntimeIdentifiers").Split(';'); + var packSupportedRuntimeIdentifiers = knownPack.GetMetadata(packName + "RuntimeIdentifiers").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + var packSupportedPortableRuntimeIdentifiers = knownPack.GetMetadata(packName + "PortableRuntimeIdentifiers").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + // Use the non-portable RIDs if there are no portable RIDs defined. + packSupportedPortableRuntimeIdentifiers = packSupportedPortableRuntimeIdentifiers.Length > 0 ? packSupportedPortableRuntimeIdentifiers : packSupportedRuntimeIdentifiers; // When publishing for a non-portable RID, prefer NETCoreSdkRuntimeIdentifier for the host. // Otherwise prefer the NETCoreSdkPortableRuntimeIdentifier. @@ -839,6 +841,7 @@ private ToolPackSupport AddToolPack( // Get the best RID for the host machine, which will be used to validate that we can run crossgen for the target platform and architecture Log.LogMessage(MessageImportance.Low, $"Determining best RID for '{knownPack.ItemSpec}@{packVersion}' from among '{knownPack.GetMetadata(packName + "RuntimeIdentifiers")}'"); + string? hostRuntimeIdentifier = usePortable ? NuGetUtils.GetBestMatchingRid(runtimeGraph, NETCoreSdkPortableRuntimeIdentifier!, packSupportedPortableRuntimeIdentifiers, out _) : NuGetUtils.GetBestMatchingRid(runtimeGraph, NETCoreSdkRuntimeIdentifier!, packSupportedRuntimeIdentifiers, out _);