-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Fix WASM boot config ContentRoot to use IntermediateOutputPath #124125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
908155d
62fa4f2
2e74845
2721a86
17ab6d2
8aa672c
be1e963
e818d74
94be767
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -332,23 +332,11 @@ static bool IsDotNetWasm(string key) | |||||||||||||
|
|
||||||||||||||
| private TaskItem CreatePromotedAsset(ITaskItem asset) | ||||||||||||||
| { | ||||||||||||||
| string newAssetItemSpec = asset.ItemSpec; | ||||||||||||||
| string newAssetRelativePath = asset.GetMetadata("RelativePath"); | ||||||||||||||
|
|
||||||||||||||
| if (FingerprintAssets) | ||||||||||||||
| { | ||||||||||||||
| string assetDirectory = Path.GetDirectoryName(asset.ItemSpec); | ||||||||||||||
| string assetFileNameToFingerprint = Path.GetFileName(newAssetRelativePath); | ||||||||||||||
| string fingerprint = asset.GetMetadata("Fingerprint"); | ||||||||||||||
| string newAssetFingerprintedFileName = assetFileNameToFingerprint.Replace("#[.{fingerprint}]!", $".{fingerprint}"); | ||||||||||||||
| if (newAssetFingerprintedFileName != assetFileNameToFingerprint) | ||||||||||||||
| { | ||||||||||||||
| newAssetItemSpec = $"{assetDirectory}/{newAssetFingerprintedFileName}"; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var newAsset = new TaskItem(newAssetItemSpec, asset.CloneCustomMetadata()); | ||||||||||||||
| newAsset.SetMetadata("RelativePath", newAssetRelativePath); | ||||||||||||||
| // Keep ItemSpec pointing to the actual file on disk. | ||||||||||||||
| // DefineStaticWebAssets will resolve fingerprint placeholders in RelativePath | ||||||||||||||
| // and compute Fingerprint/Integrity from the real file. | ||||||||||||||
| var newAsset = new TaskItem(asset.ItemSpec, asset.CloneCustomMetadata()); | ||||||||||||||
| newAsset.SetMetadata("RelativePath", asset.GetMetadata("RelativePath")); | ||||||||||||||
|
|
||||||||||||||
| ApplyPublishProperties(newAsset); | ||||||||||||||
| return newAsset; | ||||||||||||||
|
|
@@ -446,6 +434,10 @@ private void ComputeUpdatedAssemblies( | |||||||||||||
| // when the original assembly they depend on has been linked out. | ||||||||||||||
| var assetsToUpdate = new Dictionary<string, ITaskItem>(); | ||||||||||||||
| var linkedAssets = new Dictionary<string, ITaskItem>(); | ||||||||||||||
| // Secondary lookup by normalized filename for satellite matching. | ||||||||||||||
| // RelatedAsset may use a different base path (e.g., OutputPath/wwwroot) | ||||||||||||||
| // than the asset's build-time Identity (e.g., IntermediateOutputPath/webcil). | ||||||||||||||
| var assetsToUpdateByFileName = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); | ||||||||||||||
|
|
||||||||||||||
| foreach (var kvp in assemblyAssets) | ||||||||||||||
| { | ||||||||||||||
|
|
@@ -459,6 +451,8 @@ private void ComputeUpdatedAssemblies( | |||||||||||||
| { | ||||||||||||||
| // We found the assembly, so it'll have to be updated. | ||||||||||||||
| assetsToUpdate.Add(assetToUpdateItemSpec, asset); | ||||||||||||||
| if (!assetsToUpdateByFileName.ContainsKey(fileName)) | ||||||||||||||
| assetsToUpdateByFileName[fileName] = assetToUpdateItemSpec; | ||||||||||||||
| filesToRemove.Add(existing); | ||||||||||||||
| if (!string.Equals(asset.ItemSpec, existing.GetMetadata("FullPath"), StringComparison.Ordinal)) | ||||||||||||||
| { | ||||||||||||||
|
|
@@ -477,6 +471,18 @@ private void ComputeUpdatedAssemblies( | |||||||||||||
| var satelliteAssembly = kvp.Value; | ||||||||||||||
| var relatedAsset = satelliteAssembly.GetMetadata("RelatedAsset"); | ||||||||||||||
|
|
||||||||||||||
| // Try exact match first, then fall back to filename-based lookup. | ||||||||||||||
| // Normalize to .dll when webcil is enabled since assetsToUpdateByFileName | ||||||||||||||
| // keys are normalized to .dll (line 448) but RelatedAsset paths use .wasm. | ||||||||||||||
|
Comment on lines
+475
to
+476
|
||||||||||||||
| // Normalize to .dll when webcil is enabled since assetsToUpdateByFileName | |
| // keys are normalized to .dll (line 448) but RelatedAsset paths use .wasm. | |
| // Normalize to .dll when webcil is enabled since assemblies tracked in | |
| // assetsToUpdateByFileName use .dll extensions, while RelatedAsset paths may use .wasm. |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UpdateRelatedAssetProperty does a linear scan over updatedAssetsMap when the exact RelatedAsset key isn’t found. On larger apps this can become O(n^2) across assets and is also harder to reason about when multiple entries share the same base name. Consider building a secondary lookup (e.g., normalized file name → updated asset) once and using that here, similar to the approach used in ComputeUpdatedAssemblies.
Copilot
AI
Feb 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The InvalidOperationException message ("Related asset not found.") doesn't include which RelatedAsset value failed to resolve, which makes diagnosing build/publish failures harder—especially now that there is fallback matching logic. Consider including the missing RelatedAsset value (and possibly the current asset ItemSpec) in the exception message.
| if (updatedRelatedAsset == null) | |
| { | |
| throw new InvalidOperationException("Related asset not found."); | |
| if (updatedRelatedAsset is null) | |
| { | |
| throw new InvalidOperationException($"Related asset '{relatedAsset}' for asset '{asset.ItemSpec}' not found."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this needs to happen in other places like the definition of the
.wasmfiles as assets (after webcil conversion).I believe the important bit here is that ContentRoot + RelativePath must exist for all assets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added a commit that sets per-item ContentRoot metadata on each
_WebCilAssetsCandidatesitem to%(RootDir)%(Directory)(its own directory). This ensurescandidateFullPath.StartsWith(normalizedContentRoot)is always true inDefineStaticWebAssets.ComputeCandidateIdentity, so Identity equals the physical file path for all candidates — webcil-converted files inobj/webcil/, runtime pack files inpacks/, PDBs fromobj/, etc.The task-level
ContentRootparameter is kept as a fallback but the per-item metadata takes precedence viaComputePropertyValue.