Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
});

Expand Down Expand Up @@ -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<string, string>
{
["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<string, string>()) },
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");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,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.
Expand All @@ -853,15 +855,16 @@ private ToolPackSupport AddToolPack(
// This also ensures that targeting common RIDs doesn't require any non-portable assets that aren't packaged in the SDK by default.
// Due to size concerns, the non-portable ILCompiler and Crossgen2 aren't included by default in non-portable SDK distributions.
var runtimeIdentifier = RuntimeIdentifier ?? RuntimeIdentifierForPlatformAgnosticComponents;

string? supportedTargetRid = NuGetUtils.GetBestMatchingRid(runtimeGraph, runtimeIdentifier, packSupportedRuntimeIdentifiers, out _);
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
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 _);
Expand Down
Loading