WebAssembly: Building Standalone and Dynamic Linking Modules in Windows

Xiao Ling
Xiao Ling
Nov 8 · 3 min read

Emscripten supports compiling C/C++ code to wasm files. Dynamic linking is a basic need for building complicated projects. In this article, I will share how to build a standalone wasm file and how to link multiple wasm files in Windows.

Tool Installation

git clone https://github.com/emscripten-core/emsdk.git

cd emsdk

emsdk.bat install latest

emsdk.bat activate latest

emsdk install mingw-4.6.2-32bit

emsdk activate mingw-4.6.2-32bit

WebAssembly Standalone

I created three simple C files: foo1.c, foo2.c and main.c.

Foo1.c

int foo1(){return 1;}

Foo2.c

int foo2(){return 2;}

Main.c

#include <stdio.h>int foo1();int foo2();int main(){int result = foo1() + foo2();printf("hello world %d\n", result);return 0;}

Build a standalone wasm file:

emcc main.c foo1.c foo2.c -o main.wasm

The generated wasm file doesn’t depend on an Emscripten JS runtime. We can run it in wasi-supporting runtimes, such as wasmer:

> wasmer run main.wasm 
> hello world 3

Or open the .wasm file in WASI browser polyfill.

With STANDALONE_WASM option, It will also emit a .js file for running the wasm file on the web:

emcc main.c foo1.c foo2.c -s STANDALONE_WASM -o main.wasm

CMake Build

Create a CMakeLists.txt file:

Run the following command to build the project:

emsdk activate mingw-4.6.2-32bitmkdir buildcd buildemconfigure cmake ..emmake make -j4

Dynamic Linking

We can also build the *.c files to wasm files respectively for linking dynamically.

Build the side modules:

emcc foo1.c -s SIDE_MODULE=1 -o foo1.wasmemcc foo2.c -s SIDE_MODULE=1 -o foo2.wasm

Build the main module to emit the main.wasm, main.js and main.html files:

emcc main.c -s MAIN_MODULE=1 -o main.html

Serve the HTML and wasm files with Web Server for Chrome:

The dynamic libraries have not been linked yet. If you visit main.html, you will see the error message:

external function 'foo1' is missing. perhaps a side module was not linked in? if this function was expected to arrive from a system library, try to build the MAIN_MODULE with EMCC_FORCE_STDLIBS=1 in the environment

Open main.js to add following code for linking dynamic libraries:

Module['dynamicLibraries'] = ['foo1.wasm', 'foo2.wasm'];

Refresh the page. The dynamic linking sample is working now:

Downsides of Using Dynamic Libraries

Note: dynamic linking so far is not recommended because dynamic libraries have relocations for memory and function pointers, which add overhead.

Reference


Originally published at https://www.codepool.biz on November 8, 2019.

Xiao Ling

Written by

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade