WebAssembly (WASM) is a binary instruction format for a stack-based virtual machine, designed as a portable target for high-performance applications. In this article, we'll explore how to compile a simple C program to WebAssembly, load it into a web browser, and interact with it using JavaScript. We'll also explore some useful tools and commands for working with WASM outside the dev container environment.
Create the necessary folder structure and files for your WebAssembly project.
mkdir wasm-web-example cd wasm-web-example
Inside the .devcontainer folder, create the following files:
devcontainer.json
This file configures VSCode to use the Docker container with the necessary extensions and environment settings.
{ "name": "Emscripten DevContainer", "build": { "dockerfile": "Dockerfile" }, "customizations": { "vscode": { "settings": { "terminal.integrated.shell.linux": "/bin/bash", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.default.intelliSenseMode": "gcc-x64" }, "extensions": [ "ms-vscode.cpptools", "ms-vscode.cmake-tools" ] } }, "postCreateCommand": "emcc --version" }
Dockerfile
The Dockerfile will set up the Emscripten environment. Here's the content for that file:
# Use the official Emscripten image FROM emscripten/emsdk:3.1.74 # Set the working directory WORKDIR /workspace # Copy the source code into the container COPY . . # Install any additional packages if necessary (optional) # Ensure to clean up cache to minimize image size RUN apt-get update && \ apt-get install -y build-essential && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
c_cpp_properties.json
This file configures the C IntelliSense and include paths for your project.
{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/emsdk/upstream/emscripten/system/include" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "gnu++17", "configurationProvider": "ms-vscode.cmake-tools" } ], "version": 4 }
settings.json
This file includes specific VSCode settings for language associations.
{ "files.associations": { "emscripten.h": "c" }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features" }, "[typescript]": { "editor.defaultFormatter": "vscode.typescript-language-features" }, "[jsonc]": { "editor.defaultFormatter": "vscode.json-language-features" }, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" }, "[html]": { "editor.defaultFormatter": "vscode.html-language-features" } }
test.c
This C file contains the simple function that will be compiled to WebAssembly.
// test.c int add(int lhs, int rhs) { return lhs + rhs; }
test.html
This HTML file will load the WebAssembly module using JavaScript.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WebAssembly Example</title> </head> <body> <h1>WebAssembly Example</h1> <div> </li> <li> <p><strong>test.js</strong><br><br> This JavaScript file will fetch the WebAssembly module and call the exported function.<br> </p> <pre class="brush:php;toolbar:false"> // test.js const wasmFile = 'test.wasm'; fetch(wasmFile) .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes)) .then(({ instance }) => { const result = instance.exports.add(5, 3); // Call the WebAssembly function document.getElementById('output').textContent = `Result from WebAssembly: ${result}`; }) .catch(error => console.error('Error loading WebAssembly module:', error));
Now that you've set up all the necessary files and configurations, you can move on to compiling and interacting with WebAssembly.
Basic C Program:
The file test.c contains a simple function add that adds two integers. We will compile this C function into WebAssembly using Emscripten.
Emscripten Command:
Inside the dev container, open the terminal (use cmd j in VSCode) and run the following Emscripten command to compile the C code to WebAssembly:
mkdir wasm-web-example cd wasm-web-example
This command will generate test.wasm, the WebAssembly binary, and ensure that the add function is exported for use in JavaScript.
HTML Setup:
The file test.html contains a simple HTML page that loads the WebAssembly binary using JavaScript.
JavaScript Setup:
The JavaScript file test.js loads the test.wasm file and calls the exported add function:
Outside the dev container, there are several useful commands you can run to work with WebAssembly on your Mac.
{ "name": "Emscripten DevContainer", "build": { "dockerfile": "Dockerfile" }, "customizations": { "vscode": { "settings": { "terminal.integrated.shell.linux": "/bin/bash", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.default.intelliSenseMode": "gcc-x64" }, "extensions": [ "ms-vscode.cpptools", "ms-vscode.cmake-tools" ] } }, "postCreateCommand": "emcc --version" }
# Use the official Emscripten image FROM emscripten/emsdk:3.1.74 # Set the working directory WORKDIR /workspace # Copy the source code into the container COPY . . # Install any additional packages if necessary (optional) # Ensure to clean up cache to minimize image size RUN apt-get update && \ apt-get install -y build-essential && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/emsdk/upstream/emscripten/system/include" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "gnu++17", "configurationProvider": "ms-vscode.cmake-tools" } ], "version": 4 }
By following these steps, you can set up a development environment to compile C code to WebAssembly, interact with it using JavaScript, and convert resulting binaries for inspection. The use of external tools like wabt and Python’s HTTP server simplifies managing and exploring WebAssembly modules on macOS systems.
The above is the detailed content of Introduction to WebAssembly (WASM). For more information, please follow other related articles on the PHP Chinese website!