docs/workflow/building/coreclr/wasm.md
This guide provides instructions for building, running, and debugging CoreCLR on WebAssembly (WASM). This is experimental support and is currently under active development.
Make sure you've prepared your environment and installed all the requirements for your platform. If not, follow this link for the corresponding instructions.
To build the CoreCLR runtime for WebAssembly, use the following command from the repository root:
Linux/macOS:
./build.sh -os browser -c Debug -subset clr+libs
Windows:
.\build.cmd -os browser -c Debug -subset clr+libs
This command will:
Note: The first build may take longer as it downloads and sets up the Emscripten toolchain.
If you don't have dotnet-serve installed, you can install it as a global .NET tool with:
dotnet tool install --global dotnet-serve
Linux/macOS:
dotnet-serve --directory "artifacts/bin/coreclr/browser.wasm.Debug"
Windows:
dotnet-serve --directory "artifacts\bin\coreclr\browser.wasm.Debug"
This will start a local HTTP server and you can open the provided URL in your browser.
You will also need to ensure the WASM_PRELOAD_DIR (see src/coreclr/hosts/corerun/CMakeLists.txt) is populated during a build of corerun so the virtual file system is created. This will require the copying of the libraries (see Console Testing details below) and HelloWorld.dll into ./artifacts/bin/coreclr/browser.wasm.Debug/IL and then the corerun project will then need to be rebuilt.
You can also run the runtime directly in Node.js:
In script below please replace /path/to/runtime/ by a absolute unix path to the actual runtime repo (even on Windows).
cp ./artifacts/bin/microsoft.netcore.app.runtime.browser-wasm/Debug/runtimes/browser-wasm/lib/net11.0/*.dll ./artifacts/bin/coreclr/browser.wasm.Debug/IL
cp helloworld.dll ./artifacts/bin/coreclr/browser.wasm.Debug/IL
cd ./artifacts/bin/coreclr/browser.wasm.Debug/
node ./corerun.js -c /path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL /path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL/helloworld.dll
You can also run the corehost directly in Node.js:
cp ./artifacts/bin/microsoft.netcore.app.runtime.browser-wasm/Debug/runtimes/browser-wasm/lib/net11.0/*.dll ./artifacts/bin/coreclr/browser.wasm.Debug/corehost
cp helloworld.dll ./artifacts/bin/coreclr/browser.wasm.Debug/corehost
cd ./artifacts/bin/coreclr/browser.wasm.Debug/corehost
node ./main.mjs
For debugging CoreCLR WebAssembly code, the recommended approach is using Chrome browser with the C/C++ DevTools Support (DWARF) extension:
Install the Chrome extension:
Open Chrome DevTools (F12) while running your WebAssembly application
Set breakpoints in the Sources tab:
Note: The debugging experience is not perfect but works most of the time. You can step through C code, set breakpoints, and inspect the WebAssembly linear memory.
VS Code, through Node.js, provides a good debugging option for WebAssembly CoreCLR:
Install the VS Code extension (Optional):
Create a launch.json configuration:
In config below please replace /path/to/runtime/ by a absolute unix path to the actual runtime repo (even on Windows).
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "corerun",
"skipFiles": [
"<node_internals>/**"
],
"outputCapture": "std",
"program": "corerun.js",
"env": {
"CORE_ROOT":"/path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL/"
},
"runtimeArgs": [
"--stack-trace-limit=1000"
],
"args": [
"/path/to/runtime/artifacts/bin/coreclr/browser.wasm.Debug/IL/helloworld.dll"
],
"cwd": "${workspaceFolder}/artifacts/bin/coreclr/browser.wasm.Debug/"
},
{
"name": "browserhost",
"type": "node",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"runtimeArgs": [
"--stack-trace-limit=1000"
],
"args": [
"HelloWorld.dll"
],
"outputCapture": "std",
"cwd": "${workspaceFolder}/artifacts/bin/coreclr/browser.wasm.Debug/corehost",
"program": "main.mjs",
}
]
}
Note that for corerun path in the args and CORE_ROOT need to be absolute path on your host file system in unix format (even on Windows).
Copy managed DLLs System.Runtime.dll and helloworld.dll into artifacts/bin/coreclr/browser.wasm.Debug/IL/.
Set breakpoints in corerun.js in one of the put_char functions (the stdout/stderr implementation)
Start debugging and step through the WebAssembly code using the call stack
This approach allows you to debug the JavaScript host and step into WebAssembly code or into the C/C++ code if the Dwarf Debugging extension was installed.
WCHAR * strings in debugger watch window, cast it to char16_t* like (char16_t*)pLoaderModule->m_fileName