diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs index 34286cbb468a..cabcd3734b17 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs @@ -82,6 +82,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", @@ -493,6 +517,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" }); @@ -967,5 +992,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"); + } } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index 4cc5fcbb37cf..390f7962b0a6 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -857,7 +857,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