Skip to content

Fix NativeAOT publish: rebuild RID-specific assembly with generated sources#38322

Open
Copilot wants to merge 11 commits into
mainfrom
copilot/provide-workaround-comment-md
Open

Fix NativeAOT publish: rebuild RID-specific assembly with generated sources#38322
Copilot wants to merge 11 commits into
mainfrom
copilot/provide-workaround-comment-md

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 28, 2026

dotnet publish /p:PublishAot=true (with or without -r <RID>, and regardless of EFScaffoldModelStage/EFPrecompileQueriesStage) failed at runtime with Model building is not supported when publishing with NativeAOT. The compiled model and precompiled queries were generated correctly, but ILC consumed the stale RID-specific intermediate assembly produced by the outer CoreCompile before generation ran.

Targets (Microsoft.EntityFrameworkCore.Tasks.targets)

  • Refactor _EFGenerateFiles to share a single _EFInnerBuildProperties across inner invocations (PublishAot=false, propagates _EFGenerationStage).
  • Restore PublishAot-gated behavior for reflection-friendly inner generation: RuntimeIdentifier=;SelfContained=false and the first inner Build now run only when PublishAot/_EFPublishAOT is true.
  • Keep OptimizeDbContext running with _EFInnerBuildProperties.
  • Keep the final unconditional Build (<CallTarget Targets="Build" />) so the current invocation output (including RID-specific output) is rebuilt with generated sources before publish/ILC consumption.
  • Remove <CallTarget Targets="Build" /> from OptimizeDbContext.

Flow

For AOT publish:

outer CoreCompile        → obj/.../<RID>/App.dll        (no generated sources)
inner Build (refl.)      → obj/.../App.dll              (PublishAot=false, RID cleared)
inner OptimizeDbContext  → obj/.../App.dll              (writes generated *.g.cs, recompiles)
inner Build (final)      → obj/.../<RID>/App.dll        (current invocation properties)
ILC                      → consumes refreshed RID dll with generated sources

For non-AOT publish (including RID publish), the first reflection-only inner Build is skipped, and generation/rebuild runs without forcing RID clearing.

Copilot AI and others added 5 commits May 27, 2026 21:06
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
…riage md

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
…for PublishAot

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
… on PublishAot

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Comment thread src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets Outdated
Comment thread src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets Outdated
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a NativeAOT publish failure where ILC consumes a stale RID-specific intermediate assembly that was compiled before EF’s generated sources (compiled model / precompiled queries interceptors) were produced, leading to a runtime failure (“Model building is not supported when publishing with NativeAOT”).

Changes:

  • Refactors _EFGenerateFiles to centralize inner-build property computation and ensure the generation build runs in a reflection-friendly configuration (RID cleared, SelfContained=false, PublishAot=false).
  • Adds an additional post-generation inner Build that restores PublishAot/RID-related properties to refresh the RID-specific intermediate assembly before ILC runs.
  • Updates transitive props to include Microsoft.EntityFrameworkCore.GeneratedInterceptors in InterceptorsNamespaces so generated interceptor sources compile without consumer opt-in.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets Reworks the inner-build flow to generate sources using a non-RID, non-AOT build and then rebuild the RID-specific assembly after generation; removes the prior CallTarget Build inside OptimizeDbContext.
src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.props Enables the generated interceptors namespace by default via InterceptorsNamespaces for transitive consumption.

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Comment thread src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.props Outdated
Comment thread src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets Outdated
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI and others added 2 commits May 28, 2026 06:58
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI requested a review from AndriySvyryd May 28, 2026 23:23
@AndriySvyryd AndriySvyryd marked this pull request as ready for review May 28, 2026 23:27
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner May 28, 2026 23:27
Copilot AI review requested due to automatic review settings May 28, 2026 23:27
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +65 to +67
<!-- Inner builds disable AOT; for AOT publish they also clear RID/SelfContained to use reflection-friendly output. -->
<_EFInnerBuildProperties>Configuration=$(Configuration);Platform=$(Platform);PublishAot=false;_EFGenerationStage=$(_EFGenerationStage)</_EFInnerBuildProperties>
<_EFInnerBuildProperties Condition="'$(PublishAot)'=='true' Or '$(_EFPublishAOT)'=='true'">$(_EFInnerBuildProperties);RuntimeIdentifier=;SelfContained=false</_EFInnerBuildProperties>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants