Skip to content

[net11.0] Move feature switch RHCO items to static evaluation to fix IL3050 on Android NativeAOT#35134

Closed
sbomer wants to merge 4 commits intonet11.0from
dev/sbomer/maui-il3050-static-net11
Closed

[net11.0] Move feature switch RHCO items to static evaluation to fix IL3050 on Android NativeAOT#35134
sbomer wants to merge 4 commits intonet11.0from
dev/sbomer/maui-il3050-static-net11

Conversation

@sbomer
Copy link
Copy Markdown
Member

@sbomer sbomer commented Apr 24, 2026

Note

This PR was created with assistance from AI.

Summary

Move RuntimeHostConfigurationOption items and their property defaults out of the _MauiPrepareForILLink target into static PropertyGroup/ItemGroup blocks evaluated at import time. This requires no runtime changes.

Problem

dotnet/runtime#124801 moved the RuntimeHostConfigurationOption_TrimmerFeatureSettings conversion from PrepareForILLink into an earlier internal target (_PrepareTrimConfiguration). MAUI's _MauiPrepareForILLink hooks BeforeTargets="PrepareForILLink", which fires after the snapshot. ILC never receives --feature flags for MAUI's switches on Android NativeAOT, causing spurious IL3050 warnings for HybridWebViewHandler.

Fix

The property conditions (PublishAot, TrimMode, Optimize) are all static project properties available at evaluation time — there's no reason for these to be set inside a target. Moving them to static blocks makes them visible before any targets run, so _PrepareTrimConfiguration picks them up regardless of target ordering.

A sentinel property (_EnableMauiAspireUserOverride) captures the user-specified _EnableMauiAspire value before the default is set, so the MA002 warning correctly detects external overrides without false positives from MAUI's own default.

The Warning task (MA002 Aspire validation) remains in _MauiPrepareForILLink since MSBuild tasks require a target context.

This approach requires no runtime changes.

Verified

Tested locally with an Android NativeAOT MAUI app:

  • Before: --feature:Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported=false missing from ILC rsp → IL3050
  • After: --feature flag present → IL3050 suppressed by FeatureGuard

Fixes dotnet/runtime#127017

cc @sbomer @simonrozsival @MichalStrehovsky

sbomer and others added 2 commits April 24, 2026 11:50
Move PropertyGroup defaults and RuntimeHostConfigurationOption items out
of _MauiPrepareForILLink (a target) into static PropertyGroup/ItemGroup
blocks that are evaluated at import time. This ensures RHCO items are
visible before any MSBuild targets run, so _PrepareTrimConfiguration
can snapshot them into _TrimmerFeatureSettings for both ILLink and ILC.

Previously these were added in _MauiPrepareForILLink (BeforeTargets=
"PrepareForILLink"), but runtime PR dotnet/runtime#124801 moved the
RHCO → _TrimmerFeatureSettings conversion to an earlier target
(_PrepareTrimConfiguration), causing MAUI's feature switches to be
missed by ILC on Android NativeAOT.

The property conditions (PublishAot/TrimMode) are static project
properties available at evaluation time, so there is no need for
these to run inside a target. The Warning task for MA002 remains in
_MauiPrepareForILLink since MSBuild tasks require a target context.

Fixes dotnet/runtime#127017

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Capture the user-specified _EnableMauiAspire value into a sentinel
property (_EnableMauiAspireUserOverride) before setting the default.
The MA002 warning now checks the sentinel instead of _EnableMauiAspire
itself, so it only fires when the user explicitly set the property.

Previously the Warning ran inside a target before _EnableMauiAspire
was set, so checking '!= empty' correctly detected user overrides.
Now that _EnableMauiAspire is set statically, MAUI always populates
it, so the sentinel is needed to distinguish user vs MAUI values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Copilot AI review requested due to automatic review settings April 24, 2026 18:58
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35134

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35134"

Copy link
Copy Markdown
Contributor

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

Moves MAUI feature switch defaults and RuntimeHostConfigurationOption items to MSBuild evaluation-time so the runtime’s earlier trim configuration snapshot (_PrepareTrimConfiguration) can pick them up, fixing missing --feature flags in Android NativeAOT scenarios.

Changes:

  • Relocates feature-switch property defaults and RuntimeHostConfigurationOption items out of _MauiPrepareForILLink into static PropertyGroup/ItemGroup blocks.
  • Adds _EnableMauiAspireUserOverride to preserve the ability to warn only on user overrides after defaults moved to evaluation time.
  • Keeps MA002 warning emission in _MauiPrepareForILLink (target context).

evaluation time, before _PrepareTrimConfiguration snapshots RHCO items into
_TrimmerFeatureSettings. Previously these lived inside _MauiPrepareForILLink
(BeforeTargets="PrepareForILLink"), but that fires after _PrepareTrimConfiguration
runs, so ILC never received - -feature flags for MAUI switches on Android NativeAOT.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The comment says "ILC never received - -feature flags". This looks like a typo; it should be "--feature" (double hyphen) to match the actual ILC option name.

Suggested change
runs, so ILC never received - -feature flags for MAUI switches on Android NativeAOT.
runs, so ILC never received --feature flags for MAUI switches on Android NativeAOT.

Copilot uses AI. Check for mistakes.
Comment on lines +332 to +337
<!-- Capture user-specified value before setting the default, so the MA002
warning can detect external overrides. -->
<_EnableMauiAspireUserOverride>$(_EnableMauiAspire)</_EnableMauiAspireUserOverride>
<!-- Set _EnableMauiAspire based on whether optimizations are enabled when not already set -->
<_EnableMauiAspire Condition="'$(_EnableMauiAspire)' == '' and '$(Optimize)' != 'true'">true</_EnableMauiAspire>
<_EnableMauiAspire Condition="'$(_EnableMauiAspire)' == ''">false</_EnableMauiAspire>
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

_EnableMauiAspireUserOverride is only captured when PublishAot is true or TrimMode is full. If a user sets _EnableMauiAspire manually in an optimized build without those settings, MA002 will no longer trigger (the warning condition now checks only _EnableMauiAspireUserOverride). Consider capturing _EnableMauiAspireUserOverride unconditionally (e.g., in a separate PropertyGroup before any defaults are applied, and guarded so it doesn't overwrite) so the warning continues to detect external overrides in all optimized builds.

Copilot uses AI. Check for mistakes.
MauiCssEnabled's condition uses '@(MauiCss->Count())' which is an item
list reference not allowed in static PropertyGroup conditions (MSB4099).
Move it and its RHCO item back into _MauiPrepareForILLink.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Comment on lines 393 to 396
<RuntimeHostConfigurationOption Include="Microsoft.Maui.RuntimeFeature.IsCssEnabled"
Condition="'$(MauiCssEnabled)' != ''"
Value="$(MauiCssEnabled)"
Trim="true" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why isn't this one moved too? Is it because MauiCssEnabled is evaluated later based on the presence of any @(MauiCss) items?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

<!-- MauiCssEnabled depends on @(MauiCss) item list which cannot be evaluated
         in a static PropertyGroup condition (MSB4099). -->

I overlooked this comment.

Won't this cause the same issues which were caused by placing the other RHCO inside of the target? Could it happen that this feature switch is set too late due to some unexpected targets ordering?

Replace the @(MauiCss->Count()) item list check with a property-based
condition on EnableDefaultCssItems. MSBuild does not allow @() item
references in static PropertyGroup conditions (MSB4099).

When EnableDefaultCssItems is not 'true', no CSS glob runs, so
MauiCssEnabled defaults to false. When it is 'true', MauiCssEnabled
stays unset (CSS enabled by default) regardless of whether CSS files
exist on disk — the CSS code paths are present but never invoked if
no stylesheets are loaded, so there is no runtime behavior change.

This empties _MauiPrepareForILLink of all property/item logic, leaving
only the MA002 Warning task which requires a target context.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Apr 28, 2026

Closing this - #35094 works around the break, and MAUI folks need to decide how to address #35163.

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.

3 participants