emscripten-tutorial

How to build an increasingly complex C/C++ codebase to WebAssembly
git clone https://git.tronto.net/emscripten-tutorial
Download | Log | Files | Refs | README

How to port a complex C codebase to the web

This repository contains the source code for the examples discussed in this blog post / tutorial.

Each sub-folder is a self-contained example of a C or C++ program (or library) that can be compiled to WebAssembly using Emscripten, and some JavaScript and HTML code that can be used to run this program in a web page or in a JavaScript runtime such as Node.js. Following these steps in order will walk you through the process of deploying a complex application (including multithreading, persistent storage and callback functions) as a web app.

Besides the source files, each folder contains a few one-line shell scripts, for convenience. Usually, the following are present:

If one of the run-* scripts is missing, it means that that example is only meant to run in Node.js, or only as a script in a web page.

The examples have been tested only on Linux, but should work on any UNIX system, and should be easy to adapt to Windows or other OSes. Pull requests are welcome.

Prerequisites

In order to follow this tutorial, you are going to need the following:

  1. Emscripten
  2. A web server to run locally, such as darkhttpd
  3. Node.js (this is optional, since a version of Node.js is distributed together with emscripten).

0. Hello world

The folder 00_hello_world contains the simplest possible example: a C program that prints “Hello world” to standard output. The default Emscripten HTML template is used to run this code in a web page.

1. Building a library

A common use case for building C or C++ code to WebAssembly is using some high-performance library in a web app. In this situation, the code you want to build does not have a main() entry point, but instead its public functions are called from JavaScript. Motivated by this, in the folder 01_library you’ll find an extremely simple C library (with only one one-line function), and some JavaScript code to run it from a web page.

2. Making it a module

In 02_library_modularized we review the previous example and we build it into a module. The result is the same, but it is more convenient to use.

3. Multi-threading

In 03_threads we build a more complicated example based on pthreads. To run this example, the web server has to be configured to provide the correct Cross-Origin-* headers, see 03_threads/run-server.sh for details.

4. Don’t block the main thread

In 04_no_block we avoid our calculations blocking the main browser thread by using a web worker.

5. Callback functions

In 05_callback the example is extended to include a callback function. The C program uses this function to log its progress back to the JavaScript side.

6. Storage

In 06_storage we show how to use Emscripten’s file system API using as backend the indexed DB. This example only works in the browser, as other runtimes (such as Node.js) require different backends.

In this example we make use time of the --pre-js option of the compiler to include custom JavaScript code that is run when our module loads. Moreover, the C code is split into multiple files for convenience.