diff --git a/src/Layout/redist/targets/GenerateBundledVersions.targets b/src/Layout/redist/targets/GenerateBundledVersions.targets index 94f679f464dc..67d2f40a55c6 100644 --- a/src/Layout/redist/targets/GenerateBundledVersions.targets +++ b/src/Layout/redist/targets/GenerateBundledVersions.targets @@ -588,6 +588,7 @@ Copyright (c) .NET Foundation. All rights reserved. diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index 84f1ba2143fa..db3c6905fc12 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -847,13 +847,36 @@ private ToolPackSupport AddToolPack( { return ToolPackSupport.UnsupportedForTargetRuntimeIdentifier; } - if (!hostRuntimeIdentifier.Equals(targetRuntimeIdentifier)) + + // If there's an available runtime pack, use it instead of the ILCompiler package for target-specific bits. + bool useRuntimePackForAllTargets = false; + string targetPackNamePattern = packNamePattern; + if (knownPack.GetMetadata("ILCompilerRuntimePackNamePattern") is string runtimePackNamePattern && runtimePackNamePattern != string.Empty) { - var targetIlcPackName = packNamePattern.Replace("**RID**", targetRuntimeIdentifier); + targetPackNamePattern = runtimePackNamePattern; + useRuntimePackForAllTargets = true; + } + + if (useRuntimePackForAllTargets || !hostRuntimeIdentifier.Equals(targetRuntimeIdentifier)) + { + var targetIlcPackName = targetPackNamePattern.Replace("**RID**", targetRuntimeIdentifier); var targetIlcPack = new TaskItem(targetIlcPackName); targetIlcPack.SetMetadata(MetadataKeys.NuGetPackageId, targetIlcPackName); targetIlcPack.SetMetadata(MetadataKeys.NuGetPackageVersion, packVersion); TargetILCompilerPacks = new[] { targetIlcPack }; + + string targetILCompilerPackPath = GetPackPath(targetIlcPackName, packVersion); + if (targetILCompilerPackPath != null) + { + targetIlcPack.SetMetadata(MetadataKeys.PackageDirectory, targetILCompilerPackPath); + } + else if (EnableRuntimePackDownload) + { + // We need to download the runtime pack + var targetIlcPackToDownload = new TaskItem(targetIlcPackName); + targetIlcPackToDownload.SetMetadata(MetadataKeys.Version, packVersion); + packagesToDownload.Add(targetIlcPackToDownload); + } } } diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs index 9355be163c3f..7963c9924869 100644 --- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs +++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs @@ -15,7 +15,7 @@ public class GivenThatWeWantToPublishAnAotApp : SdkTest { private readonly string RuntimeIdentifier = $"/p:RuntimeIdentifier={RuntimeInformation.RuntimeIdentifier}"; - private readonly string ExplicitPackageVersion = "7.0.0-rc.2.22456.11"; + private const string NetCurrentExplicitPackageVersion = "10.0.0-preview.6.25316.103"; public GivenThatWeWantToPublishAnAotApp(ITestOutputHelper log) : base(log) { @@ -67,8 +67,10 @@ public void NativeAot_hw_runs_with_no_warnings_when_PublishAot_is_enabled(string DoSymbolsExist(publishDirectory, testProject.Name).Should().BeTrue($"{publishDirectory} should contain {testProject.Name} symbol"); IsNativeImage(publishedExe).Should().BeTrue(); + bool useRuntimePackLayout = targetFramework is not ("net7.0" or "net8.0" or "net9.0"); + GetKnownILCompilerPackVersion(testAsset, targetFramework, out string expectedVersion); - CheckIlcVersions(testAsset, targetFramework, rid, expectedVersion); + CheckIlcVersions(testAsset, targetFramework, rid, expectedVersion, useRuntimePackLayout); var command = new RunExeCommand(Log, publishedExe) .Execute().Should().Pass() @@ -249,8 +251,10 @@ public void NativeAot_app_builds_with_config_when_PublishAot_is_enabled(string t File.Exists(depsPath).Should().BeTrue(); } + private const string Net7ExplicitPackageVersion = "7.0.0"; + [RequiresMSBuildVersionTheory("17.0.0.32901")] - [InlineData(ToolsetInfo.CurrentTargetFramework)] + [InlineData("net7.0")] public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_enabled(string targetFramework) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -266,7 +270,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_enabled(string testProject.AdditionalProperties["PublishAot"] = "true"; // This will add a reference to a package that will also be automatically imported by the SDK - testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", Net7ExplicitPackageVersion)); // Linux symbol files are embedded and require additional steps to be stripped to a separate file // assumes /bin (or /usr/bin) are in the PATH @@ -302,7 +306,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_enabled(string .Execute().Should().Pass() .And.HaveStdOutContaining("Hello World"); - CheckIlcVersions(testAsset, targetFramework, rid, ExplicitPackageVersion); + CheckIlcVersions(testAsset, targetFramework, rid, Net7ExplicitPackageVersion, useRuntimePackLayout: false); } [RequiresMSBuildVersionTheory("17.0.0.32901")] @@ -315,7 +319,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_empty(string t var testProject = CreateHelloWorldTestProject(targetFramework, projectName, true); // This will add a reference to a package that will also be automatically imported by the SDK - testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", NetCurrentExplicitPackageVersion)); // Linux symbol files are embedded and require additional steps to be stripped to a separate file // assumes /bin (or /usr/bin) are in the PATH @@ -343,7 +347,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_empty(string t } [RequiresMSBuildVersionTheory("17.0.0.32901")] - [MemberData(nameof(Net7Plus), MemberType = typeof(PublishTestUtils))] + [InlineData(ToolsetInfo.CurrentTargetFramework)] public void NativeAot_hw_runs_with_cross_target_PublishAot_is_enabled(string targetFramework) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && (RuntimeInformation.OSArchitecture == Architecture.X64)) @@ -367,13 +371,13 @@ public void NativeAot_hw_runs_with_cross_target_PublishAot_is_enabled(string tar File.Exists(publishedExe).Should().BeTrue(); GetKnownILCompilerPackVersion(testAsset, targetFramework, out string expectedVersion); - CheckIlcVersions(testAsset, targetFramework, rid, expectedVersion); + CheckIlcVersions(testAsset, targetFramework, rid, expectedVersion, useRuntimePackLayout: true); } } [RequiresMSBuildVersionTheory("17.0.0.32901")] - [MemberData(nameof(Net7Plus), MemberType = typeof(PublishTestUtils))] + [InlineData(ToolsetInfo.CurrentTargetFramework)] public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_enabled(string targetFramework) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && (RuntimeInformation.OSArchitecture == Architecture.X64)) @@ -382,11 +386,16 @@ public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_enabled( var rid = "win-arm64"; var testProject = CreateHelloWorldTestProject(targetFramework, projectName, true); + testProject.RecordProperties("BundledNETCoreAppPackageVersion"); testProject.AdditionalProperties["PublishAot"] = "true"; // This will add a reference to a package that will also be automatically imported by the SDK - testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); - testProject.PackageReferences.Add(new TestPackageReference("runtime.win-x64.Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", "$(BundledNETCoreAppPackageVersion)")); + testProject.AddItem("PackageDownload", new Dictionary + { + { "Include", "Microsoft.NETCore.App.Runtime.NativeAOT.win-arm64" }, + { "Version", $"[$(BundledNETCoreAppPackageVersion)]" } + }); var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); @@ -398,13 +407,16 @@ public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_enabled( .And.HaveStdOutContaining("warning") .And.HaveStdOutContaining("Microsoft.DotNet.ILCompiler"); + var buildProperties = testProject.GetPropertyValues(testAsset.TestRoot, targetFramework); + var targetVersion = buildProperties["BundledNETCoreAppPackageVersion"]; + var publishDirectory = publishCommand.GetOutputDirectory(targetFramework: targetFramework, runtimeIdentifier: rid).FullName; var publishedDll = Path.Combine(publishDirectory, $"{projectName}.dll"); var publishedExe = Path.Combine(publishDirectory, $"{testProject.Name}{Constants.ExeSuffix}"); File.Exists(publishedDll).Should().BeFalse(); File.Exists(publishedExe).Should().BeTrue(); - CheckIlcVersions(testAsset, targetFramework, rid, ExplicitPackageVersion); + CheckIlcVersions(testAsset, targetFramework, rid, targetVersion, useRuntimePackLayout: true); } } @@ -420,8 +432,8 @@ public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_empty(st var testProject = CreateHelloWorldTestProject(targetFramework, projectName, true); // This will add a reference to a package that will also be automatically imported by the SDK - testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); - testProject.PackageReferences.Add(new TestPackageReference("runtime.win-x64.Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", NetCurrentExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("runtime.win-x64.Microsoft.DotNet.ILCompiler", NetCurrentExplicitPackageVersion)); var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); @@ -469,7 +481,7 @@ public void NativeAot_hw_fails_with_sdk6_PackageReference_PublishAot_is_enabled( var testProject = CreateHelloWorldTestProject("net6.0", projectName, true); testProject.AdditionalProperties["PublishAot"] = "true"; - testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", ExplicitPackageVersion)); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DotNet.ILCompiler", NetCurrentExplicitPackageVersion)); var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); @@ -1041,7 +1053,7 @@ private void GetKnownILCompilerPackVersion(TestAsset testAsset, string targetFra .Single(); } - private void CheckIlcVersions(TestAsset testAsset, string targetFramework, string rid, string expectedVersion) + private void CheckIlcVersions(TestAsset testAsset, string targetFramework, string rid, string expectedVersion, bool useRuntimePackLayout) { // Compiler version matches expected version var ilcToolsPathCommand = new GetValuesCommand(testAsset, "IlcToolsPath", targetFramework: targetFramework) @@ -1061,7 +1073,17 @@ private void CheckIlcVersions(TestAsset testAsset, string targetFramework, strin ilcReferenceCommand.Execute($"/p:RuntimeIdentifier={rid}", "/p:SelfContained=true").Should().Pass(); var ilcReference = ilcReferenceCommand.GetValues(); var corelibReference = ilcReference.Where(r => Path.GetFileName(r).Equals("System.Private.CoreLib.dll")).Single(); - var ilcReferenceVersion = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(corelibReference))); + string ilcReferenceVersion; + if (useRuntimePackLayout) + { + // In the runtime pack layout, System.Private.CoreLib.dll is in the runtimes//native directory + ilcReferenceVersion = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(corelibReference))))); + } + else + { + // In the old layout, System.Private.CoreLib.dll is in the framework directory + ilcReferenceVersion = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(corelibReference))); + } ilcReferenceVersion.Should().Be(expectedVersion); }