[browser] WebAssembly SDK targets more incremental#125367
Open
[browser] WebAssembly SDK targets more incremental#125367
Conversation
This was referenced Mar 10, 2026
Split monolithic targets into incremental chains: Webcil conversion: - _ComputeWasmBuildCandidates (always runs): resolves candidates, classifies DLLs vs framework pass-throughs, computes expected webcil output paths - _ConvertBuildDllsToWebcil (incremental): DLL-to-webcil conversion with Inputs/Outputs, Touch to fix content-comparison timestamp preservation - _ResolveWasmOutputs (always runs): reconstructs webcil items, classifies framework candidates, defines static web assets Build boot JSON: - _ResolveBuildWasmBootJsonEndpoints (always runs): endpoint resolution - _WriteBuildWasmBootJsonFile (incremental): JSON file generation with Inputs/Outputs, Touch for timestamp fix - _GenerateBuildWasmBootJson (always runs): static web asset registration Publish boot JSON: - _ResolvePublishWasmBootJsonInputs (always runs): input resolution - GeneratePublishWasmBootJson (incremental): JSON file generation with Inputs/Outputs, Touch for timestamp fix FileWrites are added to always-run wrapper targets so dotnet clean works correctly even when incremental targets are skipped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
084b5ee to
ab57788
Compare
This comment has been minimized.
This comment has been minimized.
Two new tests verify WASM build incrementalism via binlog analysis: - IncrementalBuild_NoChanges_SkipsWebcilAndBootJson: Builds twice with no changes, asserts _ConvertBuildDllsToWebcil and _WriteBuildWasmBootJsonFile are skipped on the second build. - IncrementalBuild_SourceChange_RunsWebcilForAppOnly: Builds, modifies a C# source file, rebuilds, then asserts the webcil/boot JSON targets run but only the app assembly is re-converted (framework DLLs skipped by the task's internal per-file timestamp check). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
…amps - Add missing file inputs to _WriteBuildWasmBootJsonFile: VFS assets, config files, and dotnet.js template - Add property stamp files for both build and publish boot JSON targets using WriteOnlyWhenDifferent to detect property-only changes (e.g., WasmDebugLevel, environment name, globalization flags) - Build stamp: wasm-bootjson-build.stamp - Publish stamp: wasm-bootjson-publish.stamp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The WriteLinesToFile Lines parameter is an item-list context where @() item transforms cannot be concatenated with string literals using a non-semicolon separator. Pre-compute the stamp string in a PropertyGroup (string context) and pass the resulting property to Lines. Fixes both _WriteWasmBootJsonBuildPropertyStamp (build) and _WriteWasmPublishBootJsonPropertyStamp (publish) targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
…andaloneHosting to stamps - Reuse %(WebcilOutputPath) metadata in _ResolveWasmOutputs instead of recomputing paths from _WasmBuildWebcilPath + FileName/AssetTraitValue, eliminating duplicated path logic and risk of future divergence. - Add to both build and publish boot JSON property stamps so standalone-vs-hosted hosting mode changes correctly invalidate the incremental boot JSON targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
Add two new test cases to RebuildTests: - IncrementalBuild_NoChanges_SkipsWebcilAndBootJson_AOT: verifies AOT publish incremental skip of boot JSON generation on no-op rebuild - IncrementalBuild_PropertyChange_RunsBootJson: verifies that changing WasmDebugLevel (property-only, no source changes) invalidates the boot JSON stamp file and triggers regeneration while skipping webcil Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
Does change of (wasm related) properties force full rebuild ? |
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.
Summary
Improves MSBuild incrementalism for WebAssembly browser build targets in
Microsoft.NET.Sdk.WebAssembly.Browser.targets. On no-op rebuilds where inputs have not changed, the expensiveConvertDllsToWebcilandGenerateWasmBootJsontasks are now skipped via MSBuild'sInputs/Outputsmechanism.Changes
Webcil Conversion
Split
_ResolveWasmOutputsinto 3 targets:_ComputeWasmBuildCandidates(always runs) — resolves build asset candidates, classifies DLLs vs framework pass-throughs, computes expected webcil output paths_ConvertBuildDllsToWebcil(incremental) — runsConvertDllsToWebcilonly when DLL inputs are newer than webcil outputs_ResolveWasmOutputs(always runs) — reconstructs webcil items via MSBuild item transforms, classifies framework candidates, callsDefineStaticWebAssetsBoot JSON Generation
Split
_GenerateBuildWasmBootJsoninto 3 targets:_ResolveBuildWasmBootJsonEndpoints(always runs) — resolves endpoints and fingerprinted assets_WriteBuildWasmBootJsonFile(incremental) — writes boot JSON file only when inputs change_GenerateBuildWasmBootJson(always runs) — defines static web assets from the boot JSON outputSplit
GeneratePublishWasmBootJsoninto 2 targets:_ResolvePublishWasmBootJsonInputs(always runs) — resolves publish endpointsGeneratePublishWasmBootJson(incremental) — writes boot JSON only when inputs changeTouch outputs for content-comparison tasks
Both
ConvertDllsToWebcil(Utils.MoveIfDifferent) andGenerateWasmBootJson(ArtifactWriter.PersistFileIfChanged) use content-comparison write patterns that preserve old file timestamps when output content is unchanged. This defeats MSBuild's timestamp-based Inputs/Outputs incrementalism. Added<Touch>after each task invocation to ensure output timestamps reflect the current build session.FileWrites in always-run wrapper targets
When incremental targets are skipped,
<FileWrites>items inside their body are not populated. Added<FileWrites>to the always-run wrapper targets (_GenerateBuildWasmBootJson,_AddPublishWasmBootJsonToStaticWebAssets,_ResolveWasmOutputs) sodotnet cleanworks correctly.Incrementalism Proof
Binlog analysis of Wasm.Browser.Sample — build 1 (clean) vs build 2 (no-op rebuild):
Build Path
Design Notes
Why split instead of just adding Inputs/Outputs?
MSBuild's
Inputs/Outputsmechanism skips the entire target body when outputs are up-to-date. Since_ResolveWasmOutputsand_GenerateBuildWasmBootJsonboth contained file-writing tasks AND item-defining tasks (DefineStaticWebAssets), making them incremental would break downstream targets that depend on the items they produce. The split separates file I/O (incremental) from item definitions (always-run).Why Touch after task execution?
Both
ConvertDllsToWebcilandGenerateWasmBootJsonimplement "write only if content changed" patterns internally. While this avoids unnecessary downstream rebuilds, it defeats MSBuild's Inputs/Outputs check because unchanged outputs retain timestamps from a previous build session. The<Touch>ensures output timestamps always reflect the current build.Framework asset classification
The Framework SourceType classification (from #125329) is preserved. Since the incremental
_ConvertBuildDllsToWebciltarget only receives DLL items, framework candidate classification is done in MSBuild item groups in_ComputeWasmBuildCandidatesinstead of via the task'sPassThroughCandidatesoutput. Items withWasmNativeBuildOutputmetadata are per-project (Computed); items without are Framework assets needing per-project materialization.Culture/non-culture DLL separation
Culture-specific DLLs have
RelatedAssetmetadata that non-culture DLLs lack. Using%(RelatedAsset)in item transforms causes MSB4096 batching errors. The fix uses separate intermediate items (_WasmWebcilConvertedNonCulture,_WasmWebcilConvertedCulture).Testing
_ConvertBuildDllsToWebciland_WriteBuildWasmBootJsonFileNote
This PR description was generated with assistance from GitHub Copilot.