[wasm] Emit producers and build_id custom sections (native, webcil, R2R) - #130768
Draft
pavelsavara with Copilot wants to merge 4 commits into
Draft
pavelsavara with Copilot wants to merge 4 commits into
pavelsavara with Copilot wants to merge 4 commits into
Conversation
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 4 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Copilot created this pull request from a session on behalf of
pavelsavara
July 15, 2026 10:44
View session
Open
3 tasks
pavelsavara
temporarily deployed
to
copilot-pat-pool
July 15, 2026 20:35 — with
GitHub Actions
Inactive
pavelsavara
temporarily deployed
to
copilot-pat-pool
July 15, 2026 20:36 — with
GitHub Actions
Inactive
Contributor
There was a problem hiding this comment.
Pull request overview
This PR prototypes emitting WebAssembly tool-conventions custom sections (producers, build_id) and surfacing a buildId value through the browser-wasm JavaScript API, wiring it through the Mono/CoreCLR relink pipelines and stamping WebCIL/R2R wasm outputs.
Changes:
- Add a reusable managed
WasmCustomSectionWriterand an MSBuild task to generate a linkable wasm object contributing.NETentries to theproducerssection during relink. - Plumb
WasmNativeBuildIdthrough build targets/tasks and exposeruntimeBuildInfo.buildIdin the JS public API surface. - Add WBT coverage for relink/webcil metadata sections and a design doc describing the approach.
Reviewed changes
Copilot reviewed 38 out of 42 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/tasks/WasmAppBuilder/WebcilConverter.cs | Exposes build-id/version passthrough to Webcil converter. |
| src/tasks/WasmAppBuilder/WasmEmitProducersObject.cs | New task writing producers wasm object for linker merge. |
| src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilWasmWrapper.cs | Appends producers/build_id to wrapped WebCIL wasm. |
| src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs | Wires metadata options into wrapper output. |
| src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj | Links shared custom-section writer into task assembly. |
| src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs | Passes build-id/product version into WebCIL conversion. |
| src/native/rollup.config.defines.js | Adds buildId rollup constant from env. |
| src/native/libs/System.Native.Browser/native/index.ts | Overrides runtimeBuildInfo.buildId from relinked native module. |
| src/native/libs/System.Native.Browser/libSystem.Native.Browser.footer.js | Exposes WASM_BUILD_ID via $DOTNET during emcc link. |
| src/native/libs/Common/JavaScript/types/public-api.ts | Extends public RuntimeAPI typing with buildId. |
| src/native/libs/Common/JavaScript/types/ems-ambient.ts | Adds buildId to emscripten ambient DOTNET shape. |
| src/native/libs/Common/JavaScript/loader/index.ts | Seeds runtimeBuildInfo.buildId from rollup constant. |
| src/native/libs/Common/JavaScript/loader/dotnet.d.ts | Updates generated public typings for buildId. |
| src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/WasmMetadataSectionsTests.cs | New tests validating producers/build_id emission. |
| src/mono/wasm/build/WasmApp.Common.targets | Forces native relink when WasmNativeBuildId is set. |
| src/mono/sample/wasm/Directory.Build.targets | Propagates WasmNativeBuildId through nested builds. |
| src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj | Sample configuration updates (currently problematic). |
| src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in | Treats WasmNativeBuildId as relink-triggering. |
| src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets | Passes build-id/version into ConvertDllsToWebCIL task. |
| src/mono/browser/runtime/types/internal.ts | Adds buildId to emscriptenBuildOptions typing. |
| src/mono/browser/runtime/types/index.ts | Extends runtime API typing with buildId. |
| src/mono/browser/runtime/rollup.config.js | Adds buildId constant in mono runtime rollup config. |
| src/mono/browser/runtime/loader/globals.ts | Formatting-only changes. |
| src/mono/browser/runtime/loader/assets.ts | Formatting-only changes. |
| src/mono/browser/runtime/globals.ts | Copies buildId from relinked module into runtimeBuildInfo. |
| src/mono/browser/runtime/exports.ts | Seeds runtimeBuildInfo.buildId from rollup constant. |
| src/mono/browser/runtime/es6/dotnet.es6.lib.js | Plumbs WASM_BUILD_ID into emcc-evaluated options blob. |
| src/mono/browser/runtime/dotnet.d.ts | Updates generated public typings for buildId. |
| src/mono/browser/build/BrowserWasmApp.targets | Mono relink: emits producers object + build-id linker/env wiring. |
| src/mono/browser/build/BrowserWasmApp.CoreCLR.targets | CoreCLR relink: emits producers object + build-id linker/env wiring. |
| src/mono/browser/browser.proj | Treats WasmNativeBuildId as runtime-pack defaultable property. |
| src/coreclr/tools/Common/Wasm/WasmCustomSectionWriter.cs | New encoder/merger for producers/build_id custom sections. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs | Stamps producers/build_id into R2R webcil wasm output. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj | Links shared custom-section writer into ILC tool. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs | Plumbs wasm build-id option through compilation pipeline. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs | Carries wasm build-id into object emission. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs | Passes wasm build-id through to WasmObjectWriter. |
| src/coreclr/tools/aot/crossgen2/Properties/Resources.resx | Adds help text for new crossgen2 option. |
| src/coreclr/tools/aot/crossgen2/Program.cs | Wires new option into ReadyToRun builder. |
| src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs | Adds --wasm-native-build-id option. |
| src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js | Adds buildId field to corerun runtimeBuildInfo. |
| docs/design/mono/wasm-custom-sections.md | Design doc describing custom section strategy and properties. |
Comment on lines
+113
to
+114
| if (moduleBytes.Length < 8 || BitConverter.ToUInt32(moduleBytes, 0) != WasmMagic) | ||
| throw new InvalidDataException("Not a WebAssembly module (bad magic)."); |
Comment on lines
+116
to
+118
| uint version = BitConverter.ToUInt32(moduleBytes, 4); | ||
| if (version != 1) | ||
| throw new InvalidDataException($"Unsupported WebAssembly module version {version}."); |
Comment on lines
+181
to
+186
| if (mergedProducers is not null) | ||
| WriteProducersSection(ms, mergedProducers); | ||
|
|
||
| if (buildId is not null) | ||
| WriteBuildIdSection(ms, buildId); | ||
|
|
Comment on lines
91
to
95
| `runAOTCompilation: ${RUN_AOT_COMPILATION}, ` + | ||
| `wasmEnableThreads: ${!!PTHREADS}, ` + | ||
| `gitHash: "${gitHash}", ` + | ||
| `buildId: "${WASM_BUILD_ID}", ` + | ||
| `});`; |
Comment on lines
+61
to
+65
| catch (Exception ex) | ||
| { | ||
| Log.LogError($"Failed to write producers object '{OutputPath}': {ex.Message}"); | ||
| return false; | ||
| } |
Comment on lines
19
to
21
| <WasmProfilers>browser:callspec=N:Sample</WasmProfilers> | ||
| <WasmNativeBuildId>Advanced-1a2b3c4d5e6f7788-ID</WasmNativeBuildId> | ||
|
|
Comment on lines
+444
to
+445
| <!-- build_id value exposed on runtimeBuildInfo.buildId; kept in sync with the wasm-ld - -build-id flag. --> | ||
| <EmscriptenEnvVars Include="WASM_BUILD_ID=$(_WasmNormalizedBuildId)" Condition="'$(_WasmNormalizedBuildId)' != ''" /> |
Comment on lines
147
to
150
| var webcilWriter = Microsoft.WebAssembly.Build.Tasks.WebcilConverter.FromPortableExecutable(inputPath: dllFilePath, outputPath: tmpWebcil, logger: logAdapter, webcilVersion: WebcilVersion); | ||
| webcilWriter.ProductVersion = ProductVersion ?? string.Empty; | ||
| webcilWriter.BuildId = ParseBuildId(WasmNativeBuildId); | ||
| webcilWriter.ConvertToWebcil(); |
2 of 29 tasks
Resolve Browser WASM custom-section conflicts with the current WebCIL writer and app-relink infrastructure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 1, 2026
Open
This branch was previously deployed
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.
Emits the two WebAssembly tool-conventions custom sections —
producersandbuild_id— into the WebAssembly artifacts produced by the .NET wasm toolchain, for both Mono and CoreCLR.Where the sections are emitted
producersbuild_iddotnet.native.wasm(app native re-link)wasm-ldwasm-ldbuild-id linker flag, only when$(WasmNativeBuildId)is setConvertDllsToWebcil)WebcilWasmWrapper$(WasmNativeBuildId)if set, otherwise a per-file SHA-256 content hashWebCilObjectWriter--wasm-native-build-idif set, otherwise a content hashAll three paths reuse
WasmCustomSectionWriter, linked into the Webcil task assembly and the ReadyToRun compiler, so there is one implementation of the section encoding.build_iddotnet.native.wasmonly when a value is provided; there is intentionally no implicit random-per-build ID.$(WasmNativeBuildId)accepts a hexadecimal value, pins the ID, and forces a native application re-link.--wasm-native-build-idoption for R2R Webcil output.producersThe generated entries are:
language=C#processed-by=<Mono|CoreCLR|WebCIL>sdk=.NETFor an application native re-link,
WasmEmitProducersObjectcreates a small relocatable object that is passed towasm-ld. Emission can be disabled with$(WasmEmitProducersSection)=false.JavaScript exposure
runtimeBuildInfo.buildIdsurfaces the native module'sbuild_idon both Mono and CoreCLR:dotnet.*.jsbuild: a rollup constant (consts:buildId)WASM_BUILD_IDand overrides the rollup constantMSBuild properties
WasmNativeBuildIdbuild_idfor the native module; Webcil modules fall back to a content hash.WasmEmitProducersSectionproducerssection. Defaults totrue.Tests
src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/WasmMetadataSectionsTests.cscovers the sections indotnet.native.wasmand Webcil modules, with and without an explicitly pinned ID.Local validation after merging current
main:.\build.cmd -bl -os browser -subset clr+libs+host -c Debug /p:RuntimeFlavor=CoreCLR.\dotnet.cmd build -bl:artifacts\log\pr130768-sample.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:Configuration=Debug /p:RuntimeFlavor=CoreCLR /p:WasmBuildNative=true /p:WasmNativeBuildId=1a2b3c4d5e6f7788 src\mono\sample\wasm\browser\Wasm.Browser.Sample.csprojdotnet.native.wasmcontainsbuild_idbytes1a2b3c4d5e6f7788.\dotnet.cmd build -bl:artifacts\log\pr130768-wbt.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:Configuration=Debug /p:RuntimeFlavor=CoreCLR /t:Test src\mono\wasm\Wasm.Build.Tests /p:TestUsingWorkloads=false /p:InstallWorkloadForTesting=false /p:XUnitClassName=Wasm.Build.NativeRebuild.Tests.WasmMetadataSectionsTestsNETSDK1147, requiring thewasm-toolsworkload before reaching the test targetsKnown limitation from local validation:
dotnet-producers.ois generated and included in the Emscripten response file, but the final relinked CoreCLRdotnet.native.wasmdid not contain aproducerssection. This still needs investigation before theproducerspath is considered validated.Not included / deferred
dotnet.native.wasmused by non-relinking applications.Design notes:
docs/design/mono/wasm-custom-sections.md.Merged current
mainatced3e57460dd57581734dfd4d7888cb3e2eca028in merge commitc157dd70460071dbb01eb27bda091b0f6262c605.Resolves #96334
Resolves #91049
Note
This PR description was updated with the assistance of GitHub Copilot.