Hello Wasm World!¶
Introduction¶
This example walks through how to compile a hello world executable written in C++ to WebAssembly and how to execute it with standalone WebAssembly runtimes, the Node.js JavaScript runtime, and web browser runtimes!
Before getting started, make sure Node.js and Podman (recommended) or Docker are installed. On Linux, make sure you can run podman
or docker
without sudo
. On Windows, we highly recommend Podman.
While we recommend following along step-by-step, the complete example can also be found in the examples/
directory of the project repository.
Let’s get started! 🚀
Write the code¶
First, let’s create a new directory to house our project.
mkdir HelloWorld
cd HelloWorld
Let’s write some code! Populate hello.cxx with our Hello World program:
#include <iostream>
int main() {
std::cout << "Hello Wasm world!" << std::endl;
return 0;
}
Next, provide a CMake build configuration at CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(HelloWorld)
add_executable(hello hello.cxx)
Install itk-wasm¶
We use the add_executable
command to build executables with itk-wasm. The Emscripten and WASI toolchains along with itk-wasm build and execution configurations are contained in itk-wasm dockcross Docker images invoked by the itk-wasm command line interface (CLI). Note that the same code can also be built and tested with native operating system toolchains. This is useful for development and debugging.
Build the program with the itk-wasm CLI, itk-wasm
. This is shipped with the itk-wasm
Node.js package. First install itk-wasm with the Node Package Manager, npm
, the CLI that ships with Node.js.
# Initialize an empty project in the current directory
npm init --yes
npm install itk-wasm@1.0.0-b.106
WASI¶
Build the project with the WASI itkwasm/wasi
toolchain in the ./wasi-build/
directory:
npx itk-wasm -i itkwasm/wasi build
A hello.wasi.wasm
WebAssembly binary is built in the ./wasi-build/
directory.
❯ ls wasi-build
build.ninja CMakeFiles libwasi-exception-shim.a
cmake_install.cmake hello.wasi.wasm
Execute the binary with the run
itk-wasm
subcommand.
❯ npx itk-wasm run wasi-build/hello.wasi.wasm
Hello Wasm world!
Congratulations! You just executed a C++ program compiled to WebAssembly. 🎉
The binary can also be executed with other WASI runtimes.
Node.js¶
For Node.js or the Browser, build the project with the default Emscripten toolchain. The project is built in the ./emscripten-build
directory by default.
npx itk-wasm build
To execute the project, create an index.mjs
JavaScript file to invoke the module:
import path from 'path'
import { runPipelineNode } from 'itk-wasm'
const pipelinePath = path.resolve('emscripten-build', 'hello')
const args = []
await runPipelineNode(pipelinePath, args)
Important: Inside the package.json file, we must also add "type": "module",
to tell Node.js that we have a modern JavaScript project that uses ES modules.
And run it!
❯ npx node ./index.mjs
Hello Wasm world!
Congratulations! You just executed a C++ program in JavaScript. 🎉
Browser¶
The same Emscripten Wasm module can be executed in a web browser.
Create an HTML file named index.html
that will call the Wasm module through JavaScript and display its output in the HTML DOM:
<!DOCTYPE html>
<html>
<head>
<title>itk-wasm Browser Hello World!</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/itk-wasm@1.0.0-b.106/dist/umd/itk-wasm.min.js"></script>
</head>
<body>
<textarea readonly>WebAssembly output...</textarea>
<script>
const outputTextArea = document.querySelector("textarea");
outputTextArea.textContent = "Loading...";
const wasmURL = new URL('emscripten-build/hello', document.location)
const args = []
const inputs = null
const outputs = null
itk.runPipeline(null, wasmURL, args, inputs, outputs).then(
({ stdout, webWorker }) => {
webWorker.terminate()
outputTextArea.textContent = stdout
})
</script>
</body>
</html>
Serve the web page and Wasm module with an http server:
npm install http-server
http-server .
And point your browser to http://127.0.0.1:8080/
.
Congratulations! You just executed a C++ program in your web browser. 🎉