[Extensibility] Fix dual-path backend activation and Compile filtering - #36955
[Extensibility] Fix dual-path backend activation and Compile filtering#36955PureWeen wants to merge 1 commit into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac6265fe-09a0-473c-b3f9-9ec6d6dd97cd
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36955Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36955" |
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
This PR adjusts SingleProject MSBuild targets to (1) default ActivationValue from BackendIdentity even when TargetPlatformIdentifier(s) metadata is also present (enabling dual-path activation), and (2) make _MauiRemovePlatformCompileItems remove only the Compile items explicitly marked ExcludeFromCurrentConfiguration=true rather than over-removing via cross-item-type batching.
Changes:
- Update
_MauiNormalizePlatformSpecificFoldersto back-fillActivationValuefromBackendIdentitywheneverActivationValueis empty (no longer gated by empty TPI metadata). - Rework
_MauiRemovePlatformCompileItemsto compute the removal set by intersecting the platform filesystem candidates with the actualCompileitems marked excluded. - Add MSBuild regression tests covering (a) recognized vs neutral activation via
BackendIdentity, and (b) compile-item removal behavior.
Show a summary per file
| File | Description |
|---|---|
| src/Controls/tests/Xaml.UnitTests/MSBuild/MSBuildTests.cs | Adds regression coverage for compile removal correctness and dual-path backend activation. |
| src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.SingleProject.targets | Fixes platform Compile removal to avoid cross-item batching over-removal by intersecting with excluded Compile identities. |
| src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.SingleProject.Before.targets | Expands activation defaulting so a single registration can participate in both recognized-TPI and neutral-selector activation paths. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 0
|
Closing as superseded by #36956, which addresses the same two post-merge gaps with stronger regression coverage for Compile metadata preservation, ordering/uniqueness, and dual-path backend activation. |
…ompile filtering (#36957) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description of Change This focused follow-up addresses two empirically validated gaps found by the GPT-5.6 Sol post-merge verification of #36654. 1. `BackendIdentity` now defaults `ActivationValue` even when `TargetPlatformIdentifier` or `TargetPlatformIdentifiers` is also present. A single registration can therefore activate through a recognized TPI or through `MauiActiveBackend` on a neutral TFM, while explicit `ActivationValue` and `ActivationProperty` metadata still win. 2. platform Compile removal now starts from the `Compile` items in the `ExcludeFromCurrentConfiguration=true` metadata batch and intersects them with physical `Platforms/**` candidates. A fresh filesystem glob can no longer pull an explicitly false Compile item from another metadata bucket into the removal set. The helper-item removal pattern remains in place, preserving active item order and avoiding remove/re-add duplication. ## Before and After Before this change, a registration such as: ```xml <MauiPlatformSpecificFolder Include="Platforms/MacOS/" TargetPlatformIdentifiers="macos" BackendIdentity="macos" /> ``` worked for recognized TPI `macos` but did not activate on a neutral TFM with `MauiActiveBackend=macos`. It now supports both paths and remains inactive for another recognized TPI or a mismatched backend. Before this change, the presence of any true Compile metadata batch caused a fresh `Platforms/**` glob to include physical files explicitly marked false by a downstream target. Removal is now constrained to the actual true Compile identities under the platform folder. ## Tests The real shipping SingleProject targets are covered by regressions for: - one dual-path macOS registration through recognized TPI and neutral backend activation, plus recognized-TPI and backend mismatch negatives; - two physical platform Compile files in different metadata buckets with no folder allow-list, asserting only the true item is removed and the surviving list is ordered and duplicate-free. Validation: - complete `MSBuildTests.SingleProject_*` matrix: **46 passed, 0 failed**; - new regression matrix: **7 passed, 0 failed**; - `Controls.Build.Tasks.csproj` build: **succeeded with 0 warnings and 0 errors**; - targeted `dotnet format`: completed successfully. The unfiltered local graph is unavailable on this Mac because the platform project graph requires the iOS workload (`NETSDK1147`) and the full BuildTasks solution filter includes .NET Framework 4.7.2 projects without local reference assemblies (`MSB3644`). The workload-neutral matrix above used the repository-pinned .NET 11 SDK with platform TFMs disabled and imported the exact shipping targets. ### Candidate selection and final review #36957 is the selected implementation. Alternatives #36955 and #36956 both fail their own new Windows Helix XAML regression by removing the explicit-false Compile item. This branch uses FullPath/PathLike intersection, passes the expanded 46-case matrix, preserves metadata and duplicate count, handles absolute Compile identities, and skips the platform filesystem glob when no removal batch exists. Neutral activation of built-in backend identities is intentional: #36654 documented that built-ins use the same registration shape and that ActivationValue defaults from BackendIdentity. A dedicated regression now locks that contract. ## Issues Fixed Part of #34099 Part of #35021 Fixes #36650 Follow-up to #36654 --------- Co-authored-by: PureWeen <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac6265fe-09a0-473c-b3f9-9ec6d6dd97cd Copilot-Session: 66f84348-6476-4097-8b7f-f240338e85c3
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Summary
This follows the GPT-5.6 Sol post-merge verification of #36654 and addresses two focused SingleProject gaps found against the merged implementation. It is part of #34099 and a follow-up to #36654; it does not close #34099.
Root causes and behavior changes
Dual-path backend identity
_MauiNormalizePlatformSpecificFoldersonly defaultedActivationValuefromBackendIdentitywhen both singular and plural target-platform metadata were empty. A registration that intentionally supported both paths, such asTargetPlatformIdentifiers="macos" BackendIdentity="macos", worked for a recognizedmacosTPI but could not activate on a neutral TFM throughMauiActiveBackend=macos.The default now applies whenever
ActivationValueis empty, regardless of TPI metadata. Explicit activation values remain unchanged, explicit activation properties remain authoritative, and the existing neutral-path guard still prevents a backend selector from activating the folder on a different recognized TPI.Cross-item Compile batching
_MauiRemovePlatformCompileItemscreated a fresh filesystem glob inside theExcludeFromCurrentConfiguration=truebatch. That glob also contained physical files represented by downstreamCompileitems explicitly markedfalse, so a separate true item could cause those active files to be removed.The target now copies the actual
Compileidentities markedtrueto a temporary item type and intersects those identities with the platform filesystem candidates. It removes only the true identities without updating or re-adding activeCompileitems, preserving their metadata, ordering, and uniqueness.Tests
Added real shipping-target regressions to
MSBuildTests:macosTPI and neutralMauiActiveBackend=macos, while remaining excluded for recognizediosand a different neutral backend;The two failures were reproduced before the target changes with direct workload-neutral MSBuild imports, then passed after the fixes. A 25-case direct shipping-target matrix passed for legacy shared folders, all five built-ins, GTK activation through
ActivationValueandBackendIdentity, whitespace/unresolved fail-closed behavior, bare-activation compatibility, design-time unflip, ordering, and duplicate prevention.dotnet format Microsoft.Maui.sln --no-restore --exclude Templates/src --exclude-diagnostics CA1822 --include src/Controls/tests/Xaml.UnitTests/MSBuild/MSBuildTests.cs --verify-no-changescompleted successfully with reference-load warnings.The repository-native filtered xUnit run and build-task solution build could not complete locally because this machine has .NET SDK 10.0.203 while
global.jsonrequires 11.0.100-rc.1.26379.102. The filtered test fails withNETSDK1045; the build first reports missing restore assets, and the allowed restore attempt confirmsNETSDK1045for the net11.0 projects.Remaining limitations
CI with the pinned .NET 11 SDK is still required to execute the repository-native xUnit matrix and build. This PR remains scoped to SingleProject compile selection and does not implement the broader app-head manifest, entitlement, resource, launch, or design-time extensibility work tracked by #34099.