From 9ea8b9c5b8dbd29b91a56958492afdac8b441bb2 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 16 Mar 2026 11:51:51 -0700 Subject: [PATCH 1/6] Use SDK NativeCompile hook instead of BeforeTargets/AfterTargets for ILC publish integration Redefine the SDK's empty NativeCompile placeholder target with the actual NativeAOT compilation pipeline, replacing the fragile BeforeTargets/AfterTargets hooks that previously sequenced ILC into the publish flow. - Rename ComputeLinkedFilesToPublish to NativeCompile in Publish.targets, removing AfterTargets="ComputeResolvedFilesToPublishList" - Remove BeforeTargets="Publish" from SetupProperties, ComputeIlcCompileInputs, and ImportRuntimeIlcPackageTarget (all reachable via DependsOnTargets chains) - Keep empty ComputeLinkedFilesToPublish and CopyNativeBinary for back-compat --- ...soft.DotNet.ILCompiler.SingleEntry.targets | 2 +- .../Microsoft.NETCore.Native.Publish.targets | 23 ++++++++++++++----- .../Microsoft.NETCore.Native.targets | 4 ++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets index cf313984696b5f..de638995717d6b 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets @@ -62,7 +62,7 @@ - + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index 1776c7bf1d4ed5..a6a6e05172162a 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -14,13 +14,20 @@ - @@ -60,6 +67,10 @@ + + + - + <_NETCoreAppFrameworkReference Include="@(ResolvedFrameworkReference)" Condition="'%(ResolvedFrameworkReference.RuntimePackName)' == 'Microsoft.NETCore.App.Runtime.NativeAOT.$(RuntimeIdentifier)'" /> @@ -156,7 +156,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + From bd12de944c1245f70ae639d2b4d4832dea49c83d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 16 Mar 2026 12:06:22 -0700 Subject: [PATCH 2/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Microsoft.NETCore.Native.Publish.targets | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index a6a6e05172162a..255dd63ef53ed9 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -21,10 +21,11 @@ NativeAOT compilation pipeline: ILC compilation, native linking, and updating ResolvedFileToPublish to replace managed assemblies with the native binary. - The SDK sequences this target in the publish pipeline as: - ComputeResolvedFilesToPublishList -> ILLink -> NativeCompile -> ... + The SDK typically sequences this target in the publish pipeline as: + ComputeResolvedFilesToPublishList -> ILLink (when RunILLink is true) -> NativeCompile -> ... - This gives us a clean, explicit position after ILLink (trim configuration). + This gives us a clean, explicit position after trim configuration (_PrepareTrimConfiguration), + regardless of whether ILLink itself runs. ============================================================ --> Date: Mon, 16 Mar 2026 14:23:23 -0700 Subject: [PATCH 3/6] Defer ILC targets import in test infra to after SDK targets The test infrastructure directly imported SingleEntry.targets from Directory.Build.targets, which is evaluated before Microsoft.NET.Sdk.targets. This caused the SDK's empty NativeCompile placeholder (in Publish.targets) to overwrite the NativeAOT redefinition (MSBuild last-definition-wins), resulting in no native compilation during NativeAOT test runs. Use AfterMicrosoftNETSdkTargets to defer the import to after all SDK targets, matching the pattern already used for ReadyToRun targets in tests.singlefile.targets. --- eng/testing/tests.singlefile.targets | 8 +++++++- src/tests/Directory.Build.targets | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index 6a50cbbfbf55a8..818881aa3eae8b 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -42,7 +42,13 @@ $(DefineConstants);TEST_READY_TO_RUN_COMPILED - + + + $(AfterMicrosoftNETSdkTargets);$(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets + diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index bd7093beb18339..6d77098d36327b 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -575,7 +575,12 @@ - + + + $(AfterMicrosoftNETSdkTargets);$(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets + From 9639ed2eaf4622729bb49f906c878b0dd65fac09 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 16 Mar 2026 16:31:08 -0700 Subject: [PATCH 4/6] Set PublishTrimmed early for NativeAOT tests to ensure ILLink targets load Deferring the ILC import via AfterMicrosoftNETSdkTargets also deferred the PublishTrimmed=true that Microsoft.NETCore.Native.targets sets at evaluation time. This caused liveILLink.targets to compute _RequiresLiveILLink=false (since PublishTrimmed was not yet set), so ILLink targets were never loaded, and _PrepareTrimConfiguration was missing at build time. Set PublishTrimmed=true explicitly in the NativeAOT test PropertyGroups before liveILLink.targets is imported. NativeAOT always enables trimming, so this is semantically correct. --- eng/testing/tests.singlefile.targets | 6 ++++++ src/tests/Directory.Build.targets | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index 818881aa3eae8b..039d427116e894 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -30,6 +30,12 @@ false true + + true + true diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 6d77098d36327b..6bd8b2c20e26e8 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -544,6 +544,12 @@ false + + true + $(CoreCLRCrossILCompilerDir) $(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll $(CoreCLRAotSdkDir) From 4a3adf6d7ee316d3244aad0d2796ce02ff774852 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 18 Mar 2026 11:34:30 -0700 Subject: [PATCH 5/6] Use ILCompilerTargetsPath instead of AfterMicrosoftNETSdkTargets for ILC import Replace the AfterMicrosoftNETSdkTargets hook with the SDK's ILCompilerTargetsPath extension point to import ILC targets in the correct order (before ILLink), fixing the DynamicCodeSupport property evaluation error. Gate IlcSetupPropertiesDependsOn on _IlcReferencedAsPackage to skip NuGet package resolution when using live ILC targets. --- eng/testing/tests.singlefile.targets | 18 +++++------------- ...osoft.DotNet.ILCompiler.SingleEntry.targets | 2 +- src/tests/Directory.Build.targets | 16 +++++----------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index 039d427116e894..1a992b1b7e10d3 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -30,11 +30,11 @@ false true - - true + + true + <_IlcReferencedAsPackage>false + $(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets true @@ -48,14 +48,6 @@ $(DefineConstants);TEST_READY_TO_RUN_COMPILED - - - $(AfterMicrosoftNETSdkTargets);$(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets - - diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets index de638995717d6b..62cb2d8f7aadc4 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets @@ -42,7 +42,7 @@ RunResolvePackageDependencies - ImportRuntimeIlcPackageTarget + ImportRuntimeIlcPackageTarget SetupProperties diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 6bd8b2c20e26e8..c9a5138af52d8a 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -544,11 +544,11 @@ false - - true + + true + <_IlcReferencedAsPackage>false + $(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets $(CoreCLRCrossILCompilerDir) $(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll @@ -581,12 +581,6 @@ - - - $(AfterMicrosoftNETSdkTargets);$(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets - From 9f2854028ca877149b205c16e15151368d574b8f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 18 Mar 2026 12:43:56 -0700 Subject: [PATCH 6/6] Disable single-file analyzer for coreclr tests PublishAot=true (added for SDK import order) enables EnableSingleFileAnalyzer, which promotes IL3000 (Assembly.Location usage) to an error in tracing tests. Disable it alongside the existing EnableTrimAnalyzer and EnableAotAnalyzer suppressions. --- src/tests/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/Directory.Build.props b/src/tests/Directory.Build.props index df43d981422b54..b6dce9ef455492 100644 --- a/src/tests/Directory.Build.props +++ b/src/tests/Directory.Build.props @@ -143,6 +143,7 @@ false false false + false false true Test