Fix XamlC MSBuild target incrementality for Debug builds#34742
Closed
davidnguyen-tech wants to merge 3 commits into
Closed
Fix XamlC MSBuild target incrementality for Debug builds#34742davidnguyen-tech wants to merge 3 commits into
davidnguyen-tech wants to merge 3 commits into
Conversation
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34742Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34742" |
Move the _MauiXamlCValidateOnly property computation from inside the XamlC target body to a static PropertyGroup. This makes it available at evaluation time for use in target Conditions. The property depends only on static properties (Configuration, _MauiForceXamlCForDebug, BuildingForLiveUnitTesting) so hoisting is safe. No behavioral change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split XamlC into two mutually exclusive targets: - XamlC (Release): Inputs include both the assembly and @(MauiXaml). Runs when either changes. Required because Release mode compiles XAML into IL and writes it back into the assembly. - _XamlCValidateOnly (Debug): Inputs include only @(MauiXaml). Skips when only C# files change. Safe because validate-only mode reads the assembly but never writes to it. This saves ~0.5s on incremental Debug builds when only non-XAML C# files change, improving Android inner loop performance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CSharpOnlyChange_DoesNotTriggerXamlCInDebug: verifies the core fix — adding a C# file in Debug mode does not re-run XamlC - CSharpOnlyChange_DoesTriggerXamlCInRelease: verifies Release correctness — C#-only changes still trigger XamlC since the assembly is in Inputs - Update NoXamlFiles to also verify _XamlCValidateOnly is skipped Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4926c7c to
09845f9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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!
Description
Fixes XamlC MSBuild target incrementality to avoid unnecessary re-runs on non-XAML C# changes, improving MAUI Android inner loop build performance.
Problem
The XamlC target uses
Inputs="$(IntermediateOutputPath)$(TargetFileName)"(the compiled assembly DLL). Since any C# change rebuilds the assembly, XamlC re-runs even when no XAML files changed. In Debug mode (ValidateOnly=True), this wastes ~0.56s scanning and validating all XAML on every incremental build.Solution
Split the XamlC target into two mutually exclusive targets based on
_MauiXamlCValidateOnly:XamlC_XamlCValidateOnlyThe key insight: in Debug/ValidateOnly mode, XamlC only reads the assembly for validation — it never writes to it. So the assembly does not need to be an Input. When only C# files change (no XAML changes), the validate-only target correctly reports up-to-date and skips.
In Release mode, XamlC compiles XAML into IL and writes it back into the assembly, so the assembly must remain an Input to ensure correctness.
Tradeoff
In Debug mode, if a C# type referenced by XAML is removed/renamed without editing the XAML file, validation will not catch this until the XAML file is next modified or a clean build is done. This is an acceptable tradeoff because:
Testing
CSharpOnlyChange_DoesNotTriggerXamlCInDebugtest verifying the core fixCSharpOnlyChange_DoesTriggerXamlCInReleasetest verifying Release correctnessNoXamlFilestest to verify both targets are skipped when no XAML files exist