Introduction to WebAssembly, Emscripten, and Binaryen: Installation, Compilation, and Usage
This guide introduces WebAssembly and its ecosystem—explaining how Emscripten compiles C/C++ to asm.js or .wasm, how Binaryen converts asm.js to the final binary, and provides step‑by‑step Ubuntu installation, simple hello‑world compilation, build‑process wrappers, and real‑world examples such as FFmpeg, SQLite, and game engines.
WebAssembly is a binary format for the web jointly developed by Mozilla, Google, Microsoft, and Apple. It serves as a compilation target for any programming language, allowing applications to run in browsers or other runtimes.
Before WebAssembly, each company had its own technology to extend browser capabilities (e.g., Microsoft TypeScript, Apple FLTJIT, Google PNaCl, and asm.js). The four companies combined their efforts to create WebAssembly, which is now supported by major browsers.
C/C++ => LLVM => Emscripten => asm.js
When the source is compiled to LLVM IR, the compiler performs many optimizations, improving performance.
What can be done with WebAssembly
WebAssembly enables existing C/C++ tools or libraries to be compiled to JavaScript and executed in browsers or Node.js. Typical use cases include:
Game engines such as Unreal and Unity
FFmpeg and other codec libraries
SQLite database
Python, Lua, and other runtime environments
Environment Setup
To use WebAssembly you need to install Emscripten and Binaryen. Emscripten compiles source code to asm.js or WebAssembly, while Binaryen converts asm.js to the final .wasm binary.
Emscripten Installation (Ubuntu 14.04 example)
Two installation methods exist: using the emsdk script or building from source. The following commands illustrate the source‑build approach:
sudo apt-get update
sudo apt-get install python2.7 nodejs build-essential cmake git-core default-jre
mkdir myfastcomp && cd myfastcomp
git clone https://github.com/kripken/emscripten-fastcomp
cd emscripten-fastcomp
git clone https://github.com/kripken/emscripten-fastcomp-clang tools/clang
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86;JSBackend" -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DCLANG_INCLUDE_EXAMPLES=OFF -DCLANG_INCLUDE_TESTS=OFF
../configure --enable-optimized --disable-assertions --enable-targets=host,js
make -j2
git clone https://github.com/kripken/emscripten.git
LLVM_ROOT=$(python -c "import os,sys;print(os.path.expanduser(os.getenv('LLVM') or '/home/vagrant/myfastcomp/emscripten-fastcomp/build/bin'))")After installation, run emcc -v to verify the configuration.
Simple Hello World Test
#include<stdio.h>
int main(){
printf("hello\n");
return 0;
}Compile and run:
../emscripten/emscripten/emcc hello.c
ls # shows a.out.js and hello.c
nodejs a.out.js # prints helloEmscripten Build Process for Large Projects
Typical open‑source projects use ./configure && make . To target WebAssembly, replace the native compiler with emcc and use the provided wrappers:
./emconfigure ./configure
./emmake make
./emcc [-Ox] project.bc -o project.jsBinaryen
Binaryen converts the JavaScript output of Emscripten into the final WebAssembly binary (.wasm).
Installation
git clone https://github.com/WebAssembly/binaryen.git
cd binaryen
cmake . && makeKey Tools
asm2wasm : converts asm.js to a S‑expression .wast file
wasm-as : assembles .wast into a .wasm binary
Compiling a Simple Module
JavaScript source (my.asm.js):
function MyFirstModule(global) {
"use asm";
var exp = global.Math.exp;
function doubleExp(value) {
value = +value;
return +(+exp(+value) * 2.0);
}
function secondFunc(){
return +(2);
}
return { doubleExp: doubleExp ,secondFunc : secondFunc};
}Convert to .wast and then to .wasm:
asm2wasm my.asm.js -o my.asm.wast
wasm-as my.asm.wast -o my.asm.wasmThe resulting .wasm binary contains a preamble, type section, function section, memory section, export section, etc.
Running the .wasm in a Browser
var myFirstModule;
fetch("my.asm.wasm")
.then(r => r.arrayBuffer())
.then(buffer => {
var deps = {"global": {}, "env": {}};
deps["global.Math"] = window.Math;
var moduleBufferView = new Uint8Array(buffer);
myFirstModule = Wasm.instantiateModule(buffer, deps);
});Browser Support
WebAssembly is supported in the latest Chrome (or Chrome Canary with the flag chrome://flags/#enable-webassembly ), Microsoft Edge preview, and Firefox Nightly (enable javascript.options.wasm ).
Project Examples
videoconvert.js – FFmpeg compiled to JavaScript for in‑browser transcoding
sql.js – SQLite compiled to JavaScript
ocrad.js – OCR library in JavaScript
pypy.js – Python runtime compiled to JavaScript
jslinux – Linux running in the browser
Angry Bots – 3D game demo using WebAssembly
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.