[wasm] Emit producers and build_id custom sections (native, webcil, R2R)#130768
Draft
pavelsavara with Copilot wants to merge 3 commits into
Draft
[wasm] Emit producers and build_id custom sections (native, webcil, R2R)#130768pavelsavara with Copilot wants to merge 3 commits into
pavelsavara with Copilot wants to merge 3 commits into
Conversation
Co-authored-by: pavelsavara <[email protected]>
Co-authored-by: pavelsavara <[email protected]>
|
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
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(); |
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.Fixes #96334
Fixes #91049
Where the sections are emitted
producersbuild_iddotnet.native.wasm(app native re-link)wasm-ldwasm-ld --build-id(only when$(WasmNativeBuildId)is set)ConvertDllsToWebcil)WebcilWasmWrapper$(WasmNativeBuildId)if set, else a per-file SHA-256 content hashWasmObjectWriter--wasm-native-build-idif set, else a content hashAll three reuse a single encoder —
WasmCustomSectionWriter, relocated tosrc/coreclr/tools/Common/Wasm/andCompile-linked into the webcil task assembly and the ReadyToRun compiler — so there is one implementation of the section encoding.build_id$(WasmNativeBuildId)(hex) pins the value and forces a native re-link for the app native path.--wasm-native-build-idoption for the R2R path.producersContributes
language=C#,processed-by=<Mono|CoreCLR|WebCIL>,sdk=.NET. For the app native path it is delivered as a tiny relocatable object handed towasm-ld(which merges it with clang/LLVM's own entries), keeping both sections linker-driven and consistent with howbuild_idis produced. Toggle with$(WasmEmitProducersSection)(defaulttrue).JavaScript exposure
runtimeBuildInfo.buildIdsurfaces the native module'sbuild_idon both Mono and CoreCLR, via the same two channels used for options likewasmEnableSIMD:dotnet.*.jsbuild → rollup constant (consts:buildId)WASM_BUILD_IDenv var, which overrides the constantMSBuild properties
WasmNativeBuildIdbuild_idfor the native module (webcils fall back to a content hash).WasmEmitProducersSectionproducerssection (defaulttrue).Tests
src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/WasmMetadataSectionsTests.csverifies the sections indotnet.native.wasm(with and without a pinned id) and in webcil modules, running on both the Mono and CoreCLR legs.Not included / deferred
dotnet.native.wasm(the prebuilt, non-relinked binary). Today only the app re-link path stamps the native module; non-relinked apps keep the sectionless runtime-pack binary.Design notes:
docs/design/mono/wasm-custom-sections.md.Note
This PR description was updated with the assistance of GitHub Copilot.